Connected displays: use Robolectric for tests

Use Robolectric for tests so that we don't have to deploy to a device
emulator. TestHandler is not available in Robolectric tests, so this CL
includes a substitute.

Flag: com.android.settings.flags.display_topology_pane_in_display_list
Test: atest <all moved tests>
Bug: b/399743032
Change-Id: I95721d9b90376374da7011e42c70e474b494e992
diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java
similarity index 100%
rename from tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayPreferenceFragmentTest.java
diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java b/tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java
similarity index 80%
rename from tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java
rename to tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java
index 9dd2db1..f011f85 100644
--- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java
@@ -26,9 +26,12 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Message;
 import android.os.RemoteException;
 import android.view.Display.Mode;
 
@@ -36,7 +39,6 @@
 import androidx.preference.PreferenceScreen;
 import androidx.test.core.app.ApplicationProvider;
 
-import com.android.server.testutils.TestHandler;
 import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DisplayListener;
 import com.android.settings.flags.FakeFeatureFlagsImpl;
 
@@ -44,6 +46,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayDeque;
 import java.util.List;
 
 public class ExternalDisplayTestBase {
@@ -57,11 +60,43 @@
     FakeFeatureFlagsImpl mFlags = new FakeFeatureFlagsImpl();
     Context mContext;
     DisplayListener mListener;
-    TestHandler mHandler = new TestHandler(null);
+    TestHandler mHandler;
     PreferenceManager mPreferenceManager;
     PreferenceScreen mPreferenceScreen;
     List<DisplayDevice> mDisplays;
 
+    static class TestHandler extends Handler {
+        private final ArrayDeque<Message> mPending = new ArrayDeque<>();
+        private final Handler mSubhandler;
+
+        TestHandler(Handler subhandler) {
+            mSubhandler = subhandler;
+        }
+
+        ArrayDeque<Message> getPendingMessages() {
+            return mPending;
+        }
+
+        /**
+         * Schedules to send the message upon next invocation of {@link #flush()}. This ignores the
+         * time argument since our code doesn't meaningfully use it, but this is the most convenient
+         * way to intercept both Message and Callback objects synchronously.
+         */
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            mPending.add(msg);
+            return true;
+        }
+
+        void flush() {
+            for (var msg : mPending) {
+                mSubhandler.sendMessage(msg);
+            }
+            mPending.clear();
+            shadowOf(mSubhandler.getLooper()).idle();
+        }
+    }
+
     /**
      * Setup.
      */
@@ -85,6 +120,7 @@
             doReturn(display).when(mMockedInjector).getDisplay(display.getId());
         }
         doReturn(mFlags).when(mMockedInjector).getFlags();
+        mHandler = new TestHandler(mContext.getMainThreadHandler());
         doReturn(mHandler).when(mMockedInjector).getHandler();
         doReturn("").when(mMockedInjector).getSystemProperty(
                 VIRTUAL_DISPLAY_PACKAGE_NAME_SYSTEM_PROPERTY);
diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayUpdaterTest.java
similarity index 100%
rename from tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayUpdaterTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/display/ExternalDisplayUpdaterTest.java
diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java
similarity index 100%
rename from tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java