Merge "Adjust tests to new android-support-test + espresso libraries."
diff --git a/core/tests/coretests/src/android/view/PinchZoomAction.java b/core/tests/coretests/src/android/view/PinchZoomAction.java
index 78a4b31..97fe980 100644
--- a/core/tests/coretests/src/android/view/PinchZoomAction.java
+++ b/core/tests/coretests/src/android/view/PinchZoomAction.java
@@ -16,23 +16,23 @@
 
 package android.view;
 
-import static android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull;
 import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
 import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import static org.hamcrest.Matchers.allOf;
 
 import android.os.SystemClock;
 import android.support.test.espresso.InjectEventSecurityException;
 import android.support.test.espresso.PerformException;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.MotionEvents;
-import android.support.test.espresso.action.Swiper;
 import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.action.Swiper;
 import android.support.test.espresso.util.HumanReadables;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
-import javax.annotation.Nullable;
+
 import org.hamcrest.Matcher;
 
 /**
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
index bec4180..b50d6f4 100644
--- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
@@ -16,8 +16,6 @@
 
 package android.widget.espresso;
 
-import org.hamcrest.Matcher;
-
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.ViewAction;
 import android.support.test.espresso.action.CoordinatesProvider;
@@ -25,10 +23,13 @@
 import android.support.test.espresso.action.MotionEvents.DownResultHolder;
 import android.support.test.espresso.action.Press;
 import android.support.test.espresso.action.Tapper;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 
+import org.hamcrest.Matcher;
+
 /**
  * ViewAction for performing an click on View by a mouse.
  */
@@ -41,8 +42,9 @@
         TRIPLE {
             @Override
             public Tapper.Status sendTap(UiController uiController, float[] coordinates,
-                    float[] precision) {
-                Tapper.Status stat = sendSingleTap(uiController, coordinates, precision);
+                    float[] precision, int inputDevice, int buttonState) {
+                Tapper.Status stat = sendSingleTap(uiController, coordinates, precision,
+                        inputDevice, buttonState);
                 boolean warning = false;
                 if (stat == Tapper.Status.FAILURE) {
                     return Tapper.Status.FAILURE;
@@ -55,7 +57,8 @@
                     if (0 < doubleTapMinimumTimeout) {
                         uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);
                     }
-                    stat = sendSingleTap(uiController, coordinates, precision);
+                    stat = sendSingleTap(uiController, coordinates, precision, inputDevice,
+                            buttonState);
                     if (stat == Tapper.Status.FAILURE) {
                         return Tapper.Status.FAILURE;
                     } else if (stat == Tapper.Status.WARNING) {
@@ -69,11 +72,19 @@
                     return Tapper.Status.SUCCESS;
                 }
             }
+
+            @Override
+            public Tapper.Status sendTap(UiController uiController, float[] coordinates,
+                    float[] precision) {
+                return sendTap(uiController, coordinates, precision, InputDevice.SOURCE_UNKNOWN,
+                        MotionEvent.BUTTON_PRIMARY);
+            }
         };
 
         private static Tapper.Status sendSingleTap(UiController uiController,
-                float[] coordinates, float[] precision) {
-            DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision);
+                float[] coordinates, float[] precision, int inputDevice, int buttonState) {
+            DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision,
+                    inputDevice, buttonState);
             try {
                 if (!MotionEvents.sendUp(uiController, res.down)) {
                     MotionEvents.sendCancel(uiController, res.down);
diff --git a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
index 20fd4d3..dfe8511 100644
--- a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
@@ -22,12 +22,12 @@
 
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.espresso.core.deps.guava.base.Function;
 import android.support.test.filters.SmallTest;
 import android.view.LayoutInflater;
 import android.view.View.MeasureSpec;
 
 import com.android.frameworks.coretests.R;
+import com.google.common.base.Function;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
index b597868..fe23541 100644
--- a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
+++ b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
@@ -22,7 +22,6 @@
 import android.support.test.internal.runner.ClassPathScanner;
 import android.support.test.internal.runner.ClassPathScanner.ChainedClassNameFilter;
 import android.support.test.internal.runner.ClassPathScanner.ExternalClassNameFilter;
-import android.support.test.internal.runner.TestLoader;
 import android.testing.AndroidTestingRunner;
 import android.text.TextUtils;
 import android.util.Log;
@@ -32,8 +31,11 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -69,12 +71,11 @@
     };
 
     @Test
-    public void testAllClassInheritance() {
+    public void testAllClassInheritance() throws Throwable {
         boolean anyClassWrong = false;
-        TestLoader loader = new TestLoader();
         for (String className : getClassNamesFromClassPath()) {
-            Class<?> cls = loader.loadIfTest(className);
-            if (cls == null) continue;
+            Class<?> cls = Class.forName(className, false, this.getClass().getClassLoader());		
+            if (!isTestClass(cls)) continue;
 
             boolean hasParent = false;
             for (Class<?> parent : BASE_CLS_WHITELIST) {
@@ -125,4 +126,85 @@
         return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST)
                 .stream().map(cls -> cls.getSimpleName()).toArray());
     }
+
+    /**
+     * Determines if given class is a valid test class.
+     *
+     * @param loadedClass
+     * @return <code>true</code> if loadedClass is a test
+     */
+    private boolean isTestClass(Class<?> loadedClass) {
+        try {
+            if (Modifier.isAbstract(loadedClass.getModifiers())) {
+                logDebug(String.format("Skipping abstract class %s: not a test",
+                        loadedClass.getName()));
+                return false;
+            }
+            // TODO: try to find upstream junit calls to replace these checks
+            if (junit.framework.Test.class.isAssignableFrom(loadedClass)) {
+                // ensure that if a TestCase, it has at least one test method otherwise
+                // TestSuite will throw error
+                if (junit.framework.TestCase.class.isAssignableFrom(loadedClass)) {
+                    return hasJUnit3TestMethod(loadedClass);
+                }
+                return true;
+            }
+            // TODO: look for a 'suite' method?
+            if (loadedClass.isAnnotationPresent(org.junit.runner.RunWith.class)) {
+                return true;
+            }
+            for (Method testMethod : loadedClass.getMethods()) {
+                if (testMethod.isAnnotationPresent(org.junit.Test.class)) {
+                    return true;
+                }
+            }
+            logDebug(String.format("Skipping class %s: not a test", loadedClass.getName()));
+            return false;
+        } catch (Exception e) {
+            // Defensively catch exceptions - Will throw runtime exception if it cannot load methods.
+            // For earlier versions of Android (Pre-ICS), Dalvik might try to initialize a class
+            // during getMethods(), fail to do so, hide the error and throw a NoSuchMethodException.
+            // Since the java.lang.Class.getMethods does not declare such an exception, resort to a
+            // generic catch all.
+            // For ICS+, Dalvik will throw a NoClassDefFoundException.
+            Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
+                    loadedClass.getName()));
+            return false;
+        } catch (Error e) {
+            // defensively catch Errors too
+            Log.w(TAG, String.format("%s in isTestClass for %s", e.toString(),
+                    loadedClass.getName()));
+            return false;
+        }
+    }
+
+    private boolean hasJUnit3TestMethod(Class<?> loadedClass) {
+        for (Method testMethod : loadedClass.getMethods()) {
+            if (isPublicTestMethod(testMethod)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // copied from junit.framework.TestSuite
+    private boolean isPublicTestMethod(Method m) {
+        return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+    }
+
+    // copied from junit.framework.TestSuite
+    private boolean isTestMethod(Method m) {
+        return m.getParameterTypes().length == 0 && m.getName().startsWith("test")
+                && m.getReturnType().equals(Void.TYPE);
+    }
+
+    /**
+     * Utility method for logging debug messages. Only actually logs a message if TAG is marked
+     * as loggable to limit log spam during normal use.
+     */
+    private void logDebug(String msg) {
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, msg);
+        }
+    }
 }