diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 776405d23035e..7e4567b91d2e0 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -2725,6 +2725,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState); somethingChanged |= readMagnificationCapabilitiesLocked(userState); somethingChanged |= readMagnificationFollowTypingLocked(userState); + somethingChanged |= readAlwaysOnMagnificationLocked(userState); somethingChanged |= readUiContrastLocked(userState); return somethingChanged; } @@ -4378,6 +4379,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private final Uri mMagnificationFollowTypingUri = Settings.Secure.getUriFor( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED); + // TODO: replace name with Settings Secure Key + private final Uri mAlwaysOnMagnificationUri = Settings.Secure.getUriFor( + "accessibility_magnification_always_on_enabled"); + private final Uri mUiContrastUri = Settings.Secure.getUriFor( CONTRAST_LEVEL); @@ -4421,6 +4426,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMagnificationCapabilityUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver( mMagnificationFollowTypingUri, false, this, UserHandle.USER_ALL); + contentResolver.registerContentObserver( + mAlwaysOnMagnificationUri, false, this, UserHandle.USER_ALL); contentResolver.registerContentObserver( mUiContrastUri, false, this, UserHandle.USER_ALL); } @@ -4492,6 +4499,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } else if (mMagnificationFollowTypingUri.equals(uri)) { readMagnificationFollowTypingLocked(userState); + } else if (mAlwaysOnMagnificationUri.equals(uri)) { + readAlwaysOnMagnificationLocked(userState); } else if (mUiContrastUri.equals(uri)) { if (readUiContrastLocked(userState)) { updateUiContrastLocked(userState); @@ -4605,6 +4614,23 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return false; } + boolean readAlwaysOnMagnificationLocked(AccessibilityUserState userState) { + // TODO: replace name const with Settings Secure Key + final boolean isSettingsAlwaysOnEnabled = Settings.Secure.getIntForUser( + mContext.getContentResolver(), + "accessibility_magnification_always_on_enabled", + 0, userState.mUserId) == 1; + final boolean isAlwaysOnFeatureFlagEnabled = mMagnificationController + .isAlwaysOnMagnificationFeatureFlagEnabled(); + final boolean isAlwaysOnEnabled = isAlwaysOnFeatureFlagEnabled && isSettingsAlwaysOnEnabled; + if (isAlwaysOnEnabled != userState.isAlwaysOnMagnificationEnabled()) { + userState.setAlwaysOnMagnificationEnabled(isAlwaysOnEnabled); + mMagnificationController.setAlwaysOnMagnificationEnabled(isAlwaysOnEnabled); + return true; + } + return false; + } + @Override public void setGestureDetectionPassthroughRegion(int displayId, Region region) { mMainHandler.sendMessage( diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java index 43730fce0cb7a..1c9ce3c827356 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java @@ -136,6 +136,8 @@ class AccessibilityUserState { private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; // Whether the following typing focus feature for magnification is enabled. private boolean mMagnificationFollowTypingEnabled = true; + // Whether the always on magnification feature is enabled. + private boolean mAlwaysOnMagnificationEnabled = false; /** The stroke width of the focus rectangle in pixels */ private int mFocusStrokeWidth; @@ -221,6 +223,7 @@ class AccessibilityUserState { mFocusStrokeWidth = mFocusStrokeWidthDefaultValue; mFocusColor = mFocusColorDefaultValue; mMagnificationFollowTypingEnabled = true; + mAlwaysOnMagnificationEnabled = false; mUiContrast = CONTRAST_NOT_SET; } @@ -531,6 +534,8 @@ class AccessibilityUserState { .append(String.valueOf(mIsAudioDescriptionByDefaultRequested)); pw.append(", magnificationFollowTypingEnabled=") .append(String.valueOf(mMagnificationFollowTypingEnabled)); + pw.append(", alwaysOnMagnificationEnabled=") + .append(String.valueOf(mAlwaysOnMagnificationEnabled)); pw.append("}"); pw.println(); pw.append(" shortcut key:{"); @@ -711,6 +716,14 @@ class AccessibilityUserState { return mMagnificationFollowTypingEnabled; } + public void setAlwaysOnMagnificationEnabled(boolean enabled) { + mAlwaysOnMagnificationEnabled = enabled; + } + + public boolean isAlwaysOnMagnificationEnabled() { + return mAlwaysOnMagnificationEnabled; + } + /** * Sets the magnification mode to the given display. * diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 558c71b11c864..a6e6bd7d7b664 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -677,6 +677,19 @@ public class MagnificationController implements WindowMagnificationManager.Callb getFullScreenMagnificationController().setMagnificationFollowTypingEnabled(enabled); } + /** + * Called when the always on magnification feature is switched. + * + * @param enabled Enable the always on magnification feature + */ + public void setAlwaysOnMagnificationEnabled(boolean enabled) { + getFullScreenMagnificationController().setAlwaysOnMagnificationEnabled(enabled); + } + + public boolean isAlwaysOnMagnificationFeatureFlagEnabled() { + return AlwaysOnMagnificationFeatureFlag.isAlwaysOnMagnificationEnabled(); + } + private DisableMagnificationCallback getDisableMagnificationEndRunnableLocked( int displayId) { return mMagnificationEndRunnableSparseArray.get(displayId); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index 4d1d2b22ed345..32b98647e78b4 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -34,6 +34,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; @@ -438,6 +439,42 @@ public class AccessibilityManagerServiceTest { verify(mMockMagnificationController).setMagnificationFollowTypingEnabled(false); } + @Test + public void testSettingsAlwaysOn_setEnabled_featureFlagDisabled_doNothing() { + when(mMockMagnificationController.isAlwaysOnMagnificationFeatureFlagEnabled()) + .thenReturn(false); + + final AccessibilityUserState userState = mA11yms.mUserStates.get( + mA11yms.getCurrentUserIdLocked()); + Settings.Secure.putIntForUser( + mTestableContext.getContentResolver(), + // TODO: replace name with Settings Secure Key + "accessibility_magnification_always_on_enabled", + 1, mA11yms.getCurrentUserIdLocked()); + + mA11yms.readAlwaysOnMagnificationLocked(userState); + + verify(mMockMagnificationController, never()).setAlwaysOnMagnificationEnabled(anyBoolean()); + } + + @Test + public void testSettingsAlwaysOn_setEnabled_featureFlagEnabled_propagateToController() { + when(mMockMagnificationController.isAlwaysOnMagnificationFeatureFlagEnabled()) + .thenReturn(true); + + final AccessibilityUserState userState = mA11yms.mUserStates.get( + mA11yms.getCurrentUserIdLocked()); + Settings.Secure.putIntForUser( + mTestableContext.getContentResolver(), + // TODO: replace name with Settings Secure Key + "accessibility_magnification_always_on_enabled", + 1, mA11yms.getCurrentUserIdLocked()); + + mA11yms.readAlwaysOnMagnificationLocked(userState); + + verify(mMockMagnificationController).setAlwaysOnMagnificationEnabled(eq(true)); + } + @SmallTest @Test public void testOnClientChange_magnificationEnabledAndCapabilityAll_requestConnection() { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java index ed0336a5a4ea7..b4558b211fc68 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java @@ -179,6 +179,7 @@ public class AccessibilityUserStateTest { assertEquals(mFocusStrokeWidthDefaultValue, mUserState.getFocusStrokeWidthLocked()); assertEquals(mFocusColorDefaultValue, mUserState.getFocusColorLocked()); assertTrue(mUserState.isMagnificationFollowTypingEnabled()); + assertFalse(mUserState.isAlwaysOnMagnificationEnabled()); } @Test @@ -389,6 +390,15 @@ public class AccessibilityUserStateTest { assertFalse(mUserState.isMagnificationFollowTypingEnabled()); } + @Test + public void setAlwaysOnMagnificationEnabled_defaultFalseAndSetTrue_returnTrue() { + assertFalse(mUserState.isAlwaysOnMagnificationEnabled()); + + mUserState.setAlwaysOnMagnificationEnabled(true); + + assertTrue(mUserState.isAlwaysOnMagnificationEnabled()); + } + @Test public void setFocusAppearanceData_returnExpectedFocusAppearanceData() { final int focusStrokeWidthValue = 100; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index 407c575fd6d03..b4a16c2da517f 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -738,6 +738,13 @@ public class MagnificationControllerTest { verify(mScreenMagnificationController).setMagnificationFollowTypingEnabled(eq(false)); } + @Test + public void setPreferenceAlwaysOnMagnificationEnabled_setPrefEnabled_enableOnFullScreen() { + mMagnificationController.setAlwaysOnMagnificationEnabled(true); + + verify(mScreenMagnificationController).setAlwaysOnMagnificationEnabled(eq(true)); + } + @Test public void onRectangleOnScreenRequested_fullScreenIsActivated_fullScreenDispatchEvent() { mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,