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
This commit is contained in:
Matthew DeVore
2025-02-28 02:00:04 +00:00
parent ded1d1c0d6
commit 0a583b223e
4 changed files with 38 additions and 2 deletions

View File

@@ -26,9 +26,12 @@ import static org.mockito.ArgumentMatchers.anyInt;
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.PreferenceManager;
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.junit.Before;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayDeque;
import java.util.List;
public class ExternalDisplayTestBase {
@@ -57,11 +60,43 @@ public class ExternalDisplayTestBase {
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 @@ public class ExternalDisplayTestBase {
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);