Fix testable looper threading

In the case where an annotation was not used and the TestableLooper
was manually created, then the messages would be executed on the wrong
thread.

Also switch some handlers over to async, might save us a little time.

Test: runtest --path frameworks/base/tests/testables
Bug: 79550837
Change-Id: I70a36449ae08eb5799e2dad41a5d258bb51a3fd3
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
index 93fed85..3207b48 100644
--- a/tests/testables/src/android/testing/TestableInstrumentation.java
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -77,7 +77,7 @@
         private TestLooperManager mManager;
 
         public MainLooperManager() {
-            mMainHandler = new Handler(Looper.getMainLooper());
+            mMainHandler = Handler.createAsync(Looper.getMainLooper());
             startManaging();
         }
 
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index f1a7092..f8d223a 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -51,12 +51,12 @@
         this(acquireLooperManager(l), l);
     }
 
-    private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
+    private TestableLooper(TestLooperManager wrapper, Looper l) {
         mQueueWrapper = wrapper;
         setupQueue(l);
     }
 
-    private TestableLooper(Looper looper, boolean b) throws Exception {
+    private TestableLooper(Looper looper, boolean b) {
         setupQueue(looper);
     }
 
@@ -64,7 +64,7 @@
         return mLooper;
     }
 
-    private void setupQueue(Looper l) throws Exception {
+    private void setupQueue(Looper l) {
         mLooper = l;
         mQueue = mLooper.getQueue();
         mHandler = new Handler(mLooper);
@@ -75,7 +75,7 @@
      * the looper will not be available for any subsequent tests. This is
      * automatically handled for tests using {@link RunWithLooper}.
      */
-    public void destroy() throws NoSuchFieldException, IllegalAccessException {
+    public void destroy() {
         mQueueWrapper.release();
         if (mLooper == Looper.getMainLooper()) {
             TestableInstrumentation.releaseMain();
@@ -133,7 +133,7 @@
 
                 if (mMessageHandler != null) {
                     if (mMessageHandler.onMessageHandled(result)) {
-                        result.getTarget().dispatchMessage(result);
+                        mQueueWrapper.execute(result);
                         mQueueWrapper.recycle(result);
                     } else {
                         mQueueWrapper.recycle(result);
@@ -141,7 +141,7 @@
                         return false;
                     }
                 } else {
-                    result.getTarget().dispatchMessage(result);
+                    mQueueWrapper.execute(result);
                     mQueueWrapper.recycle(result);
                 }
             } else {
@@ -238,7 +238,7 @@
             super(base.getMethod());
             mLooper = other.mLooper;
             mTestableLooper = other;
-            mHandler = new Handler(mLooper);
+            mHandler = Handler.createAsync(mLooper);
         }
 
         public static FrameworkMethod get(FrameworkMethod base, boolean setAsMain, Object test) {
diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java
index 13e72ba..25f6a488 100644
--- a/tests/testables/tests/src/android/testing/TestableLooperTest.java
+++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java
@@ -16,6 +16,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -158,4 +159,22 @@
     public void testMainLooperAnnotation() {
         assertEquals(Looper.myLooper(), Looper.getMainLooper());
     }
+
+    @Test
+    public void testCorrectLooperExecution() throws Exception {
+        boolean[] hasRun = new boolean[] { false };
+        Runnable r = () -> {
+            assertEquals("Should run on main looper", Looper.getMainLooper(), Looper.myLooper());
+            hasRun[0] = true;
+        };
+        TestableLooper testableLooper = new TestableLooper(Looper.getMainLooper());
+        try {
+            new Handler(Looper.getMainLooper()).post(r);
+            testableLooper.processAllMessages();
+
+            assertTrue(hasRun[0]);
+        } finally {
+            testableLooper.destroy();
+        }
+    }
 }