Merge "Update VolumeDialog to use a11y api for ui timeout value."

This commit is contained in:
Rhed Jao
2018-11-15 06:13:42 +00:00
committed by Android (Google) Code Review
3 changed files with 66 additions and 59 deletions

View File

@@ -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...
*/
@@ -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);
}
}

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -170,7 +170,6 @@ public class VolumeDialogImpl implements VolumeDialog {
@Override
public void destroy() {
mAccessibility.destroy();
mController.removeCallback(mControllerCallbackH);
mHandler.removeCallbacksAndMessages(null);
}
@@ -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) {
@@ -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) {
@@ -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
@@ -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 {

View File

@@ -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;
@@ -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;
@@ -59,7 +65,6 @@ import java.util.function.Predicate;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@Ignore
public class VolumeDialogImplTest extends SysuiTestCase {
VolumeDialogImpl mDialog;
@@ -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() {