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

Commit 2f53ef05 authored by Roy Chou's avatar Roy Chou
Browse files

feat(fullscreen magnification): magnification should not work when no sysui connection

For sysui fullscreen magnification border implementation, if the connection is not established, the magnification should not work. So we won't have a magnified but no border situation.
To achieve this, we add flag and connection check in FullScreenMagnificationController#setScaleAndCenter. If the flag on and no connection, it will just return without activating/changing the magnification, so we can block magnification control from both AccessibilityService.setMagnificationConfig and AccessibilityShortcut.
Besides, when disconnected the fullscreen magnification should deactivate for the consistency. So in AccessibilityManagerService if setMagnificationConnection with null object, it will reset the fullscreen magnification.

Bug: 330420781
Flag: ACONFIG always_draw_magnification_fullscreen_border DEVELOPMENT
Test: manually flip the flag
      atest AccessibilityManagerServiceTest
      atest FullScreenMagnificationControllerTest
Change-Id: Iaf3daf8819182678fe85a78ccb5718b2ecd4889e
parent b485ab8a
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -4623,6 +4623,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                android.Manifest.permission.STATUS_BAR_SERVICE);

        getMagnificationConnectionManager().setConnection(connection);

        if (com.android.window.flags.Flags.alwaysDrawMagnificationFullscreenBorder()
                && connection == null
                && mMagnificationController.isFullScreenMagnificationControllerInitialized()) {
            // Since the connection does not exist, the system ui cannot provide the border
            // implementation for fullscreen magnification. So we call reset to deactivate the
            // fullscreen magnification to prevent the magnified but no border situation.
            final ArrayList<Display> displays = getValidDisplayList();
            for (int i = 0; i < displays.size(); i++) {
                final Display display = displays.get(i);
                getMagnificationController().getFullScreenMagnificationController()
                        .reset(display.getDisplayId(), false);
            }
        }
    }

    /**
+14 −3
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ public class FullScreenMagnificationController implements

    private final MagnificationThumbnailFeatureFlag mMagnificationThumbnailFeatureFlag;
    @NonNull private final Supplier<MagnificationThumbnail> mThumbnailSupplier;
    @NonNull private final Supplier<Boolean> mMagnificationConnectionStateSupplier;

    /**
     * This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
@@ -682,6 +683,12 @@ public class FullScreenMagnificationController implements
            if (!mRegistered) {
                return false;
            }
            // If the border implementation is on system ui side but the connection is not
            // established, the fullscreen magnification should not work.
            if (com.android.window.flags.Flags.alwaysDrawMagnificationFullscreenBorder()
                    && !mMagnificationConnectionStateSupplier.get()) {
                return false;
            }
            if (DEBUG) {
                Slog.i(LOG_TAG,
                        "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
@@ -941,7 +948,8 @@ public class FullScreenMagnificationController implements
            @NonNull AccessibilityTraceManager traceManager, @NonNull Object lock,
            @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback,
            @NonNull MagnificationScaleProvider scaleProvider,
            @NonNull Executor backgroundExecutor) {
            @NonNull Executor backgroundExecutor,
            @NonNull Supplier<Boolean> magnificationConnectionStateSupplier) {
        this(
                new ControllerContext(
                        context,
@@ -955,7 +963,8 @@ public class FullScreenMagnificationController implements
                /* thumbnailSupplier= */ null,
                backgroundExecutor,
                () -> new Scroller(context),
                TimeAnimator::new);
                TimeAnimator::new,
                magnificationConnectionStateSupplier);
    }

    /** Constructor for tests */
@@ -968,11 +977,13 @@ public class FullScreenMagnificationController implements
            Supplier<MagnificationThumbnail> thumbnailSupplier,
            @NonNull Executor backgroundExecutor,
            Supplier<Scroller> scrollerSupplier,
            Supplier<TimeAnimator> timeAnimatorSupplier) {
            Supplier<TimeAnimator> timeAnimatorSupplier,
            @NonNull Supplier<Boolean> magnificationConnectionStateSupplier) {
        mControllerCtx = ctx;
        mLock = lock;
        mScrollerSupplier = scrollerSupplier;
        mTimeAnimatorSupplier = timeAnimatorSupplier;
        mMagnificationConnectionStateSupplier = magnificationConnectionStateSupplier;
        mMainThreadId = mControllerCtx.getContext().getMainLooper().getThread().getId();
        mScreenStateObserver = new ScreenStateObserver(mControllerCtx.getContext(), this);
        addInfoChangedCallback(magnificationInfoChangedCallback);
+9 −1
Original line number Diff line number Diff line
@@ -798,7 +798,9 @@ public class MagnificationController implements MagnificationConnectionManager.C
                        mLock,
                        this,
                        mScaleProvider,
                        mBackgroundExecutor
                        mBackgroundExecutor,
                        () -> (isMagnificationConnectionManagerInitialized()
                                && getMagnificationConnectionManager().isConnected())
                );
            }
        }
@@ -831,6 +833,12 @@ public class MagnificationController implements MagnificationConnectionManager.C
        }
    }

    private boolean isMagnificationConnectionManagerInitialized() {
        synchronized (mLock) {
            return mMagnificationConnectionManager != null;
        }
    }

    private @Nullable PointF getCurrentMagnificationCenterLocked(int displayId, int targetMode) {
        if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
            if (mMagnificationConnectionManager == null
+14 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.view.accessibility.Flags.FLAG_SKIP_ACCESSIBILITY_WARNING_D
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG;
import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;

import static com.google.common.truth.Truth.assertThat;

@@ -68,6 +69,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -222,6 +224,8 @@ public class AccessibilityManagerServiceTest {
                mMockMagnificationConnectionManager);
        when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
                mMockFullScreenMagnificationController);
        when(mMockMagnificationController.isFullScreenMagnificationControllerInitialized())
                .thenReturn(true);
        when(mMockMagnificationController.supportWindowMagnification()).thenReturn(true);
        when(mMockWindowManagerService.getAccessibilityController()).thenReturn(
                mMockA11yController);
@@ -568,6 +572,16 @@ public class AccessibilityManagerServiceTest {
        verify(mMockMagnificationController).setAlwaysOnMagnificationEnabled(eq(true));
    }

    @Test
    @EnableFlags(FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
    public void testSetConnectionNull_borderFlagEnabled_unregisterFullScreenMagnification()
            throws RemoteException {
        mA11yms.setMagnificationConnection(null);

        verify(mMockFullScreenMagnificationController, atLeastOnce()).reset(
                /* displayId= */ anyInt(), /* animate= */ anyBoolean());
    }

    @SmallTest
    @Test
    public void testOnClientChange_magnificationEnabledAndCapabilityAll_requestConnection() {
+22 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MOD

import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
import static com.android.server.accessibility.magnification.MockMagnificationConnection.TEST_DISPLAY;
import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -139,6 +140,8 @@ public class FullScreenMagnificationControllerTest {

    private final TimeAnimator mMockTimeAnimator = mock(TimeAnimator.class);

    private boolean mMockMagnificationConnectionState;

    FullScreenMagnificationController mFullScreenMagnificationController;

    public DisplayManagerInternal mDisplayManagerInternalMock = mock(DisplayManagerInternal.class);
@@ -175,6 +178,8 @@ public class FullScreenMagnificationControllerTest {

        mScaleProvider = new MagnificationScaleProvider(mMockContext);

        // Assume the connection is established by default
        mMockMagnificationConnectionState = true;
        mFullScreenMagnificationController =
                new FullScreenMagnificationController(
                        mMockControllerCtx,
@@ -184,7 +189,8 @@ public class FullScreenMagnificationControllerTest {
                        () -> mMockThumbnail,
                        ConcurrentUtils.DIRECT_EXECUTOR,
                        () -> mMockScroller,
                        () -> mMockTimeAnimator);
                        () -> mMockTimeAnimator,
                        () -> mMockMagnificationConnectionState);
    }

    @After
@@ -196,7 +202,6 @@ public class FullScreenMagnificationControllerTest {
                CURRENT_USER_ID);
    }


    @Test
    public void testRegister_WindowManagerAndContextRegisterListeners() {
        register(DISPLAY_0);
@@ -290,6 +295,21 @@ public class FullScreenMagnificationControllerTest {
        mFullScreenMagnificationController.unregister(displayId);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
    public void testSetScale_noConnection_doNothing() {
        register(TEST_DISPLAY);

        // Assume that the connection does not exist.
        mMockMagnificationConnectionState = false;

        final float scale = 2.0f;
        final PointF center = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
        assertFalse(mFullScreenMagnificationController
                .setScale(TEST_DISPLAY, scale, center.x, center.y, false, SERVICE_ID_1));
        assertFalse(mFullScreenMagnificationController.isActivated(TEST_DISPLAY));
    }

    @Test
    public void testSetScale_noAnimation_shouldGoStraightToWindowManagerAndUpdateState() {
        for (int i = 0; i < DISPLAY_COUNT; i++) {
Loading