Add haptic feedback for a11y shortcut
Bug: 35036259 Test: Activated shortcut, felt the vibration. Also added unit test. Change-Id: I3070620d9152ce9b9bb084ee4f01d26020f125d0
This commit is contained in:
@@ -29,6 +29,7 @@ import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
@@ -48,6 +49,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
|
||||
*/
|
||||
public class AccessibilityShortcutController {
|
||||
private static final String TAG = "AccessibilityShortcutController";
|
||||
private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
|
||||
.build();
|
||||
|
||||
|
||||
private final Context mContext;
|
||||
private AlertDialog mAlertDialog;
|
||||
@@ -100,6 +106,8 @@ public class AccessibilityShortcutController {
|
||||
final int userId = ActivityManager.getCurrentUser();
|
||||
final int dialogAlreadyShown = Settings.Secure.getIntForUser(
|
||||
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, userId);
|
||||
|
||||
// Play a notification tone
|
||||
final Ringtone tone =
|
||||
RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_NOTIFICATION_URI);
|
||||
if (tone != null) {
|
||||
@@ -108,6 +116,18 @@ public class AccessibilityShortcutController {
|
||||
.build());
|
||||
tone.play();
|
||||
}
|
||||
|
||||
// Play a notification vibration
|
||||
Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if ((vibrator != null) && vibrator.hasVibrator()) {
|
||||
// Don't check if haptics are disabled, as we need to alert the user that their
|
||||
// way of interacting with the phone may change if they activate the shortcut
|
||||
long[] vibePattern = PhoneWindowManager.getLongIntArray(mContext.getResources(),
|
||||
R.array.config_safeModeDisabledVibePattern);
|
||||
vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
|
||||
|
||||
if (dialogAlreadyShown == 0) {
|
||||
// The first time, we show a warning rather than toggle the service to give the user a
|
||||
// chance to turn off this feature before stuff gets enabled.
|
||||
|
||||
@@ -21,9 +21,11 @@ import android.app.AlertDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
@@ -54,6 +56,7 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SER
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.mockito.AdditionalMatchers.aryEq;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
@@ -67,6 +70,11 @@ import static org.mockito.Mockito.when;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AccessibilityShortcutControllerTest {
|
||||
private static final String SERVICE_NAME_STRING = "fake.package/fake.service.name";
|
||||
private static final long VIBRATOR_PATTERN_1 = 100L;
|
||||
private static final long VIBRATOR_PATTERN_2 = 150L;
|
||||
private static final int[] VIBRATOR_PATTERN_INT = {(int) VIBRATOR_PATTERN_1,
|
||||
(int) VIBRATOR_PATTERN_2};
|
||||
private static final long[] VIBRATOR_PATTERN_LONG = {VIBRATOR_PATTERN_1, VIBRATOR_PATTERN_2};
|
||||
|
||||
private @Mock Context mContext;
|
||||
private @Mock FrameworkObjectProvider mFrameworkObjectProvider;
|
||||
@@ -77,6 +85,8 @@ public class AccessibilityShortcutControllerTest {
|
||||
private @Mock AccessibilityServiceInfo mServiceInfo;
|
||||
private @Mock Resources mResources;
|
||||
private @Mock Toast mToast;
|
||||
private @Mock Vibrator mVibrator;
|
||||
private @Mock ApplicationInfo mApplicationInfo;
|
||||
|
||||
private MockContentResolver mContentResolver;
|
||||
private WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
|
||||
@@ -85,10 +95,15 @@ public class AccessibilityShortcutControllerTest {
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mVibrator.hasVibrator()).thenReturn(true);
|
||||
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
|
||||
when(mContext.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(mVibrator);
|
||||
|
||||
mContentResolver = new MockContentResolver(mContext);
|
||||
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
|
||||
.thenReturn(Collections.singletonList(mServiceInfo));
|
||||
@@ -104,6 +119,8 @@ public class AccessibilityShortcutControllerTest {
|
||||
.thenReturn(mToast);
|
||||
|
||||
when(mResources.getString(anyInt())).thenReturn("Howdy %s");
|
||||
when(mResources.getIntArray(anyInt())).thenReturn(VIBRATOR_PATTERN_INT);
|
||||
|
||||
ResolveInfo resolveInfo = mock(ResolveInfo.class);
|
||||
when(resolveInfo.loadLabel(anyObject())).thenReturn("Service name");
|
||||
when(mServiceInfo.getResolveInfo()).thenReturn(resolveInfo);
|
||||
@@ -162,6 +179,14 @@ public class AccessibilityShortcutControllerTest {
|
||||
assertTrue(accessibilityShortcutController.isAccessibilityShortcutAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnAccessibilityShortcut_vibrates() {
|
||||
configureShortcutEnabled();
|
||||
AccessibilityShortcutController accessibilityShortcutController = getController();
|
||||
accessibilityShortcutController.performAccessibilityShortcut();
|
||||
verify(mVibrator).vibrate(aryEq(VIBRATOR_PATTERN_LONG), eq(-1), anyObject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnAccessibilityShortcut_firstTime_showsWarningDialog()
|
||||
throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user