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
This commit is contained in:
Daniel Hsieh
2022-02-23 11:50:53 +00:00
parent 07229fd519
commit dd4bdc29dc
7 changed files with 85 additions and 26 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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<WindowMagnifier> 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();
}

View File

@@ -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<IBinder> 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);
}

View File

@@ -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() {

View File

@@ -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());
}

View File

@@ -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);