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

Commit 32ea3725 authored by Phil Weaver's avatar Phil Weaver
Browse files

Add haptic feedback for a11y shortcut

Bug: 35036259
Test: Activated shortcut, felt the vibration. Also added unit test.
Change-Id: I3070620d9152ce9b9bb084ee4f01d26020f125d0
parent 7219795f
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);
@@ -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 {