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

Commit 5892d5f6 authored by chihtinglo's avatar chihtinglo Committed by Candice
Browse files

fix(magnification): Clear button status when restoring the window size

Store the MagnificationSize index and the width and height of window
magnifier in Preference.
While restoring the window magnifier, we check whether the window
preference is kept before:
Case(1)- No preference for current density: Use the default window size
Case(2)- Found invalid preference data format: Use the default window
size
Case(3)- Found valid preference with index CUSTOM: Restore window width and height
preference for current density
Case(4)- Found valid preference with non-CUSTON index: Restore window
width and height via calculation with MagnificationSize index
After restoring the window size, we send a callback to
WindowMagnificationSettings to update the correcponding button selection.

Bug: 325567876
Bug: 348317974
Test: atest WindowMagnificationFrameSpecTest
      atest WindowMagnificationFrameSizePrefsTest
      atest WindowMagnificationControllerWindowlessMagnifierTest
      atest MagnificationTest
Flag: com.android.systemui.save_and_restore_magnification_settings_buttons
Change-Id: Id0c955602a29152b8078eb1cad848beb6d1bb1ae
parent b0c75b2d
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -362,6 +362,16 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks
        }
    }

    @MainThread
    void updateSettingsButtonStatus(int displayId,
            @WindowMagnificationSettings.MagnificationSize int index) {
        final MagnificationSettingsController magnificationSettingsController =
                mMagnificationSettingsSupplier.get(displayId);
        if (magnificationSettingsController != null) {
            magnificationSettingsController.updateSettingsButtonStatusOnRestore(index);
        }
    }

    @MainThread
    void toggleSettingsPanelVisibility(int displayId) {
        final MagnificationSettingsController magnificationSettingsController =
@@ -445,6 +455,11 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks

    @VisibleForTesting
    final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
        @Override
        public void onWindowMagnifierBoundsRestored(int displayId, int index) {
            mHandler.post(() -> updateSettingsButtonStatus(displayId, index));
        }

        @Override
        public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
            if (mMagnificationConnectionImpl != null) {
+4 −0
Original line number Diff line number Diff line
@@ -100,6 +100,10 @@ public class MagnificationSettingsController implements ComponentCallbacks {
        mWindowMagnificationSettings.toggleSettingsPanelVisibility();
    }

    void updateSettingsButtonStatusOnRestore(@MagnificationSize int index) {
        mWindowMagnificationSettings.updateSelectedButton(index);
    }

    void closeMagnificationSettings() {
        mContext.unregisterComponentCallbacks(this);
        mWindowMagnificationSettings.hideSettingPanel();
+46 −3
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    private final WindowManager mWm;

    private float mScale;
    private int mSettingsButtonIndex = MagnificationSize.DEFAULT;

    /**
     * MagnificationFrame represents the bound of {@link #mMirrorSurfaceView} and is constrained
@@ -436,6 +437,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        if (!mMagnificationSizeScaleOptions.contains(index)) {
            return;
        }
        mSettingsButtonIndex = index;
        int size = getMagnificationWindowSizeFromIndex(index);
        setWindowSize(size, size);
    }
@@ -446,6 +448,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        return (int) (initSize * scale) - (int) (initSize * scale) % 2;
    }

    int getMagnificationFrameSizeFromIndex(@MagnificationSize int index) {
        return getMagnificationWindowSizeFromIndex(index) - 2 * mMirrorSurfaceMargin;
    }

    void setEditMagnifierSizeMode(boolean enable) {
        mEditSizeEnable = enable;
        applyResourcesValues();
@@ -457,8 +463,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold

        if (!enable) {
            // Keep the magnifier size when exiting edit mode
            mWindowMagnificationFrameSizePrefs.saveSizeForCurrentDensity(
            mWindowMagnificationFrameSizePrefs.saveIndexAndSizeForCurrentDensity(
                    mSettingsButtonIndex,
                    new Size(mMagnificationFrame.width(), mMagnificationFrame.height()));
        } else {
            mSettingsButtonIndex = MagnificationSize.CUSTOM;
        }
    }

@@ -944,7 +953,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    }

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

        // Sets the initial frame area for the mirror and place it to the given center on the
        // display.
@@ -954,15 +964,48 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    }

    private Size restoreMagnificationWindowFrameSizeIfPossible() {
        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
            return restoreMagnificationWindowFrameIndexAndSizeIfPossible();
        }

        if (!mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity()) {
            return getDefaultMagnificationWindowFrameSize();
        }

        return mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity();
    }

    private Size restoreMagnificationWindowFrameIndexAndSizeIfPossible() {
        if (!mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity()) {
            notifyWindowSizeRestored(MagnificationSize.DEFAULT);
            return getDefaultMagnificationWindowFrameSize();
        }

        // This will return DEFAULT index if the stored preference is in an invalid format.
        // Therefore, except CUSTOM, we would like to calculate the window width and height based
        // on the restored MagnificationSize index.
        int restoredIndex = mWindowMagnificationFrameSizePrefs.getIndexForCurrentDensity();
        notifyWindowSizeRestored(restoredIndex);
        if (restoredIndex == MagnificationSize.CUSTOM) {
            return mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity();
        }

        int restoredSize = getMagnificationFrameSizeFromIndex(restoredIndex);
        return new Size(restoredSize, restoredSize);
    }

    private void notifyWindowSizeRestored(@MagnificationSize int index) {
        mSettingsButtonIndex = index;
        if (isActivated()) {
            // Send the callback only if the window magnification is activated. The check is to
            // avoid updating the settings panel in the cases that window magnification is not yet
            // activated such as during the constructor initialization of this class.
            mWindowMagnifierCallback.onWindowMagnifierBoundsRestored(mDisplayId, index);
        }
    }

    private Size getDefaultMagnificationWindowFrameSize() {
        final int defaultSize = getMagnificationWindowSizeFromIndex(MagnificationSize.MEDIUM)
        final int defaultSize = getMagnificationWindowSizeFromIndex(MagnificationSize.DEFAULT)
                - 2 * mMirrorSurfaceMargin;
        return new Size(defaultSize, defaultSize);
    }
+36 −4
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.systemui.accessibility;

import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;

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

import com.android.systemui.Flags;

/**
 * Class to handle SharedPreference for window magnification size.
 */
@@ -47,10 +51,16 @@ final class WindowMagnificationFrameSizePrefs {
    /**
     * Saves the window frame size for current screen density.
     */
    public void saveSizeForCurrentDensity(Size size) {
    public void saveIndexAndSizeForCurrentDensity(int index, Size size) {
        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
            mWindowMagnificationSizePreferences.edit()
                    .putString(getKey(),
                            WindowMagnificationFrameSpec.serialize(index, size)).apply();
        } else {
            mWindowMagnificationSizePreferences.edit()
                    .putString(getKey(), size.toString()).apply();
        }
    }

    /**
     * Check if there is a preference saved for current screen density.
@@ -61,11 +71,33 @@ final class WindowMagnificationFrameSizePrefs {
        return mWindowMagnificationSizePreferences.contains(getKey());
    }

    /**
     * Gets the index preference for current screen density. Returns DEFAULT if no preference
     * is found.
     */
    public @MagnificationSize int getIndexForCurrentDensity() {
        final String spec = mWindowMagnificationSizePreferences.getString(getKey(), null);
        if (spec == null) {
            return MagnificationSize.DEFAULT;
        }
        try {
            return WindowMagnificationFrameSpec.deserialize(spec).getIndex();
        } catch (NumberFormatException e) {
            return MagnificationSize.DEFAULT;
        }
    }

    /**
     * Gets the size preference for current screen density.
     */
    public Size getSizeForCurrentDensity() {
        if (Flags.saveAndRestoreMagnificationSettingsButtons()) {
            return WindowMagnificationFrameSpec
                    .deserialize(mWindowMagnificationSizePreferences.getString(getKey(), null))
                    .getSize();
        } else {
            return Size.parseSize(mWindowMagnificationSizePreferences.getString(getKey(), null));
        }
    }

}
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.util.Size

data class WindowMagnificationFrameSpec(val index: Int, val size: Size) {

    companion object {
        private fun throwInvalidWindowMagnificationFrameSpec(s: String?): Nothing {
            throw NumberFormatException("Invalid WindowMagnificationFrameSpec: \"$s\"")
        }

        @JvmStatic fun serialize(index: Int, size: Size) = "$index,$size"

        @JvmStatic
        fun deserialize(s: String): WindowMagnificationFrameSpec {
            val separatorIndex = s.indexOf(',')
            if (separatorIndex < 0) {
                throwInvalidWindowMagnificationFrameSpec(s)
            }
            return try {
                WindowMagnificationFrameSpec(
                    s.substring(0, separatorIndex).toInt(),
                    Size.parseSize(s.substring(separatorIndex + 1))
                )
            } catch (e: NumberFormatException) {
                throwInvalidWindowMagnificationFrameSpec(s)
            }
        }
    }
}
Loading