From dd4bdc29dc390f9949b2cc5f2f43e68ce74bfa44 Mon Sep 17 00:00:00 2001 From: Daniel Hsieh Date: Wed, 23 Feb 2022 11:50:53 +0000 Subject: [PATCH] Add a condition of ime should be visible on tracking typing focus. We add a mIsImeWindowVisibleArray in WindowMagnificationManager to indicate whether there is a ime in the displayId Display or not. The element in mIsImeWindowVisibleArray would keep the ime's visibility attribute which can be changed by onImeWindowVisibilityChanged callback. Then, we add this element which should be true to the decision of triggering tracking typing focus functionality. Bug: 215813890 Test: Manually, I use log print to trace whether the mIsImeWindowVisibleArray is set during AccessibilityController#setMagnificationCallbacks. atest WindowMagnificationManagerTest atest FullScreenMagnificationControllerTest atest MagnificationControllerTest Change-Id: I14f172255e79d04428db86769ed49d679f2790f5 --- .../FullScreenMagnificationController.java | 13 +++--- .../MagnificationController.java | 20 +++++---- .../WindowMagnificationManager.java | 8 +++- .../server/wm/AccessibilityController.java | 17 ++++--- ...FullScreenMagnificationControllerTest.java | 2 +- .../MagnificationControllerTest.java | 6 +-- .../WindowMagnificationManagerTest.java | 45 ++++++++++++++++++- 7 files changed, 85 insertions(+), 26 deletions(-) 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 a958209669264..fa32452f389ec 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -303,7 +303,7 @@ public class FullScreenMagnificationController implements public void onImeWindowVisibilityChanged(boolean shown) { final Message m = PooledLambda.obtainMessage( FullScreenMagnificationController::notifyImeWindowVisibilityChanged, - FullScreenMagnificationController.this, shown); + FullScreenMagnificationController.this, mDisplayId, shown); mControllerCtx.getHandler().sendMessage(m); } @@ -1215,11 +1215,12 @@ public class FullScreenMagnificationController implements /** * Notifies that the IME window visibility changed. * + * @param displayId the logical display id * @param shown {@code true} means the IME window shows on the screen. Otherwise it's * hidden. */ - void notifyImeWindowVisibilityChanged(boolean shown) { - mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(shown); + void notifyImeWindowVisibilityChanged(int displayId, boolean shown) { + mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(displayId, shown); } /** @@ -1609,17 +1610,19 @@ public class FullScreenMagnificationController implements * Called when the state of the magnification activation is changed. * It is for the logging data of the magnification activation state. * - * @param displayId The logical display id. + * @param displayId the logical display id * @param activated {@code true} if the magnification is activated, otherwise {@code false}. */ void onFullScreenMagnificationActivationState(int displayId, boolean activated); /** * Called when the IME window visibility changed. + * + * @param displayId the logical display id * @param shown {@code true} means the IME window shows on the screen. Otherwise it's * hidden. */ - void onImeWindowVisibilityChanged(boolean shown); + void onImeWindowVisibilityChanged(int displayId, boolean shown); /** * Called when the magnification spec changed. diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 09e82c787c904..fcfba1cfc316e 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -38,6 +38,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.view.accessibility.MagnificationAnimationCallback; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; @@ -99,7 +100,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb // Track the active user to reset the magnification and get the associated user settings. private @UserIdInt int mUserId = UserHandle.USER_SYSTEM; @GuardedBy("mLock") - private boolean mImeWindowVisible = false; + private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); private long mWindowModeEnabledTime = 0; private long mFullScreenModeEnabledTime = 0; @@ -377,7 +378,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); mLastActivatedMode = mActivatedMode; } - logMagnificationModeWithImeOnIfNeeded(); + logMagnificationModeWithImeOnIfNeeded(displayId); disableFullScreenMagnificationIfNeeded(displayId); } else { logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, @@ -432,7 +433,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); mLastActivatedMode = mActivatedMode; } - logMagnificationModeWithImeOnIfNeeded(); + logMagnificationModeWithImeOnIfNeeded(displayId); disableWindowMagnificationIfNeeded(displayId); } else { logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, @@ -454,12 +455,12 @@ public class MagnificationController implements WindowMagnificationManager.Callb } @Override - public void onImeWindowVisibilityChanged(boolean shown) { + public void onImeWindowVisibilityChanged(int displayId, boolean shown) { synchronized (mLock) { - mImeWindowVisible = shown; + mIsImeVisibleArray.put(displayId, shown); } - getWindowMagnificationMgr().onImeWindowVisibilityChanged(shown); - logMagnificationModeWithImeOnIfNeeded(); + getWindowMagnificationMgr().onImeWindowVisibilityChanged(displayId, shown); + logMagnificationModeWithImeOnIfNeeded(displayId); } /** @@ -575,11 +576,12 @@ public class MagnificationController implements WindowMagnificationManager.Callb } } - private void logMagnificationModeWithImeOnIfNeeded() { + private void logMagnificationModeWithImeOnIfNeeded(int displayId) { final int mode; synchronized (mLock) { - if (!mImeWindowVisible || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) { + if (!mIsImeVisibleArray.get(displayId, false) + || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) { return; } mode = mActivatedMode; diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java index 50e65809f67e2..f1b6a996b6dba 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java @@ -38,6 +38,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.view.MotionEvent; import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; @@ -99,6 +100,7 @@ public class WindowMagnificationManager implements private SparseArray mWindowMagnifiers = new SparseArray<>(); // Whether the following typing focus feature for magnification is enabled. private boolean mMagnificationFollowTypingEnabled = true; + private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); private boolean mReceiverRegistered = false; @VisibleForTesting @@ -315,7 +317,8 @@ public class WindowMagnificationManager implements float toCenterY = (float) (top + bottom) / 2; synchronized (mLock) { - if (!isPositionInSourceBounds(displayId, toCenterX, toCenterY) + if (mIsImeVisibleArray.get(displayId, false) + && !isPositionInSourceBounds(displayId, toCenterX, toCenterY) && isTrackingTypingFocusEnabled(displayId)) { moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY, STUB_ANIMATION_CALLBACK); @@ -387,7 +390,8 @@ public class WindowMagnificationManager implements * * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden. */ - void onImeWindowVisibilityChanged(boolean shown) { + void onImeWindowVisibilityChanged(int displayId, boolean shown) { + mIsImeVisibleArray.put(displayId, shown); if (shown) { enableAllTrackingTypingFocus(); } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 57f77d5b7b945..e37b08f417f20 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -79,6 +79,7 @@ import android.util.ArraySet; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.TypedValue; import android.util.proto.ProtoOutputStream; import android.view.Display; @@ -138,7 +139,7 @@ final class AccessibilityController { new SparseArray<>(); private SparseArray mFocusedWindow = new SparseArray<>(); private int mFocusedDisplay = -1; - private boolean mIsImeVisible = false; + private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); // Set to true if initializing window population complete. private boolean mAllObserversInitialized = true; private final AccessibilityWindowsPopulator mAccessibilityWindowsPopulator; @@ -167,8 +168,11 @@ final class AccessibilityController { if (dc != null) { final Display display = dc.getDisplay(); if (display != null && display.getType() != Display.TYPE_OVERLAY) { - mDisplayMagnifiers.put(displayId, new DisplayMagnifier( - mService, dc, display, callbacks)); + final DisplayMagnifier magnifier = new DisplayMagnifier( + mService, dc, display, callbacks); + magnifier.notifyImeWindowVisibilityChanged( + mIsImeVisibleArray.get(displayId, false)); + mDisplayMagnifiers.put(displayId, magnifier); result = true; } } @@ -483,11 +487,13 @@ final class AccessibilityController { mAccessibilityTracing.logTrace(TAG + ".updateImeVisibilityIfNeeded", FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + ";shown=" + shown); } - if (mIsImeVisible == shown) { + + final boolean isDisplayImeVisible = mIsImeVisibleArray.get(displayId, false); + if (isDisplayImeVisible == shown) { return; } - mIsImeVisible = shown; + mIsImeVisibleArray.put(displayId, shown); final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); if (displayMagnifier != null) { displayMagnifier.notifyImeWindowVisibilityChanged(shown); @@ -523,6 +529,7 @@ final class AccessibilityController { } public void onDisplayRemoved(int displayId) { + mIsImeVisibleArray.delete(displayId); mFocusedWindow.remove(displayId); } 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 3ce2ed84d3e8f..f3a0b7fa1ea73 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 @@ -1158,7 +1158,7 @@ public class FullScreenMagnificationControllerTest { MagnificationCallbacks callbacks = getMagnificationCallbacks(DISPLAY_0); callbacks.onImeWindowVisibilityChanged(true); mMessageCapturingHandler.sendAllMessages(); - verify(mRequestObserver).onImeWindowVisibilityChanged(eq(true)); + verify(mRequestObserver).onImeWindowVisibilityChanged(eq(DISPLAY_0), eq(true)); } private void setScaleToMagnifying() { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index ec59090240f3c..ddbee988cfcb9 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -748,7 +748,7 @@ public class MagnificationControllerTest { MagnificationController spyController = spy(mMagnificationController); spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true); - spyController.onImeWindowVisibilityChanged(true); + spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true); verify(spyController).logMagnificationModeWithIme( eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)); @@ -759,7 +759,7 @@ public class MagnificationControllerTest { MagnificationController spyController = spy(mMagnificationController); spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true); - spyController.onImeWindowVisibilityChanged(true); + spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true); verify(spyController).logMagnificationModeWithIme( eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)); @@ -768,7 +768,7 @@ public class MagnificationControllerTest { @Test public void imeWindowStateShown_noMagnifying_noLogAnyMode() { MagnificationController spyController = spy(mMagnificationController); - spyController.onImeWindowVisibilityChanged(true); + spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true); verify(spyController, never()).logMagnificationModeWithIme(anyInt()); } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java index 2f75493e5e2c3..096b63cbf0044 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java @@ -281,6 +281,7 @@ public class WindowMagnificationManagerTest { throws RemoteException { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region outRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); final Rect requestedRect = outRegion.getBounds(); @@ -302,6 +303,7 @@ public class WindowMagnificationManagerTest { final float distanceY = 10f; mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region outRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); final Rect requestedRect = outRegion.getBounds(); @@ -320,6 +322,7 @@ public class WindowMagnificationManagerTest { throws RemoteException { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region outRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); final Rect requestedRect = outRegion.getBounds(); @@ -331,12 +334,29 @@ public class WindowMagnificationManagerTest { verify(mMockConnection.getConnection(), never()) .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); } + @Test + public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier() + throws RemoteException { + mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + final Region outRegion = new Region(); + mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + + mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } @Test public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier() throws RemoteException { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region outRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); final Rect requestedRect = outRegion.getBounds(); @@ -350,13 +370,33 @@ public class WindowMagnificationManagerTest { any(IRemoteMagnificationAnimationCallback.class)); } + @Test + public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier() + throws RemoteException { + mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); + final Region outRegion = new Region(); + mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); + final Rect requestedRect = outRegion.getBounds(); + requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false); + + mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY, + requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom); + + verify(mMockConnection.getConnection(), never()) + .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any()); + } + @Test public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier() throws RemoteException { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY); - mWindowMagnificationManager.onImeWindowVisibilityChanged(true); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region outRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion); final Rect requestedRect = outRegion.getBounds(); @@ -374,6 +414,7 @@ public class WindowMagnificationManagerTest { public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); final Region beforeRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); final Rect requestedRect = beforeRegion.getBounds(); @@ -392,6 +433,7 @@ public class WindowMagnificationManagerTest { public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); final Region beforeRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion); @@ -411,6 +453,7 @@ public class WindowMagnificationManagerTest { throws RemoteException { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); + mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true); mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false); final Region beforeRegion = new Region(); mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);