Loading packages/SystemUI/res/values/strings.xml +8 −0 Original line number Diff line number Diff line Loading @@ -2678,6 +2678,14 @@ <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> <!-- 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] --> <string name="magnification_mode_switch_state_full_screen">Magnify entire screen</string> <!-- A11y state description for magnification mode switch that device is in window mode. [CHAR LIMIT=NONE] --> <string name="magnification_mode_switch_state_window">Magnify part of screen</string> <!-- Click action label for magnification switch. [CHAR LIMIT=NONE] --> <string name="magnification_mode_switch_click_label">Switch</string> <!-- Device Controls strings --> <!-- Device Controls empty state, title [CHAR LIMIT=30] --> Loading packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +35 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,14 @@ package com.android.systemui.accessibility; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; import android.annotation.NonNull; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; import android.graphics.PointF; import android.os.Bundle; import android.provider.Settings; import android.util.MathUtils; import android.view.Gravity; Loading @@ -28,6 +31,8 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -71,6 +76,29 @@ class MagnificationModeSwitch { applyResourcesValues(); mImageView.setImageResource(getIconResId(mMagnificationMode)); mImageView.setOnTouchListener(this::onTouch); mImageView.setAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); info.setStateDescription(formatStateDescription()); info.setContentDescription(mContext.getResources().getString( R.string.magnification_mode_switch_description)); final AccessibilityAction clickAction = new AccessibilityAction( AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString( R.string.magnification_mode_switch_click_label)); info.addAction(clickAction); info.setClickable(true); } @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (action == AccessibilityAction.ACTION_CLICK.getId()) { handleSingleTap(); return true; } return super.performAccessibilityAction(host, action, args); } }); mAnimationTask = () -> { mImageView.animate() Loading @@ -81,6 +109,13 @@ class MagnificationModeSwitch { }; } private CharSequence formatStateDescription() { final int stringId = mMagnificationMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW ? R.string.magnification_mode_switch_state_window : R.string.magnification_mode_switch_state_full_screen; return mContext.getResources().getString(stringId); } private void applyResourcesValues() { final int padding = mContext.getResources().getDimensionPixelSize( R.dimen.magnification_switch_button_padding); Loading packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +49 −7 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK; import static com.android.systemui.accessibility.MagnificationModeSwitch.getIconResId; import static junit.framework.Assert.assertEquals; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyLong; Loading @@ -45,10 +48,12 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.ViewPropertyAnimator; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ImageView; import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; Loading Loading @@ -142,13 +147,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { resetMockImageViewAndAnimator(); listener.onTouch(mSpyImageView, MotionEvent.obtain( 0, ViewConfiguration.getTapTimeout(), ACTION_UP, 100, 100, 0)); verify(mViewPropertyAnimator).cancel(); verify(mSpyImageView).setImageResource( getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)); verify(mWindowManager).removeView(mSpyImageView); final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, actualMode); verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); } @Test Loading Loading @@ -222,6 +221,34 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { assertShowButtonAnimation(); } @Test public void initializeA11yNode_showWindowModeButton_expectedValues() { mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); final AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo(); mSpyImageView.onInitializeAccessibilityNodeInfo(nodeInfo); assertEquals(mContext.getString(R.string.magnification_mode_switch_description), nodeInfo.getContentDescription()); assertEquals(mContext.getString(R.string.magnification_mode_switch_state_window), nodeInfo.getStateDescription()); assertThat(nodeInfo.getActionList(), hasItems(new AccessibilityNodeInfo.AccessibilityAction( ACTION_CLICK.getId(), mContext.getResources().getString( R.string.magnification_mode_switch_click_label)))); } @Test public void performA11yActions_showWindowModeButton_verifyTapAction() { mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); resetMockImageViewAndAnimator(); mSpyImageView.performAccessibilityAction( ACTION_CLICK.getId(), null); verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); } private void assertModeUnchanged(int expectedMode) { final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); Loading Loading @@ -254,4 +281,19 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { Mockito.reset(mSpyImageView); initMockImageViewAndAnimator(); } /** * Verifies the tap behaviour including the image of the button and the magnification mode. * * @param expectedMode the expected mode after tapping */ private void verifyTapAction(int expectedMode) { verify(mViewPropertyAnimator).cancel(); verify(mSpyImageView).setImageResource( getIconResId(expectedMode)); verify(mWindowManager).removeView(mSpyImageView); final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); assertEquals(expectedMode, actualMode); } } Loading
packages/SystemUI/res/values/strings.xml +8 −0 Original line number Diff line number Diff line Loading @@ -2678,6 +2678,14 @@ <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> <!-- 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] --> <string name="magnification_mode_switch_state_full_screen">Magnify entire screen</string> <!-- A11y state description for magnification mode switch that device is in window mode. [CHAR LIMIT=NONE] --> <string name="magnification_mode_switch_state_window">Magnify part of screen</string> <!-- Click action label for magnification switch. [CHAR LIMIT=NONE] --> <string name="magnification_mode_switch_click_label">Switch</string> <!-- Device Controls strings --> <!-- Device Controls empty state, title [CHAR LIMIT=30] --> Loading
packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +35 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,14 @@ package com.android.systemui.accessibility; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; import android.annotation.NonNull; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; import android.graphics.PointF; import android.os.Bundle; import android.provider.Settings; import android.util.MathUtils; import android.view.Gravity; Loading @@ -28,6 +31,8 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -71,6 +76,29 @@ class MagnificationModeSwitch { applyResourcesValues(); mImageView.setImageResource(getIconResId(mMagnificationMode)); mImageView.setOnTouchListener(this::onTouch); mImageView.setAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); info.setStateDescription(formatStateDescription()); info.setContentDescription(mContext.getResources().getString( R.string.magnification_mode_switch_description)); final AccessibilityAction clickAction = new AccessibilityAction( AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString( R.string.magnification_mode_switch_click_label)); info.addAction(clickAction); info.setClickable(true); } @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (action == AccessibilityAction.ACTION_CLICK.getId()) { handleSingleTap(); return true; } return super.performAccessibilityAction(host, action, args); } }); mAnimationTask = () -> { mImageView.animate() Loading @@ -81,6 +109,13 @@ class MagnificationModeSwitch { }; } private CharSequence formatStateDescription() { final int stringId = mMagnificationMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW ? R.string.magnification_mode_switch_state_window : R.string.magnification_mode_switch_state_full_screen; return mContext.getResources().getString(stringId); } private void applyResourcesValues() { final int padding = mContext.getResources().getDimensionPixelSize( R.dimen.magnification_switch_button_padding); Loading
packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +49 −7 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK; import static com.android.systemui.accessibility.MagnificationModeSwitch.getIconResId; import static junit.framework.Assert.assertEquals; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyLong; Loading @@ -45,10 +48,12 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.ViewPropertyAnimator; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ImageView; import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; Loading Loading @@ -142,13 +147,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { resetMockImageViewAndAnimator(); listener.onTouch(mSpyImageView, MotionEvent.obtain( 0, ViewConfiguration.getTapTimeout(), ACTION_UP, 100, 100, 0)); verify(mViewPropertyAnimator).cancel(); verify(mSpyImageView).setImageResource( getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)); verify(mWindowManager).removeView(mSpyImageView); final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, actualMode); verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); } @Test Loading Loading @@ -222,6 +221,34 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { assertShowButtonAnimation(); } @Test public void initializeA11yNode_showWindowModeButton_expectedValues() { mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); final AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo(); mSpyImageView.onInitializeAccessibilityNodeInfo(nodeInfo); assertEquals(mContext.getString(R.string.magnification_mode_switch_description), nodeInfo.getContentDescription()); assertEquals(mContext.getString(R.string.magnification_mode_switch_state_window), nodeInfo.getStateDescription()); assertThat(nodeInfo.getActionList(), hasItems(new AccessibilityNodeInfo.AccessibilityAction( ACTION_CLICK.getId(), mContext.getResources().getString( R.string.magnification_mode_switch_click_label)))); } @Test public void performA11yActions_showWindowModeButton_verifyTapAction() { mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); resetMockImageViewAndAnimator(); mSpyImageView.performAccessibilityAction( ACTION_CLICK.getId(), null); verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); } private void assertModeUnchanged(int expectedMode) { final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); Loading Loading @@ -254,4 +281,19 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { Mockito.reset(mSpyImageView); initMockImageViewAndAnimator(); } /** * Verifies the tap behaviour including the image of the button and the magnification mode. * * @param expectedMode the expected mode after tapping */ private void verifyTapAction(int expectedMode) { verify(mViewPropertyAnimator).cancel(); verify(mSpyImageView).setImageResource( getIconResId(expectedMode)); verify(mWindowManager).removeView(mSpyImageView); final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); assertEquals(expectedMode, actualMode); } }