fix(magnification thumbnail): fix thumbnail not refreshing when orientation changes or IME opens
Fix: b/279538599
Fix: b/279538852
Fix: b/279527264
Test: manual
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:602b563ad69f508ada7fed55b9b19d339a3cd7e0)
Merged-In: Idb0855b78a867d120ac0911fba1b5f8c66da1c13
Change-Id: Idb0855b78a867d120ac0911fba1b5f8c66da1c13
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index b1cdc50..ba3d434 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -319,6 +319,10 @@
FullScreenMagnificationController::onUserContextChanged,
FullScreenMagnificationController.this, mDisplayId);
mControllerCtx.getHandler().sendMessage(m);
+
+ synchronized (mLock) {
+ refreshThumbnail();
+ }
}
@Override
@@ -344,7 +348,7 @@
mMagnificationRegion.set(magnified);
mMagnificationRegion.getBounds(mMagnificationBounds);
- refreshThumbnail(getScale(), getCenterX(), getCenterY());
+ refreshThumbnail();
// It's possible that our magnification spec is invalid with the new bounds.
// Adjust the current spec's offsets if necessary.
@@ -602,13 +606,13 @@
}
@GuardedBy("mLock")
- void refreshThumbnail(float scale, float centerX, float centerY) {
+ void refreshThumbnail() {
if (mMagnificationThumbnail != null) {
mMagnificationThumbnail.setThumbnailBounds(
mMagnificationBounds,
- scale,
- centerX,
- centerY
+ getScale(),
+ getCenterX(),
+ getCenterY()
);
}
}
@@ -627,7 +631,7 @@
// We call refreshThumbnail when the thumbnail is just created to set current
// magnification bounds to thumbnail. It to prevent the thumbnail size has not yet
// updated properly and thus shows with huge size. (b/276314641)
- refreshThumbnail(getScale(), getCenterX(), getCenterY());
+ refreshThumbnail();
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
index 03fa93d..3772fa7 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
@@ -99,15 +99,17 @@
Log.d(LOG_TAG, "setThumbnailBounds " + currentBounds);
}
mHandler.post(() -> {
- mWindowBounds = currentBounds;
- setBackgroundBounds();
+ refreshBackgroundBounds(currentBounds);
if (mVisible) {
updateThumbnailMainThread(scale, centerX, centerY);
}
});
}
- private void setBackgroundBounds() {
+ @MainThread
+ private void refreshBackgroundBounds(Rect currentBounds) {
+ mWindowBounds = currentBounds;
+
Point magnificationBoundary = getMagnificationThumbnailPadding(mContext);
mThumbnailWidth = (int) (mWindowBounds.width() / BG_ASPECT_RATIO);
mThumbnailHeight = (int) (mWindowBounds.height() / BG_ASPECT_RATIO);
@@ -117,6 +119,10 @@
mBackgroundParams.height = mThumbnailHeight;
mBackgroundParams.x = initX;
mBackgroundParams.y = initY;
+
+ if (mVisible) {
+ mWindowManager.updateViewLayout(mThumbnailLayout, mBackgroundParams);
+ }
}
@MainThread
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index e6ef044..5b5c8d4 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -29,6 +29,7 @@
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -202,6 +203,7 @@
assertFalse(mFullScreenMagnificationController.isRegistered(DISPLAY_0));
assertFalse(mFullScreenMagnificationController.isRegistered(DISPLAY_1));
+ // Once for each display on unregister
verify(mMockThumbnail, times(2)).hideThumbnail();
}
@@ -543,7 +545,11 @@
// The first time is triggered when the thumbnail is just created.
// The second time is triggered when the magnification region changed.
verify(mMockThumbnail, times(2)).setThumbnailBounds(
- any(), anyFloat(), anyFloat(), anyFloat());
+ /* currentBounds= */ any(),
+ /* scale= */ anyFloat(),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
}
@Test
@@ -681,6 +687,9 @@
checkActivatedAndMagnifying(/* activated= */ true, /* magnifying= */ true, displayId);
assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, SERVICE_ID_2));
checkActivatedAndMagnifying(/* activated= */ false, /* magnifying= */ false, displayId);
+
+ // Once on init before it's activated and once for reset
+ verify(mMockThumbnail, times(2)).hideThumbnail();
}
@Test
@@ -783,6 +792,9 @@
mMessageCapturingHandler.sendAllMessages();
checkActivatedAndMagnifying(/* activated= */ false, /* magnifying= */ false, DISPLAY_0);
checkActivatedAndMagnifying(/* activated= */ false, /* magnifying= */ false, DISPLAY_1);
+
+ // Twice for each display: once on init before it's activated and once for screen off
+ verify(mMockThumbnail, times(4)).hideThumbnail();
}
@Test
@@ -847,6 +859,15 @@
mMessageCapturingHandler.sendAllMessages();
checkActivatedAndMagnifying(
/* activated= */ expectedActivated, /* magnifying= */ false, displayId);
+
+ if (expectedActivated) {
+ verify(mMockThumbnail, times(2)).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ /* scale= */ anyFloat(),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
+ }
}
@Test
@@ -950,6 +971,13 @@
INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER, scale);
assertThat(endSpec, closeTo(getMagnificationSpec(scale, expectedOffsets)));
verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec)));
+
+ verify(mMockThumbnail, atLeastOnce()).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ eq(scale),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
}
@Test
@@ -984,6 +1012,13 @@
INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER, scale);
assertThat(endSpec, closeTo(getMagnificationSpec(scale, expectedOffsets)));
verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec)));
+
+ verify(mMockThumbnail, atLeastOnce()).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ eq(scale),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
}
@Test
@@ -1246,6 +1281,13 @@
callbacks.onImeWindowVisibilityChanged(true);
mMessageCapturingHandler.sendAllMessages();
verify(mRequestObserver).onImeWindowVisibilityChanged(eq(DISPLAY_0), eq(true));
+
+ verify(mMockThumbnail, atLeastOnce()).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ /* scale= */ anyFloat(),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
}
@Test
@@ -1270,6 +1312,15 @@
mFullScreenMagnificationController.onUserContextChanged(DISPLAY_0);
verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(DISPLAY_0), eq(false));
+ verify(mMockThumbnail).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ /* scale= */ anyFloat(),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
+
+ // Once on init before it's activated and once for reset
+ verify(mMockThumbnail, times(2)).hideThumbnail();
}
@Test
@@ -1281,6 +1332,12 @@
assertEquals(1.0f, mFullScreenMagnificationController.getScale(DISPLAY_0), 0);
assertTrue(mFullScreenMagnificationController.isActivated(DISPLAY_0));
+ verify(mMockThumbnail).setThumbnailBounds(
+ /* currentBounds= */ any(),
+ /* scale= */ anyFloat(),
+ /* centerX= */ anyFloat(),
+ /* centerY= */ anyFloat()
+ );
}
private void setScaleToMagnifying() {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
index 3baa102..8faddf8 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationThumbnailTest.java
@@ -187,6 +187,29 @@
.addView(eq(mMagnificationThumbnail.mThumbnailLayout), any());
verify(mMockWindowManager, never())
.removeView(eq(mMagnificationThumbnail.mThumbnailLayout));
+ verify(mMockWindowManager, never())
+ .updateViewLayout(eq(mMagnificationThumbnail.mThumbnailLayout), any());
+ }
+
+ @Test
+ public void whenVisible_setBoundsUpdatesLayout() throws InterruptedException {
+ runOnMainSync(() -> mMagnificationThumbnail.updateThumbnail(
+ /* scale= */ 2f,
+ /* centerX= */ 5,
+ /* centerY= */ 10
+ ));
+ runOnMainSync(() -> mMagnificationThumbnail.setThumbnailBounds(
+ new Rect(),
+ /* scale= */ 2f,
+ /* centerX= */ 5,
+ /* centerY= */ 10
+ ));
+ idle();
+
+ verify(mMockWindowManager).updateViewLayout(
+ eq(mMagnificationThumbnail.mThumbnailLayout),
+ /* params= */ any()
+ );
}
private static void idle() {