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

Commit f693c74e authored by ryanlwlin's avatar ryanlwlin
Browse files

Fix visible mirror window after switching user

The window magnification will be set to null if the new user
doesn't request this feature. However all existed mirror windows
are not cleared. We disable all window magnification if the connection
is going to set to null.

Bug: 154077487
Test: manual test
      case 1
      1. Turn on magnification and show the mirror window
      2. Switch to another user and observe it
      case 2
      1. Turn on magnification and show the mirror window
      2. Switch to another user whose magnification is turned on.
      3. Observe if the window is gone.

Test: atest WindowMagnificationManagerTest
Change-Id: I1cf689f22587077258b857e2a114edd93a9fe1e0
parent d86b48ad
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -112,7 +112,6 @@ import com.android.internal.util.IntPair;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;

@@ -1392,17 +1391,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                && (userState.getMagnificationModeLocked()
                == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);

        if (windowMagnificationEnabled == getWindowMagnificationMgr().isConnected()) {
        if (!getWindowMagnificationMgr().requestConnection(windowMagnificationEnabled)) {
            return;
        }
        final long identity = Binder.clearCallingIdentity();
        try {
            final StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.requestWindowMagnificationConnection(windowMagnificationEnabled);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        mMainHandler.sendMessage(obtainMessage(
                AccessibilityManagerService::notifyMagnificationModeChangeToInputFilter,
                this));
+44 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Settings;
@@ -32,7 +33,9 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.accessibility.MagnificationController;
import com.android.server.statusbar.StatusBarManagerInternal;

/**
 * A class to manipulate window magnification through {@link WindowMagnificationConnectionWrapper}
@@ -111,10 +114,50 @@ public final class WindowMagnificationManager implements
     *
     * @return {@code true} if {@link IWindowMagnificationConnection} is available
     */
    public boolean isConnected() {
    @GuardedBy("mLock")
    private boolean isConnected() {
        return mConnectionWrapper != null;
    }

    /**
     * Requests {@link IWindowMagnificationConnection} through
     * {@link StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)} and
     * destroys all window magnifiers if necessary.
     *
     * @param connect {@code true} if needs connection, otherwise set the connection to null and
     *                            destroy all window magnifiers.
     * @return {@code true} if {@link IWindowMagnificationConnection} state is going to change.
     */
    public boolean requestConnection(boolean connect) {
        synchronized (mLock) {
            if (connect == isConnected()) {
                return false;
            }
            if (!connect) {
                disableAllWindowMagnifiers();
            }
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            final StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.requestWindowMagnificationConnection(connect);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        return true;
    }

    @GuardedBy("mLock")
    private void disableAllWindowMagnifiers() {
        for (int i = 0; i < mWindowMagnifiers.size(); i++) {
            final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i);
            magnifier.disable();
        }
        mWindowMagnifiers.clear();
    }

    private void resetWindowMagnifiers() {
        synchronized (mLock) {
            for (int i = 0; i < mWindowMagnifiers.size(); i++) {
+20 −6
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ import android.view.MotionEvent;
import android.view.accessibility.IWindowMagnificationConnectionCallback;

import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;

import org.junit.Before;
import org.junit.Test;
@@ -60,14 +62,16 @@ public class WindowMagnificationManagerTest {
    private static final int CURRENT_USER_ID = UserHandle.USER_CURRENT;

    private MockWindowMagnificationConnection mMockConnection;
    @Mock
    private Context mContext;
    @Mock private Context mContext;
    @Mock private StatusBarManagerInternal mMockStatusBarManagerInternal;
    private MockContentResolver mResolver;
    private WindowMagnificationManager mWindowMagnificationManager;

    @Before
    public void setUp() throws RemoteException {
        MockitoAnnotations.initMocks(this);
        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
        LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
        mResolver = new MockContentResolver();
        mMockConnection = new MockWindowMagnificationConnection();
        mWindowMagnificationManager = new WindowMagnificationManager(mContext, CURRENT_USER_ID);
@@ -259,12 +263,22 @@ public class WindowMagnificationManagerTest {
    }

    @Test
    public void isConnected_returnExpectedValue() throws RemoteException {
        assertFalse(mWindowMagnificationManager.isConnected());

    public void
            requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection()
            throws RemoteException {
        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
        mWindowMagnificationManager.enableWindowMagnifier(TEST_DISPLAY, 3f, NaN, NaN);

        assertTrue(mWindowMagnificationManager.requestConnection(false));

        assertTrue(mWindowMagnificationManager.isConnected());
        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY);
        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false);
    }

    @Test
    public void requestConnection_requestWindowMagnificationConnection() throws RemoteException {
        assertTrue(mWindowMagnificationManager.requestConnection(true));
        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true);
    }

    private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {