fix(#Magnification): reset gesture handler state when magnifier deactivates

Add FullScreenMagnificationGestureHandler as MagnificationInfoChange callbacks for FullScreenMagnificationController, so that when fullscreen magnifier resets the gesture handler would be notified and reset the state.

Bug: b/271520937
Test: manually
      atest FullScreenMagnificationControllerTest
      atest FullScreenMagnificationGestureHandlerTest
      atest MagnificationControllerTest
Change-Id: I605dbd7b0c29fb056dca6afd89d4316db7e71a08
This commit is contained in:
Roy Chou
2023-03-07 06:42:11 +00:00
parent abc36a70d7
commit d9f6d456e3
3 changed files with 84 additions and 11 deletions

View File

@@ -63,6 +63,7 @@ import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.wm.WindowManagerInternal;
import java.util.ArrayList;
import java.util.Locale;
import java.util.function.Supplier;
@@ -90,7 +91,9 @@ public class FullScreenMagnificationController implements
private final ScreenStateObserver mScreenStateObserver;
private final MagnificationInfoChangedCallback mMagnificationInfoChangedCallback;
@GuardedBy("mLock")
private final ArrayList<MagnificationInfoChangedCallback>
mMagnificationInfoChangedCallbacks = new ArrayList<>();
private final MagnificationScaleProvider mScaleProvider;
@@ -393,8 +396,10 @@ public class FullScreenMagnificationController implements
.setScale(scale)
.setCenterX(centerX)
.setCenterY(centerY).build();
mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId,
mMagnificationRegion, config);
mMagnificationInfoChangedCallbacks.forEach(callback -> {
callback.onFullScreenMagnificationChanged(mDisplayId,
mMagnificationRegion, config);
});
if (mUnregisterPending && !isActivated()) {
unregister(mDeleteAfterUnregister);
}
@@ -502,8 +507,10 @@ public class FullScreenMagnificationController implements
if (changed) {
mMagnificationActivated = activated;
mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
mDisplayId, mMagnificationActivated);
mMagnificationInfoChangedCallbacks.forEach(callback -> {
callback.onFullScreenMagnificationActivationState(
mDisplayId, mMagnificationActivated);
});
mControllerCtx.getWindowManager().setForceShowMagnifiableBounds(
mDisplayId, activated);
}
@@ -580,8 +587,10 @@ public class FullScreenMagnificationController implements
sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
if (isActivated() && (id != INVALID_SERVICE_ID)) {
mIdOfLastServiceToMagnify = id;
mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId,
mIdOfLastServiceToMagnify);
mMagnificationInfoChangedCallbacks.forEach(callback -> {
callback.onRequestMagnificationSpec(mDisplayId,
mIdOfLastServiceToMagnify);
});
}
return changed;
}
@@ -787,7 +796,7 @@ public class FullScreenMagnificationController implements
mLock = lock;
mMainThreadId = mControllerCtx.getContext().getMainLooper().getThread().getId();
mScreenStateObserver = new ScreenStateObserver(mControllerCtx.getContext(), this);
mMagnificationInfoChangedCallback = magnificationInfoChangedCallback;
addInfoChangedCallback(magnificationInfoChangedCallback);
mScaleProvider = scaleProvider;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mThumbnailSupplier = thumbnailSupplier;
@@ -1349,7 +1358,11 @@ public class FullScreenMagnificationController implements
* hidden.
*/
void notifyImeWindowVisibilityChanged(int displayId, boolean shown) {
mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(displayId, shown);
synchronized (mLock) {
mMagnificationInfoChangedCallbacks.forEach(callback -> {
callback.onImeWindowVisibilityChanged(displayId, shown);
});
}
}
private void onScreenTurnedOff() {
@@ -1411,6 +1424,18 @@ public class FullScreenMagnificationController implements
}
}
void addInfoChangedCallback(@NonNull MagnificationInfoChangedCallback callback) {
synchronized (mLock) {
mMagnificationInfoChangedCallbacks.add(callback);
}
}
void removeInfoChangedCallback(@NonNull MagnificationInfoChangedCallback callback) {
synchronized (mLock) {
mMagnificationInfoChangedCallbacks.remove(callback);
}
}
private boolean traceEnabled() {
return mControllerCtx.getTraceManager().isA11yTracingEnabledForTypes(
FLAGS_WINDOW_MANAGER_INTERNAL);
@@ -1709,7 +1734,7 @@ public class FullScreenMagnificationController implements
return animate ? STUB_ANIMATION_CALLBACK : null;
}
interface MagnificationInfoChangedCallback {
interface MagnificationInfoChangedCallback {
/**
* Called when the {@link MagnificationSpec} is changed with non-default
@@ -1722,7 +1747,6 @@ 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 activated {@code true} if the magnification is activated, otherwise {@code false}.

View File

@@ -32,6 +32,7 @@ import static java.lang.Math.abs;
import static java.util.Arrays.asList;
import static java.util.Arrays.copyOfRange;
import android.accessibilityservice.MagnificationConfig;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
@@ -40,6 +41,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PointF;
import android.graphics.Region;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -129,6 +131,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@VisibleForTesting final FullScreenMagnificationController mFullScreenMagnificationController;
private final FullScreenMagnificationController.MagnificationInfoChangedCallback
mMagnificationInfoChangedCallback;
@VisibleForTesting final DelegatingState mDelegatingState;
@VisibleForTesting final DetectingState mDetectingState;
@VisibleForTesting final PanningScalingState mPanningScalingState;
@@ -158,6 +162,40 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
+ ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
}
mFullScreenMagnificationController = fullScreenMagnificationController;
mMagnificationInfoChangedCallback =
new FullScreenMagnificationController.MagnificationInfoChangedCallback() {
@Override
public void onRequestMagnificationSpec(int displayId, int serviceId) {
return;
}
@Override
public void onFullScreenMagnificationActivationState(int displayId,
boolean activated) {
if (displayId != mDisplayId) {
return;
}
if (!activated) {
clearAndTransitionToStateDetecting();
}
}
@Override
public void onImeWindowVisibilityChanged(int displayId, boolean shown) {
return;
}
@Override
public void onFullScreenMagnificationChanged(int displayId,
@NonNull Region region,
@NonNull MagnificationConfig config) {
return;
}
};
mFullScreenMagnificationController.addInfoChangedCallback(
mMagnificationInfoChangedCallback);
mPromptController = promptController;
mDelegatingState = new DelegatingState();
@@ -217,6 +255,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
// Check if need to reset when MagnificationGestureHandler is the last magnifying service.
mFullScreenMagnificationController.resetIfNeeded(
mDisplayId, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
mFullScreenMagnificationController.removeInfoChangedCallback(
mMagnificationInfoChangedCallback);
clearAndTransitionToStateDetecting();
}

View File

@@ -415,6 +415,15 @@ public class FullScreenMagnificationGestureHandlerTest {
returnToNormalFrom(STATE_ACTIVATED);
}
@Test
public void testMagnifierDeactivates_shortcutTriggeredState_returnToIdleState() {
goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
mFullScreenMagnificationController.reset(DISPLAY_0, /* animate= */ false);
assertIn(STATE_IDLE);
}
@Test
public void testThreeFingersOneTap_activatedState_dispatchMotionEvents() {
goFromStateIdleTo(STATE_ACTIVATED);