SurfaceControlViewHostTests: Deflake touchable region test
ViewRootImpl propagates the touchable region to the window-manager
via a one-way call for which there is currently no way to wait
on the result. Rather than add something to the system-image
for this one test, we work around it by polling the dump. In
the future when we consolidate the client->WM interface we should
have a generic method of waiting on the completion of any
"Transaction", which can solve our problems around here.
Bug: 220765793
Test: SurfaceControlViewHostTests
Change-Id: I0ae9a48cd45685b4e4c9585521af9b86c0a9f057
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
index 0635661..8e6b6df 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
@@ -237,6 +237,34 @@
}
+ private String getTouchableRegionFromDump() {
+ final String output = runCommandAndPrintOutput("dumpsys window windows");
+ boolean foundWindow = false;
+ for (String line : output.split("\\n")) {
+ if (line.contains("ConfigChangeHandlingActivity")) {
+ foundWindow = true;
+ }
+ if (foundWindow && line.contains("touchable region")) {
+ return line;
+ }
+ }
+ return null;
+ }
+
+ private boolean waitForTouchableRegionChanged(String originalTouchableRegion) {
+ int retries = 0;
+ while (retries < 50) {
+ if (getTouchableRegionFromDump() != originalTouchableRegion) {
+ return true;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (Exception e) {
+ }
+ }
+ return false;
+ }
+
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mTestService == null) {
@@ -851,10 +879,21 @@
mInstrumentation.waitForIdleSync();
assertFalse(mClicked);
+ String originalRegion = getTouchableRegionFromDump();
+
mActivityRule.runOnUiThread(() -> {
mSurfaceView.getRootSurfaceControl().setTouchableRegion(new Region(0,0,1,1));
});
mInstrumentation.waitForIdleSync();
+ // ViewRootImpl sends the touchable region to the WM via a one-way call, which is great
+ // for performance...however not so good for testability, we have no way
+ // to verify it has arrived! It doesn't make so much sense to bloat
+ // the system image size with a completion callback for just this one test
+ // so we settle for some inelegant spin-polling on the WM dump.
+ // In the future when we revisit WM/Client interface and transactionalize
+ // everything, we should have a standard way to wait on the completion of async
+ // operations
+ waitForTouchableRegionChanged(originalRegion);
CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mSurfaceView);
mInstrumentation.waitForIdleSync();
@@ -955,4 +994,3 @@
assertTrue(mClicked);
}
}
-