Loading services/core/java/com/android/server/wm/DisplayContent.java +5 −1 Original line number Diff line number Diff line Loading @@ -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); } } Loading services/core/java/com/android/server/wm/InputManagerCallback.java +3 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,9 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal mInputDevicesReadyMonitor.notifyAll(); } } mService.onInputDevicesChanged(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } Loading services/core/java/com/android/server/wm/WindowManagerService.java +26 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; } Loading Loading @@ -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 { Loading services/core/java/com/android/server/wm/WindowState.java +3 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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; } Loading services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +99 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +5 −1 Original line number Diff line number Diff line Loading @@ -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); } } Loading
services/core/java/com/android/server/wm/InputManagerCallback.java +3 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,9 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal mInputDevicesReadyMonitor.notifyAll(); } } mService.onInputDevicesChanged(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +26 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; } Loading Loading @@ -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 { Loading
services/core/java/com/android/server/wm/WindowState.java +3 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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; } Loading
services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +99 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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(); Loading