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

Commit 674ca99d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "fix(magnify_ime): magnifies navBar when mouse or keyboard connected" into main

parents aae9b8fe 2e9eba8a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -5484,8 +5484,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    void reapplyMagnificationSpec() {
        reapplyMagnificationSpec(getPendingTransaction());
    }

    void reapplyMagnificationSpec(Transaction t) {
        if (mMagnificationSpec != null) {
            applyMagnificationSpec(getPendingTransaction(), mMagnificationSpec);
            applyMagnificationSpec(t, mMagnificationSpec);
        }
    }

+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
                mInputDevicesReadyMonitor.notifyAll();
            }
        }

        mService.onInputDevicesChanged();

        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

+26 −1
Original line number Diff line number Diff line
@@ -700,6 +700,7 @@ public class WindowManagerService extends IWindowManager.Stub

    // Cache whether to Magnify the IME.
    private boolean mMagnifyIme = false;
    private boolean mIsMouseOrKeyboardConnected = false;

    /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
     * LAST_ANR_LIFETIME_DURATION_MSECS */
@@ -1508,11 +1509,14 @@ public class WindowManagerService extends IWindowManager.Stub
                new ConfigurationChangeSettingInternalImpl());
    }

    @VisibleForTesting
    boolean isMagnifyImeEnabled() {
        return mMagnifyIme;
    }

    boolean isMagnifyNavBarEnabled() {
        return mMagnifyIme && mIsMouseOrKeyboardConnected;
    }

    DisplayAreaPolicy.Provider getDisplayAreaPolicyProvider() {
        return mDisplayAreaPolicyProvider;
    }
@@ -1564,6 +1568,27 @@ public class WindowManagerService extends IWindowManager.Stub
        return mInputManagerCallback;
    }

    void onInputDevicesChanged() {
        boolean hasMouseOrKeyboard = false;
        for (final InputDevice device : mInputManager.getInputDevices()) {
            if (!device.isEnabled() || device.isVirtual()) {
                continue;
            }
            if (device.supportsSource(InputDevice.SOURCE_MOUSE) || device.isFullKeyboard()) {
                hasMouseOrKeyboard = true;
                break;
            }
        }
        synchronized (mGlobalLock) {
            if (mIsMouseOrKeyboardConnected != hasMouseOrKeyboard) {
                mIsMouseOrKeyboardConnected = hasMouseOrKeyboard;
                var t = mTransactionFactory.get();
                mRoot.forAllDisplays(dc -> dc.reapplyMagnificationSpec(t));
                t.apply();
            }
        }
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
+3 −1
Original line number Diff line number Diff line
@@ -4944,7 +4944,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    boolean shouldMagnify() {
        if (mAttrs.type == TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY
                || mAttrs.type == TYPE_MAGNIFICATION_OVERLAY
                || mAttrs.type == TYPE_NAVIGATION_BAR
                // It's tempting to wonder: Have we forgotten the rounded corners overlay?
                // worry not: it's a fake TYPE_NAVIGATION_BAR_PANEL
                || mAttrs.type == TYPE_NAVIGATION_BAR_PANEL) {
@@ -4954,6 +4953,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                || mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
            return mWmService.isMagnifyImeEnabled();
        }
        if (mAttrs.type == TYPE_NAVIGATION_BAR) {
            return mWmService.isMagnifyNavBarEnabled();
        }
        if ((mAttrs.privateFlags & PRIVATE_FLAG_NOT_MAGNIFIABLE) != 0) {
            return false;
        }
+99 −0
Original line number Diff line number Diff line
@@ -107,10 +107,12 @@ import android.util.ArraySet;
import android.util.MergedConfiguration;
import android.view.Gravity;
import android.view.IWindow;
import android.view.InputDevice;
import android.view.InputWindowHandle;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.KeyCharacterMap;
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowInsets;
@@ -130,6 +132,7 @@ import com.android.server.wm.SensitiveContentPackages.PackageInfo;
import com.android.window.flags.Flags;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@@ -150,6 +153,14 @@ import java.util.List;
@RunWith(WindowTestRunner.class)
public class WindowStateTests extends WindowTestsBase {

    @Before
    public void setUp() {
        when(mWm.mInputManager.getInputDevices()).thenReturn(new InputDevice[]{
                new InputDevice.Builder().setSources(InputDevice.SOURCE_TOUCHSCREEN).build()
        });
        mWm.onInputDevicesChanged();
    }

    @After
    public void tearDown() {
        mWm.mSensitiveContentPackages.clearBlockedApps();
@@ -343,14 +354,17 @@ public class WindowStateTests extends WindowTestsBase {
                TYPE_MAGNIFICATION_OVERLAY).build();
        final WindowState navPanelWindow = newWindowBuilder("navPanelWindow",
                TYPE_NAVIGATION_BAR_PANEL).build();
        final WindowState navWindow = newWindowBuilder("navWindow", TYPE_NAVIGATION_BAR).build();

        a11yMagWindow.setHasSurface(true);
        magWindow.setHasSurface(true);
        navPanelWindow.setHasSurface(true);
        navWindow.setHasSurface(true);

        assertFalse(a11yMagWindow.shouldMagnify());
        assertFalse(magWindow.shouldMagnify());
        assertFalse(navPanelWindow.shouldMagnify());
        assertFalse(navWindow.shouldMagnify());
    }

    @Test
@@ -424,6 +438,91 @@ public class WindowStateTests extends WindowTestsBase {
        assertFalse(navWindow.shouldMagnify());
    }

    @Test
    @EnableFlags(com.android.server.accessibility
            .Flags.FLAG_ENABLE_MAGNIFICATION_MAGNIFY_NAV_BAR_AND_IME)
    public void testMagnifyNavBar_WhenImeIsMagnified_shouldNotMagnify() {
        final ContentResolver cr = useFakeSettingsProvider();
        Settings.Secure.putInt(cr,
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME, 1);
        mWm.mSettingsObserver.onChange(true /* selfChange */,
                Settings.Secure.getUriFor(
                        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME));

        final WindowState navWindow = newWindowBuilder("navWindow", TYPE_NAVIGATION_BAR).build();
        navWindow.setHasSurface(true);

        // Here are examples of devices that should not trigger magnifying nav bar:
        when(mWm.mInputManager.getInputDevices()).thenReturn(new InputDevice[]{
                new InputDevice.Builder().setSources(InputDevice.SOURCE_TOUCHSCREEN).build(),
                new InputDevice.Builder().setSources(InputDevice.SOURCE_GAMEPAD).build(),
                new InputDevice.Builder().setSources(InputDevice.SOURCE_ROTARY_ENCODER).build(),
                // A disabled device.
                new InputDevice.Builder().setSources(InputDevice.SOURCE_MOUSE)
                        .setEnabled(false).build(),
                // A non-full alphabetic keyboard.
                new InputDevice.Builder().setSources(InputDevice.SOURCE_KEYBOARD)
                        .setKeyboardType(InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC).build(),
                // A virtual keyboard.
                new InputDevice.Builder().setSources(InputDevice.SOURCE_KEYBOARD)
                        .setId(KeyCharacterMap.VIRTUAL_KEYBOARD).build(),
        });
        mWm.onInputDevicesChanged();

        assertTrue(mWm.isMagnifyImeEnabled());
        assertFalse(mWm.isMagnifyNavBarEnabled());
        assertFalse(navWindow.shouldMagnify());
    }

    @Test
    @EnableFlags(com.android.server.accessibility
            .Flags.FLAG_ENABLE_MAGNIFICATION_MAGNIFY_NAV_BAR_AND_IME)
    public void testMagnifyNavBar_WhenImeIsMagnified_withMouse_shouldMagnify() {
        final ContentResolver cr = useFakeSettingsProvider();
        Settings.Secure.putInt(cr,
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME, 1);
        mWm.mSettingsObserver.onChange(true /* selfChange */,
                Settings.Secure.getUriFor(
                        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME));

        final WindowState navWindow = newWindowBuilder("navWindow", TYPE_NAVIGATION_BAR).build();
        navWindow.setHasSurface(true);

        when(mWm.mInputManager.getInputDevices()).thenReturn(new InputDevice[]{
                new InputDevice.Builder().setSources(InputDevice.SOURCE_MOUSE).build()
        });
        mWm.onInputDevicesChanged();

        assertTrue(mWm.isMagnifyImeEnabled());
        assertTrue(mWm.isMagnifyNavBarEnabled());
        assertTrue(navWindow.shouldMagnify());
    }

    @Test
    @EnableFlags(com.android.server.accessibility
            .Flags.FLAG_ENABLE_MAGNIFICATION_MAGNIFY_NAV_BAR_AND_IME)
    public void testMagnifyNavBar_WhenImeIsMagnified_withKeyboard_shouldMagnify() {
        final ContentResolver cr = useFakeSettingsProvider();
        Settings.Secure.putInt(cr,
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME, 1);
        mWm.mSettingsObserver.onChange(true /* selfChange */,
                Settings.Secure.getUriFor(
                        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MAGNIFY_NAV_AND_IME));

        final WindowState navWindow = newWindowBuilder("navWindow", TYPE_NAVIGATION_BAR).build();
        navWindow.setHasSurface(true);

        when(mWm.mInputManager.getInputDevices()).thenReturn(new InputDevice[]{
                new InputDevice.Builder().setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType(
                        InputDevice.KEYBOARD_TYPE_ALPHABETIC).build()
        });
        mWm.onInputDevicesChanged();

        assertTrue(mWm.isMagnifyImeEnabled());
        assertTrue(mWm.isMagnifyNavBarEnabled());
        assertTrue(navWindow.shouldMagnify());
    }

    @Test
    public void testCanBeImeLayeringTarget() {
        final WindowState appWindow = newWindowBuilder("appWindow", TYPE_APPLICATION).build();