Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58277fab authored by Phil Weaver's avatar Phil Weaver Committed by Android (Google) Code Review
Browse files

Merge "Add haptic feedback for a11y shortcut"

parents b3d2e110 32ea3725
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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.
+26 −1
Original line number Diff line number Diff line
@@ -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);
@@ -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 {