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

Commit b4a82ddb authored by Candice Lo's avatar Candice Lo
Browse files

Keeping the magnifier window size in SharedPreference

Using the smallest width dp as the key to save magnifier window's width and height. If no corresponding saved window size is found, use the Medium size provided by the settings panel button to be the default magnifier size.

Bug: 265363901
Bug: 283019152
Test: atest WindowMagnificationControllerTest
Test: atest WindowMagnificationSizePrefsTest
Test: manually - test window size is restored after the device restarts
Change-Id: Id35c2ff394c9a4907240833f3d43b0d412ef6caf
parent 3c795033
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -225,6 +225,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    private boolean mAllowDiagonalScrolling = false;
    private boolean mEditSizeEnable = false;
    private boolean mSettingsPanelVisibility = false;
    @VisibleForTesting
    WindowMagnificationSizePrefs mWindowMagnificationSizePrefs;

    @Nullable
    private final MirrorWindowControl mMirrorWindowControl;
@@ -249,6 +251,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        mWindowMagnifierCallback = callback;
        mSysUiState = sysUiState;
        mConfiguration = new Configuration(context.getResources().getConfiguration());
        mWindowMagnificationSizePrefs = new WindowMagnificationSizePrefs(mContext);

        final Display display = mContext.getDisplay();
        mDisplayId = mContext.getDisplayId();
@@ -272,7 +275,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
                com.android.internal.R.integer.config_shortAnimTime);
        updateDimensions();

        final Size windowFrameSize = getDefaultMagnificationWindowFrameSize();
        final Size windowFrameSize = restoreMagnificationWindowFrameSizeIfPossible();
        setMagnificationFrame(windowFrameSize.getWidth(), windowFrameSize.getHeight(),
                mWindowBounds.width() / 2, mWindowBounds.height() / 2);
        computeBounceAnimationScale();
@@ -399,6 +402,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
            updateDimensions();
            applyTapExcludeRegion();
        }

        if (!enable) {
            // Keep the magnifier size when exiting edit mode
            mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(
                    new Size(mMagnificationFrame.width(), mMagnificationFrame.height()));
        }
    }

    void setDiagonalScrolling(boolean enable) {
@@ -523,7 +532,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
            return false;
        }
        mWindowBounds.set(currentWindowBounds);
        final Size windowFrameSize = getDefaultMagnificationWindowFrameSize();
        final Size windowFrameSize = restoreMagnificationWindowFrameSizeIfPossible();
        final float newCenterX = (getCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
        final float newCenterY = (getCenterY()) * mWindowBounds.height() / oldWindowBounds.height();

@@ -742,6 +751,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    }

    private void setMagnificationFrame(int width, int height, int centerX, int centerY) {
        mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(new Size(width, height));

        // Sets the initial frame area for the mirror and place it to the given center on the
        // display.
        final int initX = centerX - width / 2;
@@ -749,6 +760,14 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        mMagnificationFrame.set(initX, initY, initX + width, initY + height);
    }

    private Size restoreMagnificationWindowFrameSizeIfPossible() {
        if (!mWindowMagnificationSizePrefs.isPreferenceSavedForCurrentDensity()) {
            return getDefaultMagnificationWindowFrameSize();
        }

        return mWindowMagnificationSizePrefs.getSizeForCurrentDensity();
    }

    private Size getDefaultMagnificationWindowFrameSize() {
        final int defaultSize = getMagnificationWindowSizeFromIndex(MagnificationSize.MEDIUM)
                - 2 * mMirrorSurfaceMargin;
+71 −0
Original line number Diff line number Diff line
/*
 * 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.systemui.accessibility;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Size;

/**
 * Class to handle SharedPreference for window magnification size.
 */
public final class WindowMagnificationSizePrefs {

    private static final String WINDOW_MAGNIFICATION_PREFERENCES =
            "window_magnification_preferences";
    Context mContext;
    SharedPreferences mWindowMagnificationSizePreferences;

    public WindowMagnificationSizePrefs(Context context) {
        mContext = context;
        mWindowMagnificationSizePreferences = mContext
                .getSharedPreferences(WINDOW_MAGNIFICATION_PREFERENCES, Context.MODE_PRIVATE);
    }

    /**
     * Uses smallest screen width DP as the key for preference.
     */
    private String getKey() {
        return String.valueOf(
                mContext.getResources().getConfiguration().smallestScreenWidthDp);
    }

    /**
     * Saves the window frame size for current screen density.
     */
    public void saveSizeForCurrentDensity(Size size) {
        mWindowMagnificationSizePreferences.edit()
                .putString(getKey(), size.toString()).apply();
    }

    /**
     * Check if there is a preference saved for current screen density.
     *
     * @return true if there is a preference saved for current screen density, false if it is unset.
     */
    public boolean isPreferenceSavedForCurrentDensity() {
        return mWindowMagnificationSizePreferences.contains(getKey());
    }

    /**
     * Gets the size preference for current screen density.
     */
    public Size getSizeForCurrentDensity() {
        return Size.parseSize(mWindowMagnificationSizePreferences.getString(getKey(), null));
    }

}
+38 −5
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.text.TextUtils;
import android.util.Size;
import android.view.Display;
import android.view.IWindowSession;
import android.view.MotionEvent;
@@ -544,17 +545,22 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
    }

    @Test
    public void onScreenSizeChanged_enabledAtTheCenterOfScreen_keepSameWindowSizeRatio() {
    public void onScreenSizeAndDensityChanged_enabledAtTheCenterOfScreen_keepSameWindowSizeRatio() {
        // The default position is at the center of the screen.
        final float expectedRatio = 0.5f;
        final Rect testWindowBounds = new Rect(
                mWindowManager.getCurrentWindowMetrics().getBounds());
        testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
                testWindowBounds.right + 100, testWindowBounds.bottom + 100);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
        });

        // Screen size and density change
        mContext.getResources().getConfiguration().smallestScreenWidthDp =
                mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
        final Rect testWindowBounds = new Rect(
                mWindowManager.getCurrentWindowMetrics().getBounds());
        testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
                testWindowBounds.right + 100, testWindowBounds.bottom + 100);
        mWindowManager.setWindowBounds(testWindowBounds);

        mInstrumentation.runOnMainSync(() -> {
@@ -570,6 +576,25 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
                0);
    }

    @Test
    public void onScreenChangedToSavedDensity_enabled_restoreSavedMagnifierWindow() {
        mContext.getResources().getConfiguration().smallestScreenWidthDp =
                mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
        int windowFrameSize = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
        mWindowMagnificationController.mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(
                new Size(windowFrameSize, windowFrameSize));

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
        });

        WindowManager.LayoutParams params = mWindowManager.getLayoutParamsFromAttachedView();
        assertTrue(params.width == windowFrameSize);
        assertTrue(params.height == windowFrameSize);
    }

    @Test
    public void screenSizeIsChangedToLarge_enabled_defaultWindowSize() {
        mInstrumentation.runOnMainSync(() -> {
@@ -577,6 +602,9 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
                    Float.NaN);
        });
        final int screenSize = mWindowManager.getCurrentWindowMetrics().getBounds().width() * 10;
        // Screen size and density change
        mContext.getResources().getConfiguration().smallestScreenWidthDp =
                mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
        mWindowManager.setWindowBounds(new Rect(0, 0, screenSize, screenSize));

        mInstrumentation.runOnMainSync(() -> {
@@ -1138,6 +1166,11 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        mWindowManager.setWindowInsets(testInsets);
    }

    private int updateMirrorSurfaceMarginDimension() {
        return mContext.getResources().getDimensionPixelSize(
                R.dimen.magnification_mirror_surface_margin);
    }

    @Surface.Rotation
    private int simulateRotateTheDevice() {
        final Display display = Mockito.spy(mContext.getDisplay());
+56 −0
Original line number Diff line number Diff line
/*
 * 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.systemui.accessibility;

import static com.google.common.truth.Truth.assertThat;

import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Size;

import com.android.systemui.SysuiTestCase;

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

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class WindowMagnificationSizePrefsTest extends SysuiTestCase {

    WindowMagnificationSizePrefs mWindowMagnificationSizePrefs =
            new WindowMagnificationSizePrefs(mContext);

    @Test
    public void saveSizeForCurrentDensity_getExpectedSize() {
        Size testSize = new Size(500, 500);
        mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(testSize);

        assertThat(mWindowMagnificationSizePrefs.getSizeForCurrentDensity())
                .isEqualTo(testSize);
    }

    @Test
    public void saveSizeForCurrentDensity_containsPreferenceForCurrentDensity() {
        Size testSize = new Size(500, 500);
        mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(testSize);

        assertThat(mWindowMagnificationSizePrefs.isPreferenceSavedForCurrentDensity())
                .isTrue();
    }
}