17d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko/*
27d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Copyright (C) 2015 The Android Open Source Project
37d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
47d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
57d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * you may not use this file except in compliance with the License.
67d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * You may obtain a copy of the License at
77d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
87d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
97d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
107d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Unless required by applicable law or agreed to in writing, software
117d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
127d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * See the License for the specific language governing permissions and
147d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * limitations under the License
157d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko */
167d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
172e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkopackage com.android.tv.common;
187d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
191abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.content.Context;
207d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.text.TextUtils;
217d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.util.Log;
227d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
231abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport com.android.tv.common.feature.Feature;
247d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
257d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko/**
267d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Simple static methods to be called at the start of your own methods to verify
277d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * correct arguments and state.
287d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
297d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * <p>{@code checkXXX} methods throw exceptions when {@link BuildConfig#ENG} is true, and
307d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * logs a warning when it is false.
317d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
327d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * <p>This is based on com.android.internal.util.Preconditions.
337d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko */
347d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkopublic final class SoftPreconditions {
357d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private static final String TAG = "SoftPreconditions";
367d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
377d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
387d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an expression involving the parameter of the calling
397d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * method is not true.
407d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
417d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param expression a boolean expression
427d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param tag Used to identify the source of a log message.  It usually
437d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *            identifies the class or activity where the log call occurs.
447d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param msg The message you would like logged.
4565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * @return the evaluation result of the boolean expression
467d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws IllegalArgumentException if {@code expression} is true
477d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
4865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static boolean checkArgument(final boolean expression, String tag, String msg) {
497d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        if (!expression) {
507d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            warn(tag, "Illegal argument", msg, new IllegalArgumentException(msg));
517d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return expression;
537d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
547d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
557d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
567d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an expression involving the parameter of the calling
577d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * method is not true.
587d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
597d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param expression a boolean expression
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * @return the evaluation result of the boolean expression
617d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws IllegalArgumentException if {@code expression} is true
627d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
6365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static boolean checkArgument(final boolean expression) {
647d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        checkArgument(expression, null, null);
6565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return expression;
667d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
677d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
687d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
697d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an and object is null.
707d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
717d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param reference an object reference
727d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param tag Used to identify the source of a log message.  It usually
737d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *            identifies the class or activity where the log call occurs.
747d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param msg The message you would like logged.
757d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @return true if the object is null
767d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws NullPointerException if {@code reference} is null
777d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
787d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public static <T> T checkNotNull(final T reference, String tag, String msg) {
797d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        if (reference == null) {
807d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            warn(tag, "Null Pointer", msg, new NullPointerException(msg));
817d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
827d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        return reference;
837d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
847d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
857d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
867d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an and object is null.
877d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
887d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param reference an object reference
897d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @return true if the object is null
907d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws NullPointerException if {@code reference} is null
917d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
927d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public static <T> T checkNotNull(final T reference) {
937d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        return checkNotNull(reference, null, null);
947d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
957d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
967d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
977d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an expression involving the state of the calling
987d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * instance, but not involving any parameters to the calling method is not true.
997d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
1007d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param expression a boolean expression
1017d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param tag Used to identify the source of a log message.  It usually
1027d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *            identifies the class or activity where the log call occurs.
1037d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param msg The message you would like logged.
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * @return the evaluation result of the boolean expression
1057d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws IllegalStateException if {@code expression} is true
1067d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static boolean checkState(final boolean expression, String tag, String msg) {
1087d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        if (!expression) {
1097d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            warn(tag, "Illegal State", msg, new IllegalStateException(msg));
1107d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
11165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return expression;
1127d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1137d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1147d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
1157d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws or logs if an expression involving the state of the calling
1167d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * instance, but not involving any parameters to the calling method is not true.
1177d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
1187d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param expression a boolean expression
11965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * @return the evaluation result of the boolean expression
1207d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @throws IllegalStateException if {@code expression} is true
1217d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
12265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static boolean checkState(final boolean expression) {
1237d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        checkState(expression, null, null);
12465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return expression;
1257d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1267d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1277d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    /**
1281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     * Throws or logs if the Feature is not enabled
1291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     *
1301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     * @param context an android context
1311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     * @param feature the required feature
1321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     * @param tag used to identify the source of a log message.  It usually
1331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     *            identifies the class or activity where the log call occurs
1341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     * @throws IllegalStateException if {@code feature} is not enabled
1351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko     */
1361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    public static void checkFeatureEnabled(Context context, Feature feature, String tag) {
1371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko        checkState(feature.isEnabled(context), tag, feature.toString());
1381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    }
1391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko
1401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko    /**
1417d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * Throws a {@link RuntimeException} if {@link BuildConfig#ENG} is true, else log a warning.
1427d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *
1437d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param tag Used to identify the source of a log message.  It usually
1447d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     *            identifies the class or activity where the log call occurs.
1457d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     * @param msg The message you would like logged
1462e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko     * @param e The exception to wrap with a RuntimeException when thrown.
1477d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko     */
1482e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    public static void warn(String tag, String prefix, String msg, Exception e)
1492e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            throws RuntimeException {
1502e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        if (TextUtils.isEmpty(tag)) {
1512e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            tag = TAG;
1522e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
1532e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        String logMessage;
1542e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        if (TextUtils.isEmpty(msg)) {
1552e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            logMessage = prefix;
1562e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        } else if (TextUtils.isEmpty(prefix)) {
1572e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            logMessage = msg;
1582e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        } else {
1592e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            logMessage = prefix + ": " + msg;
1602e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
1612e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko
1627d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        if (BuildConfig.ENG) {
1632e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            throw new RuntimeException(msg, e);
1647d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        } else {
1657d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            Log.w(tag, logMessage, e);
1667d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
1677d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1687d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1697d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private SoftPreconditions() {
1707d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1717d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko}
172