Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8daf811 authored by Presubmit Automerger Backend's avatar Presubmit Automerger Backend
Browse files

[automerge] Notifies magnification change for the transitioning target mode 2p: d560a73c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17040106

Bug: 209701404
Bug: 210636326
Change-Id: Ib132ce87c30adbb8629ff69b24abc6b2614b3434
parents 8eeaa678 d560a73c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -353,6 +353,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        mSourceBounds.setEmpty();
        updateSystemUIStateIfNeeded();
        mContext.unregisterComponentCallbacks(this);
        // Notify source bounds empty when magnification is deleted.
        mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, new Rect());
    }

    @Override
+16 −0
Original line number Diff line number Diff line
@@ -292,6 +292,22 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        assertFalse(hasMagnificationOverlapFlag());
    }

    @Test
    public void deleteWindowMagnification_notifySourceBoundsChanged() {
        mInstrumentation.runOnMainSync(
                () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
                        Float.NaN,
                        Float.NaN));

        mInstrumentation.runOnMainSync(
                () -> mWindowMagnificationController.deleteWindowMagnification());

        // The first time is for notifying magnification enabled and the second time is for
        // notifying magnification disabled.
        verify(mWindowMagnifierCallback, times(2)).onSourceBoundsChanged(
                (eq(mContext.getDisplayId())), any());
    }

    @Test
    public void moveMagnifier_schedulesFrame() {
        mInstrumentation.runOnMainSync(() -> {
+9 −8
Original line number Diff line number Diff line
@@ -356,13 +356,6 @@ public class FullScreenMagnificationController implements
                        mSpecAnimationBridge, spec, animationCallback);
                mControllerCtx.getHandler().sendMessage(m);
            }

            final boolean lastMagnificationActivated = mMagnificationActivated;
            mMagnificationActivated = spec.scale > 1.0f;
            if (mMagnificationActivated != lastMagnificationActivated) {
                mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
                        mDisplayId, mMagnificationActivated);
            }
        }

        /**
@@ -376,9 +369,17 @@ public class FullScreenMagnificationController implements

        @GuardedBy("mLock")
        void onMagnificationChangedLocked() {
            final float scale = getScale();
            final boolean lastMagnificationActivated = mMagnificationActivated;
            mMagnificationActivated = scale > 1.0f;
            if (mMagnificationActivated != lastMagnificationActivated) {
                mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
                        mDisplayId, mMagnificationActivated);
            }

            final MagnificationConfig config = new MagnificationConfig.Builder()
                    .setMode(MAGNIFICATION_MODE_FULLSCREEN)
                    .setScale(getScale())
                    .setScale(scale)
                    .setCenterX(getCenterX())
                    .setCenterY(getCenterY()).build();
            mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId,
+122 −20
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.accessibility.magnification;

import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN;
import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW;
import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
@@ -111,6 +112,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
    @GuardedBy("mLock")
    private final SparseLongArray mFullScreenModeEnabledTimeArray = new SparseLongArray();

    /**
     * The transitioning magnification modes on the displays. The controller notifies
     * magnification change depending on the target config mode.
     * If the target mode is null, it means the config mode of the display is not
     * transitioning.
     */
    @GuardedBy("mLock")
    private final SparseArray<Integer> mTransitionModes = new SparseArray();

    @GuardedBy("mLock")
    private final SparseArray<WindowManagerInternal.AccessibilityControllerInternal
            .UiChangesForAccessibilityCallbacks> mAccessibilityCallbacksDelegateArray =
@@ -213,6 +223,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
        final PointF currentCenter = getCurrentMagnificationCenterLocked(displayId, targetMode);
        final DisableMagnificationCallback animationCallback =
                getDisableMagnificationEndRunnableLocked(displayId);

        if (currentCenter == null && animationCallback == null) {
            transitionCallBack.onResult(displayId, true);
            return;
@@ -233,6 +244,9 @@ public class MagnificationController implements WindowMagnificationManager.Callb
            transitionCallBack.onResult(displayId, true);
            return;
        }

        setTransitionState(displayId, targetMode);

        final FullScreenMagnificationController screenMagnificationController =
                getFullScreenMagnificationController();
        final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
@@ -286,19 +300,21 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                Slog.w(TAG, "Discard previous animation request");
                animationCallback.setExpiredAndRemoveFromListLocked();
            }

            final FullScreenMagnificationController screenMagnificationController =
                    getFullScreenMagnificationController();
            final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
            final float targetScale = Float.isNaN(config.getScale())
                    ? getTargetModeScaleFromCurrentMagnification(displayId, targetMode)
                    : config.getScale();
            if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
            try {
                setTransitionState(displayId, targetMode);

                if (targetMode == MAGNIFICATION_MODE_WINDOW) {
                    screenMagnificationController.reset(displayId, false);
                    windowMagnificationMgr.enableWindowMagnification(displayId,
                            targetScale, magnificationCenter.x, magnificationCenter.y,
                            animate ? STUB_ANIMATION_CALLBACK : null, id);
            } else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
                } else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) {
                    windowMagnificationMgr.disableWindowMagnification(displayId, false, null);
                    if (!screenMagnificationController.isRegistered(displayId)) {
                        screenMagnificationController.register(displayId);
@@ -307,6 +323,29 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                            magnificationCenter.x, magnificationCenter.y, animate,
                            id);
                }
            } finally {
                // Reset transition state after enabling target mode.
                setTransitionState(displayId, null);
            }
        }
    }

    /**
     * Sets magnification config mode transition state. Called when the mode transition starts and
     * ends. If the targetMode and the display id are null, it resets all
     * the transition state.
     *
     * @param displayId  The logical display id
     * @param targetMode The transition target mode. It is not transitioning, if the target mode
     *                   is set null
     */
    private void setTransitionState(Integer displayId, Integer targetMode) {
        synchronized (mLock) {
            if (targetMode == null && displayId == null) {
                mTransitionModes.clear();
            } else {
                mTransitionModes.put(displayId, targetMode);
            }
        }
    }

@@ -413,6 +452,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb

    @Override
    public void onSourceBoundsChanged(int displayId, Rect bounds) {
        if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) {
            final MagnificationConfig config = new MagnificationConfig.Builder()
                    .setMode(MAGNIFICATION_MODE_WINDOW)
                    .setScale(getWindowMagnificationMgr().getScale(displayId))
@@ -420,12 +460,50 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                    .setCenterY(bounds.exactCenterY()).build();
            mAms.notifyMagnificationChanged(displayId, new Region(bounds), config);
        }
    }

    @Override
    public void onFullScreenMagnificationChanged(int displayId, @NonNull Region region,
            @NonNull MagnificationConfig config) {
        if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) {
            mAms.notifyMagnificationChanged(displayId, region, config);
        }
    }

    /**
     * Should notify magnification change for the given display under the conditions below
     *
     * <ol>
     *   <li> 1. No mode transitioning and the change mode is active. </li>
     *   <li> 2. No mode transitioning and all the modes are inactive. </li>
     *   <li> 3. It is mode transitioning and the change mode is the transition mode. </li>
     * </ol>
     *
     * @param displayId  The logical display id
     * @param changeMode The mode that has magnification spec change
     */
    private boolean shouldNotifyMagnificationChange(int displayId, int changeMode) {
        synchronized (mLock) {
            final boolean fullScreenMagnifying = mFullScreenMagnificationController != null
                    && mFullScreenMagnificationController.isMagnifying(displayId);
            final boolean windowEnabled = mWindowMagnificationMgr != null
                    && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
            final Integer transitionMode = mTransitionModes.get(displayId);
            if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenMagnifying)
                    || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled))
                    && (transitionMode == null)) {
                return true;
            }
            if ((!fullScreenMagnifying && !windowEnabled)
                    && (transitionMode == null)) {
                return true;
            }
            if (transitionMode != null && changeMode == transitionMode) {
                return true;
            }
        }
        return false;
    }

    private void disableFullScreenMagnificationIfNeeded(int displayId) {
        final FullScreenMagnificationController fullScreenMagnificationController =
@@ -740,9 +818,32 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                    return;
                }
                setExpiredAndRemoveFromListLocked();
                setTransitionState(mDisplayId, null);

                if (success) {
                    adjustCurrentCenterIfNeededLocked();
                    applyMagnificationModeLocked(mTargetMode);
                } else {
                    // Notify magnification change if magnification is inactive when the
                    // transition is failed. This is for the failed transition from
                    // full-screen to window mode. Disable magnification callback helps to send
                    // magnification inactive change since FullScreenMagnificationController
                    // would not notify magnification change if the spec is not changed.
                    final FullScreenMagnificationController screenMagnificationController =
                            getFullScreenMagnificationController();
                    if (mCurrentMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
                            && !screenMagnificationController.isMagnifying(mDisplayId)) {
                        MagnificationConfig.Builder configBuilder =
                                new MagnificationConfig.Builder();
                        Region region = new Region();
                        configBuilder.setMode(MAGNIFICATION_MODE_FULLSCREEN)
                                .setScale(screenMagnificationController.getScale(mDisplayId))
                                .setCenterX(screenMagnificationController.getCenterX(mDisplayId))
                                .setCenterY(screenMagnificationController.getCenterY(mDisplayId));
                        screenMagnificationController.getMagnificationRegion(mDisplayId,
                                region);
                        mAms.notifyMagnificationChanged(mDisplayId, region, configBuilder.build());
                    }
                }
                updateMagnificationButton(mDisplayId, mTargetMode);
                if (mTransitionCallBack != null) {
@@ -770,6 +871,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
                    return;
                }
                setExpiredAndRemoveFromListLocked();
                setTransitionState(mDisplayId, null);
                applyMagnificationModeLocked(mCurrentMode);
                updateMagnificationButton(mDisplayId, mCurrentMode);
                if (mTransitionCallBack != null) {
+115 −5
Original line number Diff line number Diff line
@@ -197,6 +197,31 @@ public class MagnificationControllerTest {
        assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
    }

    @Test
    public void transitionToWindowModeFailedByReset_fullScreenMagnifying_notifyTransitionFailed()
            throws RemoteException {
        setMagnificationEnabled(MODE_FULLSCREEN);

        mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY,
                MODE_WINDOW,
                mTransitionCallBack);

        verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
                mCallbackArgumentCaptor.capture());
        // The transition is interrupted and failed by calling reset.
        mCallbackArgumentCaptor.getValue().onResult(false);
        verify(mTransitionCallBack).onResult(TEST_DISPLAY, false);
        final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
                MagnificationConfig.class);
        // The first time is for notifying full-screen enabled and the second time is for notifying
        // the target mode transitions failed.
        verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
                configCaptor.capture());
        final MagnificationConfig actualConfig = configCaptor.getValue();
        assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0);
        assertEquals(1.0f, actualConfig.getScale(), 0);
    }

    @Test
    public void transitionToWindowMode_disablingWindowMode_enablingWindowWithFormerCenter()
            throws RemoteException {
@@ -478,6 +503,92 @@ public class MagnificationControllerTest {
        assertEquals(config.getScale(), actualConfig.getScale(), 0);
    }

    @Test
    public void transitionMagnificationMode_windowEnabled_notifyTargetMagnificationChanged()
            throws RemoteException {
        setMagnificationEnabled(MODE_WINDOW);

        mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY,
                MODE_FULLSCREEN, mTransitionCallBack);
        mMockConnection.invokeCallbacks();

        final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
                MagnificationConfig.class);
        // The first time is for notifying window enabled and the second time is for notifying
        // the target mode transitions.
        verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
                configCaptor.capture());
        final MagnificationConfig actualConfig = configCaptor.getValue();
        assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0);
    }

    @Test
    public void transitionConfigMode_windowEnabled_notifyTargetMagnificationChanged()
            throws RemoteException {
        setMagnificationEnabled(MODE_WINDOW);

        final MagnificationConfig config = obtainMagnificationConfig(MODE_FULLSCREEN);
        mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY,
                config, true, TEST_SERVICE_ID);
        mMockConnection.invokeCallbacks();

        final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
                MagnificationConfig.class);
        // The first time is for notifying window enabled and the second time is for notifying
        // the target mode transitions.
        verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
                configCaptor.capture());
        final MagnificationConfig actualConfig = configCaptor.getValue();
        assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0);
        assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0);
        assertEquals(config.getScale(), actualConfig.getScale(), 0);
    }

    @Test
    public void transitionMagnificationMode_fullScreenEnabled_notifyTargetMagnificationChanged()
            throws RemoteException {
        setMagnificationEnabled(MODE_FULLSCREEN);

        mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY,
                MODE_WINDOW, mTransitionCallBack);
        verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
                mCallbackArgumentCaptor.capture());
        mCallbackArgumentCaptor.getValue().onResult(true);
        mMockConnection.invokeCallbacks();

        final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
                MagnificationConfig.class);
        // The first time is for notifying full-screen enabled and the second time is for notifying
        // the target mode transitions.
        verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
                configCaptor.capture());
        final MagnificationConfig actualConfig = configCaptor.getValue();
        assertEquals(MODE_WINDOW, actualConfig.getMode(), 0);
    }

    @Test
    public void transitionConfigMode_fullScreenEnabled_notifyTargetMagnificationChanged()
            throws RemoteException {
        setMagnificationEnabled(MODE_FULLSCREEN);

        final MagnificationConfig config = obtainMagnificationConfig(MODE_WINDOW);
        mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY,
                config, true, TEST_SERVICE_ID);
        mMockConnection.invokeCallbacks();

        final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
                MagnificationConfig.class);
        // The first time is for notifying full-screen enabled and the second time is for notifying
        // the target mode transitions.
        verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
                configCaptor.capture());
        final MagnificationConfig actualConfig = configCaptor.getValue();
        assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0);
        assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0);
        assertEquals(config.getScale(), actualConfig.getScale(), 0);
    }


    @Test
    public void onAccessibilityActionPerformed_magnifierEnabled_showMagnificationButton()
            throws RemoteException {
@@ -743,7 +854,7 @@ public class MagnificationControllerTest {
    }

    @Test
    public void disableWindowMode_windowModeInActive_removeMagnificationButton()
    public void disableWindowMode_windowEnabled_removeMagnificationButton()
            throws RemoteException {
        setMagnificationEnabled(MODE_WINDOW);

@@ -753,7 +864,7 @@ public class MagnificationControllerTest {
    }

    @Test
    public void onFullScreenDeactivated_fullscreenModeInActive_removeMagnificationButton()
    public void onFullScreenDeactivated_fullScreenEnabled_removeMagnificationButton()
            throws RemoteException {
        setMagnificationEnabled(MODE_FULLSCREEN);
        mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
@@ -766,7 +877,7 @@ public class MagnificationControllerTest {
    }

    @Test
    public void transitionToFullScreenMode_fullscreenModeInActive_showMagnificationButton()
    public void transitionToFullScreenMode_windowEnabled_showMagnificationButton()
            throws RemoteException {
        setMagnificationEnabled(MODE_WINDOW);

@@ -779,7 +890,7 @@ public class MagnificationControllerTest {
    }

    @Test
    public void transitionToWindow_fullscreenModeInActive_showMagnificationButton()
    public void transitionToWindow_fullScreenEnabled_showMagnificationButton()
            throws RemoteException {
        setMagnificationEnabled(MODE_FULLSCREEN);

@@ -1018,7 +1129,6 @@ public class MagnificationControllerTest {
                    reset();
                }


                final MagnificationConfig config = new MagnificationConfig.Builder().setMode(
                        MODE_FULLSCREEN).setScale(mScale).setCenterX(mCenterX).setCenterY(
                        mCenterY).build();