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

Commit 1e2052ff authored by Candice Lo's avatar Candice Lo
Browse files

Provides actions for editing window magnifier

Providing increasing and decreasing window magnifier size horizontally and vertically actions in window magnification to adjust the window in edit mode in Accessibility Service.
The Talkback actions will only show when they are available.

Bug: 274735988
Test: manually - attach video to the bug
Test: atest WindowMagnificationControllerTest
Change-Id: Ic04e61ae1334b910152aee1fb9056d50e4b832ba
parent 558f38ac
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1230,6 +1230,7 @@
    <dimen name="magnification_setting_image_button_open_in_full_padding_horizontal">28dp</dimen>
    <dimen name="magnification_setting_drag_corner_radius">28dp</dimen>
    <dimen name="magnification_setting_drag_size">56dp</dimen>
    <fraction name="magnification_resize_window_size_amount">10%</fraction>

    <!-- Seekbar with icon buttons -->
    <dimen name="seekbar_icon_size">24dp</dimen>
+4 −0
Original line number Diff line number Diff line
@@ -172,6 +172,10 @@
    <item type="id" name="accessibility_action_move_right"/>
    <item type="id" name="accessibility_action_move_up"/>
    <item type="id" name="accessibility_action_move_down"/>
    <item type="id" name="accessibility_action_increase_window_width"/>
    <item type="id" name="accessibility_action_decrease_window_width"/>
    <item type="id" name="accessibility_action_increase_window_height"/>
    <item type="id" name="accessibility_action_decrease_window_height"/>

    <!-- Accessibility actions for Accessibility floating menu. -->
    <item type="id" name="action_move_top_left"/>
+10 −0
Original line number Diff line number Diff line
@@ -2396,6 +2396,16 @@
    <string name="accessibility_control_move_left">Move left</string>
    <!-- Action in accessibility menu to move the magnification window right. [CHAR LIMIT=30] -->
    <string name="accessibility_control_move_right">Move right</string>

    <!-- Action in accessibility menu to increase the magnification window width. [CHAR LIMIT=NONE] -->
    <string name="accessibility_control_increase_window_width">Increase width of magnifier</string>
    <!-- Action in accessibility menu to decrease the magnification window width. [CHAR LIMIT=NONE] -->
    <string name="accessibility_control_decrease_window_width">Decrease width of magnifier</string>
    <!-- Action in accessibility menu to increase the magnification window height. [CHAR LIMIT=NONE] -->
    <string name="accessibility_control_increase_window_height">Increase height of magnifier</string>
    <!-- Action in accessibility menu to decrease the magnification window height. [CHAR LIMIT=NONE] -->
    <string name="accessibility_control_decrease_window_height">Decrease height of magnifier</string>

    <!-- Content description for magnification mode switch. [CHAR LIMIT=NONE] -->
    <string name="magnification_mode_switch_description">Magnification switch</string>
    <!-- A11y state description for magnification mode switch that device is in full-screen mode. [CHAR LIMIT=NONE] -->
+75 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static java.lang.Math.abs;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
@@ -702,6 +703,18 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        }
    }

    /**
     * Sets the window frame size with given width and height in pixels without changing the
     * window center.
     *
     * @param width the window frame width in pixels
     * @param height the window frame height in pixels.
     */
    @MainThread
    private void setMagnificationFrameSize(int width, int height) {
        setWindowSize(width + 2 * mMirrorSurfaceMargin, height + 2 * mMirrorSurfaceMargin);
    }

    /**
     * Sets the window size with given width and height in pixels without changing the
     * window center. The width or the height will be clamped in the range
@@ -1466,11 +1479,14 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
                    AccessibilityAction.ACTION_CLICK.getId(), getClickAccessibilityActionLabel());
            info.addAction(clickAction);
            info.setClickable(true);

            info.addAction(
                    new AccessibilityAction(R.id.accessibility_action_zoom_in,
                            mContext.getString(R.string.accessibility_control_zoom_in)));
            info.addAction(new AccessibilityAction(R.id.accessibility_action_zoom_out,
                    mContext.getString(R.string.accessibility_control_zoom_out)));

            if (!mEditSizeEnable) {
                info.addAction(new AccessibilityAction(R.id.accessibility_action_move_up,
                        mContext.getString(R.string.accessibility_control_move_up)));
                info.addAction(new AccessibilityAction(R.id.accessibility_action_move_down,
@@ -1479,6 +1495,34 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
                        mContext.getString(R.string.accessibility_control_move_left)));
                info.addAction(new AccessibilityAction(R.id.accessibility_action_move_right,
                        mContext.getString(R.string.accessibility_control_move_right)));
            } else {
                if ((mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin)
                        < mWindowBounds.width()) {
                    info.addAction(new AccessibilityAction(
                            R.id.accessibility_action_increase_window_width,
                            mContext.getString(
                                    R.string.accessibility_control_increase_window_width)));
                }
                if ((mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin)
                        < mWindowBounds.height()) {
                    info.addAction(new AccessibilityAction(
                            R.id.accessibility_action_increase_window_height,
                            mContext.getString(
                                    R.string.accessibility_control_increase_window_height)));
                }
                if ((mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin) > mMinWindowSize) {
                    info.addAction(new AccessibilityAction(
                            R.id.accessibility_action_decrease_window_width,
                            mContext.getString(
                                    R.string.accessibility_control_decrease_window_width)));
                }
                if ((mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin) > mMinWindowSize) {
                    info.addAction(new AccessibilityAction(
                            R.id.accessibility_action_decrease_window_height,
                            mContext.getString(
                                    R.string.accessibility_control_decrease_window_height)));
                }
            }

            info.setContentDescription(mContext.getString(R.string.magnification_window_title));
            info.setStateDescription(formatStateDescription(getScale()));
@@ -1493,6 +1537,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        }

        private boolean performA11yAction(int action) {
            final float changeWindowSizeAmount = mContext.getResources().getFraction(
                    R.fraction.magnification_resize_window_size_amount,
                    /* base= */ 1,
                    /* pbase= */ 1);

            if (action == AccessibilityAction.ACTION_CLICK.getId()) {
                if (mEditSizeEnable) {
                    // When edit mode is enabled, click the magnifier to exit edit mode.
@@ -1514,9 +1563,26 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
                move(-mSourceBounds.width(), 0);
            } else if (action == R.id.accessibility_action_move_right) {
                move(mSourceBounds.width(), 0);
            } else if (action == R.id.accessibility_action_increase_window_width) {
                int newFrameWidth =
                        (int) (mMagnificationFrame.width() * (1 + changeWindowSizeAmount));
                setMagnificationFrameSize(newFrameWidth, mMagnificationFrame.height());
            } else if (action == R.id.accessibility_action_increase_window_height) {
                int newFrameHeight =
                        (int) (mMagnificationFrame.height() * (1 + changeWindowSizeAmount));
                setMagnificationFrameSize(mMagnificationFrame.width(), newFrameHeight);
            } else if (action == R.id.accessibility_action_decrease_window_width) {
                int newFrameWidth =
                        (int) (mMagnificationFrame.width() * (1 - changeWindowSizeAmount));
                setMagnificationFrameSize(newFrameWidth, mMagnificationFrame.height());
            } else if (action == R.id.accessibility_action_decrease_window_height) {
                int newFrameHeight =
                        (int) (mMagnificationFrame.height() * (1 - changeWindowSizeAmount));
                setMagnificationFrameSize(mMagnificationFrame.width(), newFrameHeight);
            } else {
                return false;
            }

            mWindowMagnifierCallback.onAccessibilityActionPerformed(mDisplayId);
            return true;
        }
@@ -1527,4 +1593,5 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
                    mDisplayId, scale, /* updatePersistence= */ true);
        }
    }

}
 No newline at end of file
+240 −0
Original line number Diff line number Diff line
@@ -711,6 +711,245 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        assertEquals(View.GONE, topLeftCorner.getVisibility());
    }

    @Test
    public void windowWidthIsNotMax_performA11yActionIncreaseWidth_windowWidthIncreased() {
        final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        final int startingWidth = (int) (windowBounds.width() * 0.8);
        final int startingHeight = (int) (windowBounds.height() * 0.8);
        final float changeWindowSizeAmount = mContext.getResources().getFraction(
                R.fraction.magnification_resize_window_size_amount,
                /* base= */ 1,
                /* pbase= */ 1);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AtomicInteger actualWindowHeight = new AtomicInteger();
        final AtomicInteger actualWindowWidth = new AtomicInteger();

        mInstrumentation.runOnMainSync(
                () -> {
                    mirrorView.performAccessibilityAction(
                            R.id.accessibility_action_increase_window_width, null);
                    actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
                    actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
                });

        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
                R.dimen.magnification_mirror_surface_margin);
        // Window width includes the magnifier frame and the margin. Increasing the window size
        // will be increasing the amount of the frame size only.
        int newWindowWidth =
                (int) ((startingWidth - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
                        + 2 * mirrorSurfaceMargin;
        assertEquals(newWindowWidth, actualWindowWidth.get());
        assertEquals(startingHeight, actualWindowHeight.get());
    }

    @Test
    public void windowHeightIsNotMax_performA11yActionIncreaseHeight_windowHeightIncreased() {
        final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        final int startingWidth = (int) (windowBounds.width() * 0.8);
        final int startingHeight = (int) (windowBounds.height() * 0.8);
        final float changeWindowSizeAmount = mContext.getResources().getFraction(
                R.fraction.magnification_resize_window_size_amount,
                /* base= */ 1,
                /* pbase= */ 1);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AtomicInteger actualWindowHeight = new AtomicInteger();
        final AtomicInteger actualWindowWidth = new AtomicInteger();

        mInstrumentation.runOnMainSync(
                () -> {
                    mirrorView.performAccessibilityAction(
                            R.id.accessibility_action_increase_window_height, null);
                    actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
                    actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
                });

        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
                R.dimen.magnification_mirror_surface_margin);
        // Window height includes the magnifier frame and the margin. Increasing the window size
        // will be increasing the amount of the frame size only.
        int newWindowHeight =
                (int) ((startingHeight - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
                        + 2 * mirrorSurfaceMargin;
        assertEquals(startingWidth, actualWindowWidth.get());
        assertEquals(newWindowHeight, actualWindowHeight.get());
    }

    @Test
    public void windowWidthIsMax_noIncreaseWindowWidthA11yAction() {
        final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        final int startingWidth = windowBounds.width();
        final int startingHeight = windowBounds.height();

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AccessibilityNodeInfo accessibilityNodeInfo =
                mirrorView.createAccessibilityNodeInfo();
        assertFalse(accessibilityNodeInfo.getActionList().contains(
                new AccessibilityAction(R.id.accessibility_action_increase_window_width, null)));
    }

    @Test
    public void windowHeightIsMax_noIncreaseWindowHeightA11yAction() {
        final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        final int startingWidth = windowBounds.width();
        final int startingHeight = windowBounds.height();

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AccessibilityNodeInfo accessibilityNodeInfo =
                mirrorView.createAccessibilityNodeInfo();
        assertFalse(accessibilityNodeInfo.getActionList().contains(
                new AccessibilityAction(R.id.accessibility_action_increase_window_height, null)));
    }

    @Test
    public void windowWidthIsNotMin_performA11yActionDecreaseWidth_windowWidthDecreased() {
        int mMinWindowSize = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
        final int startingSize = (int) (mMinWindowSize * 1.1);
        final float changeWindowSizeAmount = mContext.getResources().getFraction(
                R.fraction.magnification_resize_window_size_amount,
                /* base= */ 1,
                /* pbase= */ 1);
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingSize, startingSize);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AtomicInteger actualWindowHeight = new AtomicInteger();
        final AtomicInteger actualWindowWidth = new AtomicInteger();

        mInstrumentation.runOnMainSync(
                () -> {
                    mirrorView.performAccessibilityAction(
                            R.id.accessibility_action_decrease_window_width, null);
                    actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
                    actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
                });

        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
                R.dimen.magnification_mirror_surface_margin);
        // Window width includes the magnifier frame and the margin. Decreasing the window size
        // will be decreasing the amount of the frame size only.
        int newWindowWidth =
                (int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
                        + 2 * mirrorSurfaceMargin;
        assertEquals(newWindowWidth, actualWindowWidth.get());
        assertEquals(startingSize, actualWindowHeight.get());
    }

    @Test
    public void windowHeightIsNotMin_performA11yActionDecreaseHeight_windowHeightDecreased() {
        int mMinWindowSize = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
        final int startingSize = (int) (mMinWindowSize * 1.1);
        final float changeWindowSizeAmount = mContext.getResources().getFraction(
                R.fraction.magnification_resize_window_size_amount,
                /* base= */ 1,
                /* pbase= */ 1);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingSize, startingSize);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AtomicInteger actualWindowHeight = new AtomicInteger();
        final AtomicInteger actualWindowWidth = new AtomicInteger();

        mInstrumentation.runOnMainSync(
                () -> {
                    mirrorView.performAccessibilityAction(
                            R.id.accessibility_action_decrease_window_height, null);
                    actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
                    actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
                });

        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
                R.dimen.magnification_mirror_surface_margin);
        // Window height includes the magnifier frame and the margin. Decreasing the window size
        // will be decreasing the amount of the frame size only.
        int newWindowHeight =
                (int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
                        + 2 * mirrorSurfaceMargin;
        assertEquals(startingSize, actualWindowWidth.get());
        assertEquals(newWindowHeight, actualWindowHeight.get());
    }

    @Test
    public void windowWidthIsMin_noDecreaseWindowWidthA11yAction() {
        int mMinWindowSize = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
        final int startingSize = mMinWindowSize;

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingSize, startingSize);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AccessibilityNodeInfo accessibilityNodeInfo =
                mirrorView.createAccessibilityNodeInfo();
        assertFalse(accessibilityNodeInfo.getActionList().contains(
                new AccessibilityAction(R.id.accessibility_action_decrease_window_width, null)));
    }

    @Test
    public void windowHeightIsMin_noDecreaseWindowHeightA11yAcyion() {
        int mMinWindowSize = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
        final int startingSize = mMinWindowSize;

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
            mWindowMagnificationController.setWindowSize(startingSize, startingSize);
            mWindowMagnificationController.setEditMagnifierSizeMode(true);
        });

        final View mirrorView = mWindowManager.getAttachedView();
        final AccessibilityNodeInfo accessibilityNodeInfo =
                mirrorView.createAccessibilityNodeInfo();
        assertFalse(accessibilityNodeInfo.getActionList().contains(
                new AccessibilityAction(R.id.accessibility_action_decrease_window_height, null)));
    }

    @Test
    public void enableWindowMagnification_hasA11yWindowTitle() {
        mInstrumentation.runOnMainSync(() -> {
@@ -1166,4 +1405,5 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        when(mContext.getDisplay()).thenReturn(display);
        return newRotation;
    }

}