Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java +3 −6 Original line number Diff line number Diff line Loading @@ -14,14 +14,11 @@ package com.android.systemui.statusbar.policy; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; import java.util.List; /** * For mocking because AccessibilityManager is final for some reason... */ Loading Loading @@ -62,8 +59,8 @@ public class AccessibilityManagerWrapper implements mAccessibilityManager.sendAccessibilityEvent(event); } public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList( int feedbackTypeFlags) { return mAccessibilityManager.getEnabledAccessibilityServiceList(feedbackTypeFlags); /** Returns a recommended ui timeout value in milliseconds. */ public int getRecommendedTimeoutMillis(int originalTimeout, int uiContentFlags) { return mAccessibilityManager.getRecommendedTimeoutMillis(originalTimeout, uiContentFlags); } } packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +17 −51 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.systemui.volume; import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK; import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; Loading @@ -32,7 +30,6 @@ import static android.view.View.VISIBLE; import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED; import android.accessibilityservice.AccessibilityServiceInfo; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.ActivityManager; Loading Loading @@ -68,13 +65,12 @@ import android.view.ContextThemeWrapper; import android.view.MotionEvent; import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.View.OnAttachStateChangeListener; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; Loading Loading @@ -113,6 +109,10 @@ public class VolumeDialogImpl implements VolumeDialog { private static final long USER_ATTEMPT_GRACE_PERIOD = 1000; private static final int UPDATE_ANIMATION_DURATION = 80; static final int DIALOG_TIMEOUT_MILLIS = 3000; static final int DIALOG_SAFETYWARNING_TIMEOUT_MILLIS = 5000; static final int DIALOG_HOVERING_TIMEOUT_MILLIS = 16000; private final Context mContext; private final H mHandler = new H(); private final VolumeDialogController mController; Loading Loading @@ -170,7 +170,6 @@ public class VolumeDialogImpl implements VolumeDialog { @Override public void destroy() { mAccessibility.destroy(); mController.removeCallback(mControllerCallbackH); mHandler.removeCallbacksAndMessages(null); } Loading Loading @@ -356,8 +355,6 @@ public class VolumeDialogImpl implements VolumeDialog { writer.print(" mDynamic: "); writer.println(mDynamic); writer.print(" mAutomute: "); writer.println(mAutomute); writer.print(" mSilentMode: "); writer.println(mSilentMode); writer.print(" mAccessibility.mFeedbackEnabled: "); writer.println(mAccessibility.mFeedbackEnabled); } private static int getImpliedLevel(SeekBar seekBar, int progress) { Loading Loading @@ -571,10 +568,18 @@ public class VolumeDialogImpl implements VolumeDialog { } private int computeTimeoutH() { if (mAccessibility.mFeedbackEnabled) return 20000; if (mHovering) return 16000; if (mSafetyWarning != null) return 5000; return 3000; if (mHovering) { return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_HOVERING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } if (mSafetyWarning != null) { return mAccessibilityMgr.getRecommendedTimeoutMillis( DIALOG_SAFETYWARNING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_TEXT | AccessibilityManager.FLAG_CONTENT_CONTROLS); } return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } protected void dismissH(int reason) { Loading Loading @@ -1261,28 +1266,8 @@ public class VolumeDialogImpl implements VolumeDialog { } private final class Accessibility extends AccessibilityDelegate { private boolean mFeedbackEnabled; public void init() { mDialogView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { @Override public void onViewDetachedFromWindow(View v) { if (D.BUG) Log.d(TAG, "onViewDetachedFromWindow"); } @Override public void onViewAttachedToWindow(View v) { if (D.BUG) Log.d(TAG, "onViewAttachedToWindow"); updateFeedbackEnabled(); } }); mDialogView.setAccessibilityDelegate(this); mAccessibilityMgr.addCallback(mListener); updateFeedbackEnabled(); } public void destroy() { mAccessibilityMgr.removeCallback(mListener); } @Override Loading @@ -1298,25 +1283,6 @@ public class VolumeDialogImpl implements VolumeDialog { rescheduleTimeoutH(); return super.onRequestSendAccessibilityEvent(host, child, event); } private void updateFeedbackEnabled() { mFeedbackEnabled = computeFeedbackEnabled(); } private boolean computeFeedbackEnabled() { // are there any enabled non-generic a11y services? final List<AccessibilityServiceInfo> services = mAccessibilityMgr.getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK); for (AccessibilityServiceInfo asi : services) { if (asi.feedbackType != 0 && asi.feedbackType != FEEDBACK_GENERIC) { return true; } } return false; } private final AccessibilityServicesStateChangeListener mListener = enabled -> updateFeedbackEnabled(); } private static class VolumeRow { Loading packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +46 −2 Original line number Diff line number Diff line Loading @@ -27,18 +27,23 @@ import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.media.AudioManager; import android.os.SystemClock; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.text.TextUtils; import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.ImageView; import com.android.systemui.R; Loading @@ -48,10 +53,11 @@ import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.function.Predicate; Loading @@ -59,7 +65,6 @@ import java.util.function.Predicate; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @Ignore public class VolumeDialogImplTest extends SysuiTestCase { VolumeDialogImpl mDialog; Loading Loading @@ -113,6 +118,45 @@ public class VolumeDialogImplTest extends SysuiTestCase { + " failed test", condition.test(view)); } } @Test public void testComputeTimeout() { Mockito.reset(mAccessibilityMgr); mDialog.rescheduleTimeoutH(); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } @Test public void testComputeTimeout_withHovering() { Mockito.reset(mAccessibilityMgr); View dialog = mDialog.getDialogView(); long uptimeMillis = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain(uptimeMillis, uptimeMillis, MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); dialog.dispatchGenericMotionEvent(event); event.recycle(); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_HOVERING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } @Test public void testComputeTimeout_withSafetyWarningOn() { Mockito.reset(mAccessibilityMgr); ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onShowSafetyWarning(AudioManager.FLAG_SHOW_UI); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_SAFETYWARNING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_TEXT | AccessibilityManager.FLAG_CONTENT_CONTROLS); } /* @Test public void testContentDescriptions() { Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java +3 −6 Original line number Diff line number Diff line Loading @@ -14,14 +14,11 @@ package com.android.systemui.statusbar.policy; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; import java.util.List; /** * For mocking because AccessibilityManager is final for some reason... */ Loading Loading @@ -62,8 +59,8 @@ public class AccessibilityManagerWrapper implements mAccessibilityManager.sendAccessibilityEvent(event); } public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList( int feedbackTypeFlags) { return mAccessibilityManager.getEnabledAccessibilityServiceList(feedbackTypeFlags); /** Returns a recommended ui timeout value in milliseconds. */ public int getRecommendedTimeoutMillis(int originalTimeout, int uiContentFlags) { return mAccessibilityManager.getRecommendedTimeoutMillis(originalTimeout, uiContentFlags); } }
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +17 −51 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.systemui.volume; import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK; import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; Loading @@ -32,7 +30,6 @@ import static android.view.View.VISIBLE; import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED; import android.accessibilityservice.AccessibilityServiceInfo; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.ActivityManager; Loading Loading @@ -68,13 +65,12 @@ import android.view.ContextThemeWrapper; import android.view.MotionEvent; import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.View.OnAttachStateChangeListener; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; Loading Loading @@ -113,6 +109,10 @@ public class VolumeDialogImpl implements VolumeDialog { private static final long USER_ATTEMPT_GRACE_PERIOD = 1000; private static final int UPDATE_ANIMATION_DURATION = 80; static final int DIALOG_TIMEOUT_MILLIS = 3000; static final int DIALOG_SAFETYWARNING_TIMEOUT_MILLIS = 5000; static final int DIALOG_HOVERING_TIMEOUT_MILLIS = 16000; private final Context mContext; private final H mHandler = new H(); private final VolumeDialogController mController; Loading Loading @@ -170,7 +170,6 @@ public class VolumeDialogImpl implements VolumeDialog { @Override public void destroy() { mAccessibility.destroy(); mController.removeCallback(mControllerCallbackH); mHandler.removeCallbacksAndMessages(null); } Loading Loading @@ -356,8 +355,6 @@ public class VolumeDialogImpl implements VolumeDialog { writer.print(" mDynamic: "); writer.println(mDynamic); writer.print(" mAutomute: "); writer.println(mAutomute); writer.print(" mSilentMode: "); writer.println(mSilentMode); writer.print(" mAccessibility.mFeedbackEnabled: "); writer.println(mAccessibility.mFeedbackEnabled); } private static int getImpliedLevel(SeekBar seekBar, int progress) { Loading Loading @@ -571,10 +568,18 @@ public class VolumeDialogImpl implements VolumeDialog { } private int computeTimeoutH() { if (mAccessibility.mFeedbackEnabled) return 20000; if (mHovering) return 16000; if (mSafetyWarning != null) return 5000; return 3000; if (mHovering) { return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_HOVERING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } if (mSafetyWarning != null) { return mAccessibilityMgr.getRecommendedTimeoutMillis( DIALOG_SAFETYWARNING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_TEXT | AccessibilityManager.FLAG_CONTENT_CONTROLS); } return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } protected void dismissH(int reason) { Loading Loading @@ -1261,28 +1266,8 @@ public class VolumeDialogImpl implements VolumeDialog { } private final class Accessibility extends AccessibilityDelegate { private boolean mFeedbackEnabled; public void init() { mDialogView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { @Override public void onViewDetachedFromWindow(View v) { if (D.BUG) Log.d(TAG, "onViewDetachedFromWindow"); } @Override public void onViewAttachedToWindow(View v) { if (D.BUG) Log.d(TAG, "onViewAttachedToWindow"); updateFeedbackEnabled(); } }); mDialogView.setAccessibilityDelegate(this); mAccessibilityMgr.addCallback(mListener); updateFeedbackEnabled(); } public void destroy() { mAccessibilityMgr.removeCallback(mListener); } @Override Loading @@ -1298,25 +1283,6 @@ public class VolumeDialogImpl implements VolumeDialog { rescheduleTimeoutH(); return super.onRequestSendAccessibilityEvent(host, child, event); } private void updateFeedbackEnabled() { mFeedbackEnabled = computeFeedbackEnabled(); } private boolean computeFeedbackEnabled() { // are there any enabled non-generic a11y services? final List<AccessibilityServiceInfo> services = mAccessibilityMgr.getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK); for (AccessibilityServiceInfo asi : services) { if (asi.feedbackType != 0 && asi.feedbackType != FEEDBACK_GENERIC) { return true; } } return false; } private final AccessibilityServicesStateChangeListener mListener = enabled -> updateFeedbackEnabled(); } private static class VolumeRow { Loading
packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +46 −2 Original line number Diff line number Diff line Loading @@ -27,18 +27,23 @@ import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.media.AudioManager; import android.os.SystemClock; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.text.TextUtils; import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.ImageView; import com.android.systemui.R; Loading @@ -48,10 +53,11 @@ import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.function.Predicate; Loading @@ -59,7 +65,6 @@ import java.util.function.Predicate; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @Ignore public class VolumeDialogImplTest extends SysuiTestCase { VolumeDialogImpl mDialog; Loading Loading @@ -113,6 +118,45 @@ public class VolumeDialogImplTest extends SysuiTestCase { + " failed test", condition.test(view)); } } @Test public void testComputeTimeout() { Mockito.reset(mAccessibilityMgr); mDialog.rescheduleTimeoutH(); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } @Test public void testComputeTimeout_withHovering() { Mockito.reset(mAccessibilityMgr); View dialog = mDialog.getDialogView(); long uptimeMillis = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain(uptimeMillis, uptimeMillis, MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); dialog.dispatchGenericMotionEvent(event); event.recycle(); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_HOVERING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_CONTROLS); } @Test public void testComputeTimeout_withSafetyWarningOn() { Mockito.reset(mAccessibilityMgr); ArgumentCaptor<VolumeDialogController.Callbacks> controllerCallbackCapture = ArgumentCaptor.forClass(VolumeDialogController.Callbacks.class); verify(mController).addCallback(controllerCallbackCapture.capture(), any()); VolumeDialogController.Callbacks callbacks = controllerCallbackCapture.getValue(); callbacks.onShowSafetyWarning(AudioManager.FLAG_SHOW_UI); verify(mAccessibilityMgr).getRecommendedTimeoutMillis( VolumeDialogImpl.DIALOG_SAFETYWARNING_TIMEOUT_MILLIS, AccessibilityManager.FLAG_CONTENT_TEXT | AccessibilityManager.FLAG_CONTENT_CONTROLS); } /* @Test public void testContentDescriptions() { Loading