diff --git a/core/java/com/android/internal/accessibility/common/MagnificationConstants.java b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java new file mode 100644 index 0000000000000..94c230bc94fbb --- /dev/null +++ b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.accessibility.common; + +/** + * Collection of common constants for accessibility shortcut. + */ +public final class MagnificationConstants { + private MagnificationConstants() {} + + /** + * The min value for the magnification persisted scale. We assume if the scale is lower than + * the min value, there will be no obvious magnification effect. + */ + public static final float PERSISTED_SCALE_MIN_VALUE = 1.3f; +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java index 4c1a9fa95e76d..b342a29640aa9 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java @@ -50,6 +50,7 @@ import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.Switch; +import com.android.internal.accessibility.common.MagnificationConstants; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.R; @@ -139,8 +140,10 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float scale = progress * A11Y_CHANGE_SCALE_DIFFERENCE + A11Y_SCALE_MIN_VALUE; - // update persisted scale only when scale >= 2.0 - if (scale >= 2.0f) { + // Update persisted scale only when scale >= PERSISTED_SCALE_MIN_VALUE const. + // We assume if the scale is lower than the PERSISTED_SCALE_MIN_VALUE, there will be + // no obvious magnification effect. + if (scale >= MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) { Settings.Secure.putFloatForUser(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale, UserHandle.USER_CURRENT); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java index 37069dc4693fc..595cdec23b600 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -52,6 +52,7 @@ import android.view.accessibility.MagnificationAnimationCallback; import android.view.animation.DecelerateInterpolator; import com.android.internal.R; +import com.android.internal.accessibility.common.MagnificationConstants; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.pooled.PooledLambda; @@ -1157,11 +1158,14 @@ public class FullScreenMagnificationController implements } /** - * Persists the default display magnification scale to the current user's settings. + * Persists the default display magnification scale to the current user's settings + * if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}. + * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there + * will be no obvious magnification effect. */ public void persistScale(int displayId) { final float scale = getScale(Display.DEFAULT_DISPLAY); - if (scale < 2.0f) { + if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) { return; } mScaleProvider.putScale(scale, displayId); @@ -1176,7 +1180,8 @@ public class FullScreenMagnificationController implements */ public float getPersistedScale(int displayId) { return MathUtils.constrain(mScaleProvider.getScale(displayId), - 2.0f, MagnificationScaleProvider.MAX_SCALE); + MagnificationConstants.PERSISTED_SCALE_MIN_VALUE, + MagnificationScaleProvider.MAX_SCALE); } /** diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java index 6bf37a10ba93e..9fc9d57159bbd 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -992,9 +992,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mFullScreenMagnificationController.getPersistedScale(mDisplayId), MIN_SCALE, MAX_SCALE); - final float scale = MathUtils.constrain(Math.max(currentScale + 1.0f, persistedScale), - MIN_SCALE, MAX_SCALE); - + final boolean isActivated = mFullScreenMagnificationController.isActivated(mDisplayId); + final float scale = isActivated ? (currentScale + 1.0f) : persistedScale; zoomToScale(scale, centerX, centerY); } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java index 2d5f8949098c5..d9391f422dc77 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java @@ -46,6 +46,7 @@ import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; import android.view.accessibility.MagnificationAnimationCallback; +import com.android.internal.accessibility.common.MagnificationConstants; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -716,17 +717,20 @@ public class WindowMagnificationManager implements */ float getPersistedScale(int displayId) { return MathUtils.constrain(mScaleProvider.getScale(displayId), - 2.0f, MagnificationScaleProvider.MAX_SCALE); + MagnificationConstants.PERSISTED_SCALE_MIN_VALUE, + MagnificationScaleProvider.MAX_SCALE); } /** * Persists the default display magnification scale to the current user's settings - * if scale is >= 2.0. Only the - * value of the default display is persisted in user's settings. + * if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}. + * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there + * will be no obvious magnification effect. + * Only the value of the default display is persisted in user's settings. */ void persistScale(int displayId) { float scale = getScale(displayId); - if (scale < 2.0f) { + if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) { return; } mScaleProvider.putScale(scale, displayId); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java index d996e37a2eb0b..bf23d9dcbe96e 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java @@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback; +import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -48,6 +49,9 @@ import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManagerInternal; import android.os.Looper; +import android.os.UserHandle; +import android.provider.Settings; +import android.test.mock.MockContentResolver; import android.view.DisplayInfo; import android.view.MagnificationSpec; import android.view.accessibility.MagnificationAnimationCallback; @@ -55,6 +59,7 @@ import android.view.accessibility.MagnificationAnimationCallback; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityTraceManager; import com.android.server.accessibility.test.MessageCapturingHandler; @@ -71,6 +76,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import org.testng.Assert; import java.util.Locale; @@ -93,6 +99,7 @@ public class FullScreenMagnificationControllerTest { static final int DISPLAY_1 = 1; static final int DISPLAY_COUNT = 2; static final int INVALID_DISPLAY = 2; + private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM; final FullScreenMagnificationController.ControllerContext mMockControllerCtx = mock(FullScreenMagnificationController.ControllerContext.class); @@ -105,8 +112,8 @@ public class FullScreenMagnificationControllerTest { MagnificationInfoChangedCallback.class); private final MessageCapturingHandler mMessageCapturingHandler = new MessageCapturingHandler( null); - private final MagnificationScaleProvider mScaleProvider = mock( - MagnificationScaleProvider.class); + private MagnificationScaleProvider mScaleProvider; + private MockContentResolver mResolver; private final ArgumentCaptor mConfigCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); @@ -129,6 +136,12 @@ public class FullScreenMagnificationControllerTest { when(mMockControllerCtx.getWindowManager()).thenReturn(mMockWindowManager); when(mMockControllerCtx.getHandler()).thenReturn(mMessageCapturingHandler); when(mMockControllerCtx.getAnimationDuration()).thenReturn(1000L); + mResolver = new MockContentResolver(); + mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + when(mMockContext.getContentResolver()).thenReturn(mResolver); + Settings.Secure.putFloatForUser(mResolver, + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.0f, + CURRENT_USER_ID); initMockWindowManager(); final DisplayInfo displayInfo = new DisplayInfo(); @@ -137,6 +150,7 @@ public class FullScreenMagnificationControllerTest { LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock); + mScaleProvider = new MagnificationScaleProvider(mMockContext); mFullScreenMagnificationController = new FullScreenMagnificationController( mMockControllerCtx, new Object(), mRequestObserver, mScaleProvider); } @@ -1168,6 +1182,20 @@ public class FullScreenMagnificationControllerTest { verify(mRequestObserver).onImeWindowVisibilityChanged(eq(DISPLAY_0), eq(true)); } + @Test + public void persistScale_setValueWhenScaleIsOne_nothingChanged() { + final float persistedScale = + mFullScreenMagnificationController.getPersistedScale(TEST_DISPLAY); + + PointF pivotPoint = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER; + mFullScreenMagnificationController.setScale(DISPLAY_0, 1.0f, pivotPoint.x, pivotPoint.y, + false, SERVICE_ID_1); + mFullScreenMagnificationController.persistScale(TEST_DISPLAY); + + Assert.assertEquals(mFullScreenMagnificationController.getPersistedScale(TEST_DISPLAY), + persistedScale); + } + private void setScaleToMagnifying() { register(DISPLAY_0); float scale = 2.0f; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java index 25ad2be3772e0..d841dfc2d54b6 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java @@ -273,6 +273,19 @@ public class WindowMagnificationManagerTest { CURRENT_USER_ID), 2.5f); } + @Test + public void persistScale_setValueWhenScaleIsOne_nothingChanged() { + mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + final float persistedScale = mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY); + + mWindowMagnificationManager.setScale(TEST_DISPLAY, 1.0f); + mWindowMagnificationManager.persistScale(TEST_DISPLAY); + + assertEquals(Settings.Secure.getFloatForUser(mResolver, + Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f, + CURRENT_USER_ID), persistedScale); + } + @Test public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() { mWindowMagnificationManager.setConnection(mMockConnection.getConnection());