diff options
Diffstat (limited to 'src/com/android/messaging/util/Assert.java')
-rw-r--r-- | src/com/android/messaging/util/Assert.java | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/com/android/messaging/util/Assert.java b/src/com/android/messaging/util/Assert.java new file mode 100644 index 0000000..437965c --- /dev/null +++ b/src/com/android/messaging/util/Assert.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.messaging.util; + +import android.os.Looper; + +import java.util.Arrays; + +public final class Assert { + public static @interface RunsOnMainThread {} + public static @interface DoesNotRunOnMainThread {} + public static @interface RunsOnAnyThread {} + + private static final String TEST_THREAD_SUBSTRING = "test"; + + private static boolean sIsEngBuild; + private static boolean sShouldCrash; + + // Private constructor so no one creates this class. + private Assert() { + } + + // The proguard rules will strip this method out on user/userdebug builds. + // If you change the method signature you MUST edit proguard-release.flags. + private static void setIfEngBuild() { + sShouldCrash = sIsEngBuild = true; + } + + private static void refreshGservices(final BugleGservices gservices) { + sShouldCrash = sIsEngBuild; + if (!sShouldCrash) { + sShouldCrash = gservices.getBoolean( + BugleGservicesKeys.ASSERTS_FATAL, + BugleGservicesKeys.ASSERTS_FATAL_DEFAULT); + } + } + + // Static initializer block to find out if we're running an eng or + // release build. + static { + setIfEngBuild(); + } + + // This is called from FactoryImpl once the Gservices class is initialized. + public static void initializeGservices (final BugleGservices gservices) { + gservices.registerForChanges(new Runnable() { + @Override + public void run() { + refreshGservices(gservices); + } + }); + refreshGservices(gservices); + } + + /** + * Halt execution if this is not an eng build. + * <p>Intended for use in code paths that should be run only for tests and never on + * a real build. + * <p>Note that this will crash on a user build even though asserts don't normally + * crash on a user build. + */ + public static void isEngBuild() { + isTrueReleaseCheck(sIsEngBuild); + } + + /** + * Halt execution if this isn't the case. + */ + public static void isTrue(final boolean condition) { + if (!condition) { + fail("Expected condition to be true", false); + } + } + + /** + * Halt execution if this isn't the case. + */ + public static void isFalse(final boolean condition) { + if (condition) { + fail("Expected condition to be false", false); + } + } + + /** + * Halt execution even in release builds if this isn't the case. + */ + public static void isTrueReleaseCheck(final boolean condition) { + if (!condition) { + fail("Expected condition to be true", true); + } + } + + public static void equals(final int expected, final int actual) { + if (expected != actual) { + fail("Expected " + expected + " but got " + actual, false); + } + } + + public static void equals(final long expected, final long actual) { + if (expected != actual) { + fail("Expected " + expected + " but got " + actual, false); + } + } + + public static void equals(final Object expected, final Object actual) { + if (expected != actual + && (expected == null || actual == null || !expected.equals(actual))) { + fail("Expected " + expected + " but got " + actual, false); + } + } + + public static void oneOf(final int actual, final int ...expected) { + for (int value : expected) { + if (actual == value) { + return; + } + } + fail("Expected value to be one of " + Arrays.toString(expected) + " but was " + actual); + } + + public static void inRange( + final int val, final int rangeMinInclusive, final int rangeMaxInclusive) { + if (val < rangeMinInclusive || val > rangeMaxInclusive) { + fail("Expected value in range [" + rangeMinInclusive + ", " + + rangeMaxInclusive + "], but was " + val, false); + } + } + + public static void inRange( + final long val, final long rangeMinInclusive, final long rangeMaxInclusive) { + if (val < rangeMinInclusive || val > rangeMaxInclusive) { + fail("Expected value in range [" + rangeMinInclusive + ", " + + rangeMaxInclusive + "], but was " + val, false); + } + } + + public static void isMainThread() { + if (Looper.myLooper() != Looper.getMainLooper() + && !Thread.currentThread().getName().contains(TEST_THREAD_SUBSTRING)) { + fail("Expected to run on main thread", false); + } + } + + public static void isNotMainThread() { + if (Looper.myLooper() == Looper.getMainLooper() + && !Thread.currentThread().getName().contains(TEST_THREAD_SUBSTRING)) { + fail("Not expected to run on main thread", false); + } + } + + /** + * Halt execution if the value passed in is not null + * @param obj The object to check + */ + public static void isNull(final Object obj) { + if (obj != null) { + fail("Expected object to be null", false); + } + } + + /** + * Halt execution if the value passed in is not null + * @param obj The object to check + * @param failureMessage message to print when halting execution + */ + public static void isNull(final Object obj, final String failureMessage) { + if (obj != null) { + fail(failureMessage, false); + } + } + + /** + * Halt execution if the value passed in is null + * @param obj The object to check + */ + public static void notNull(final Object obj) { + if (obj == null) { + fail("Expected value to be non-null", false); + } + } + + public static void fail(final String message) { + fail("Assert.fail() called: " + message, false); + } + + private static void fail(final String message, final boolean crashRelease) { + LogUtil.e(LogUtil.BUGLE_TAG, message); + if (crashRelease || sShouldCrash) { + throw new AssertionError(message); + } else { + // Find the method whose assertion failed. We're using a depth of 2, because all public + // Assert methods delegate to this one (see javadoc on getCaller() for details). + StackTraceElement caller = DebugUtils.getCaller(2); + if (caller != null) { + // This log message can be de-obfuscated by the Proguard retrace tool, just like a + // full stack trace from a crash. + LogUtil.e(LogUtil.BUGLE_TAG, "\tat " + caller.toString()); + } + } + } +} |