diff options
2 files changed, 46 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java index eec1fefde568..cd55f50d9b4b 100644 --- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java +++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java @@ -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. diff --git a/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java b/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java index 1de6348c6f40..8591886b36cd 100644 --- a/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java @@ -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); @@ -163,6 +180,14 @@ public class AccessibilityShortcutControllerTest { } @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 { configureShortcutEnabled(); |