Applies Accessibility UI timeout for showing duration of magnification button

Users can change Time to take action (Accessibility timeout) settings
to make the magnification button showing duration aligned with
recommended a11y UI timeout.
Settings Page: Settings > Accessibility settings > Time to take action.
Demo video: b/167977099#comment2

Bug: 167977099
Test: atest MagnificationModeSwitchTest
Change-Id: I428b9d8221854edc476fcd455f3b9114b6b97ae9
This commit is contained in:
mincheli
2020-09-18 16:33:57 +08:00
parent 168d7918b8
commit 636aa9b359
3 changed files with 43 additions and 10 deletions

View File

@@ -31,6 +31,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ImageView;
@@ -48,15 +49,16 @@ class MagnificationModeSwitch {
@VisibleForTesting
static final long FADING_ANIMATION_DURATION_MS = 300;
private static final int DEFAULT_FADE_OUT_ANIMATION_DELAY_MS = 3000;
// The button visible duration starting from the last showButton() called.
private int mVisibleDuration = DEFAULT_FADE_OUT_ANIMATION_DELAY_MS;
@VisibleForTesting
static final int DEFAULT_FADE_OUT_ANIMATION_DELAY_MS = 3000;
private int mUiTimeout;
private final Runnable mFadeInAnimationTask;
private final Runnable mFadeOutAnimationTask;
@VisibleForTesting
boolean mIsFadeOutAnimating = false;
private final Context mContext;
private final AccessibilityManager mAccessibilityManager;
private final WindowManager mWindowManager;
private final ImageView mImageView;
private final PointF mLastDown = new PointF();
@@ -74,6 +76,7 @@ class MagnificationModeSwitch {
@VisibleForTesting
MagnificationModeSwitch(Context context, @NonNull ImageView imageView) {
mContext = context;
mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
mWindowManager = (WindowManager) mContext.getSystemService(
Context.WINDOW_SERVICE);
mParams = createLayoutParams();
@@ -202,6 +205,10 @@ class MagnificationModeSwitch {
mWindowManager.addView(mImageView, mParams);
mIsVisible = true;
mImageView.postOnAnimation(mFadeInAnimationTask);
mUiTimeout = mAccessibilityManager.getRecommendedTimeoutMillis(
DEFAULT_FADE_OUT_ANIMATION_DELAY_MS,
AccessibilityManager.FLAG_CONTENT_ICONS
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
}
if (mIsFadeOutAnimating) {
mImageView.animate().cancel();
@@ -209,7 +216,7 @@ class MagnificationModeSwitch {
}
// Refresh the time slot of the fade-out task whenever this method is called.
mImageView.removeCallbacks(mFadeOutAnimationTask);
mImageView.postOnAnimationDelayed(mFadeOutAnimationTask, mVisibleDuration);
mImageView.postOnAnimationDelayed(mFadeOutAnimationTask, mUiTimeout);
}
void onConfigurationChanged(int configDiff) {

View File

@@ -72,8 +72,7 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
super(context);
mHandler = mainHandler;
mLastConfiguration = new Configuration(context.getResources().getConfiguration());
mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
Context.ACCESSIBILITY_SERVICE);
mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
mCommandQueue = commandQueue;
mModeSwitchesController = modeSwitchesController;
final WindowMagnificationController controller = new WindowMagnificationController(mContext,

View File

@@ -24,6 +24,7 @@ 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.DEFAULT_FADE_OUT_ANIMATION_DELAY_MS;
import static com.android.systemui.accessibility.MagnificationModeSwitch.FADING_ANIMATION_DURATION_MS;
import static com.android.systemui.accessibility.MagnificationModeSwitch.getIconResId;
@@ -33,6 +34,7 @@ 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.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
@@ -48,6 +50,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewPropertyAnimator;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
@@ -74,6 +77,8 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
private ImageView mSpyImageView;
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private WindowManager mWindowManager;
@Mock
private ViewPropertyAnimator mViewPropertyAnimator;
@@ -89,6 +94,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
wm.getMaximumWindowMetrics()
).when(mWindowManager).getMaximumWindowMetrics();
mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
mSpyImageView = Mockito.spy(new ImageView(mContext));
resetMockImageViewAndAnimator();
@@ -108,16 +114,37 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void showWindowModeButton_fullscreenMode_addViewAndSetImageResource() {
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
verify(mSpyImageView).setImageResource(
getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
verify(mWindowManager).addView(eq(mSpyImageView), any(WindowManager.LayoutParams.class));
assertShowFadingAnimation(FADE_IN_ALPHA);
assertShowFadingAnimation(FADE_OUT_ALPHA);
}
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
verify(mViewPropertyAnimator).withEndAction(captor.capture());
verify(mWindowManager).addView(eq(mSpyImageView), any(WindowManager.LayoutParams.class));
@Test
public void showMagnificationButton_a11yTimeout_autoFadeOut() {
final int a11yTimeout = 12345;
when(mAccessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenReturn(
a11yTimeout);
captor.getValue().run();
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
verify(mAccessibilityManager).getRecommendedTimeoutMillis(
DEFAULT_FADE_OUT_ANIMATION_DELAY_MS, AccessibilityManager.FLAG_CONTENT_ICONS
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
final ArgumentCaptor<Runnable> fadeOutCaptor = ArgumentCaptor.forClass(Runnable.class);
final ArgumentCaptor<Long> fadeOutDelay = ArgumentCaptor.forClass(Long.class);
verify(mSpyImageView).postOnAnimationDelayed(fadeOutCaptor.capture(),
fadeOutDelay.capture());
assertEquals(a11yTimeout, (long) fadeOutDelay.getValue());
// Verify the end action after fade-out.
fadeOutCaptor.getValue().run();
final ArgumentCaptor<Runnable> endActionCaptor = ArgumentCaptor.forClass(Runnable.class);
verify(mViewPropertyAnimator).withEndAction(endActionCaptor.capture());
endActionCaptor.getValue().run();
verify(mViewPropertyAnimator).cancel();
verify(mWindowManager).removeView(mSpyImageView);