Loading services/core/java/com/android/server/policy/AccessibilityShortcutController.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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. Loading services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java +26 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading @@ -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)); Loading @@ -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); Loading Loading @@ -170,6 +187,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 { Loading Loading
services/core/java/com/android/server/policy/AccessibilityShortcutController.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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. Loading
services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java +26 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading @@ -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)); Loading @@ -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); Loading Loading @@ -170,6 +187,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 { Loading