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

Commit d3a55c19 authored by Daniel Norman's avatar Daniel Norman Committed by Android (Google) Code Review
Browse files

Merge "Allows the a11y volume shortcut disambig dialog to show on lock screen." into main

parents 6ff5b9ab 4623b566
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -6,3 +6,10 @@ flag {
    description: "Enable force force-dark for smart inversion and dark theme everywhere"
    bug: "282821643"
}

flag {
    namespace: "accessibility"
    name: "allow_shortcut_chooser_on_lockscreen"
    description: "Allows the a11y shortcut disambig dialog to appear on the lockscreen"
    bug: "303871725"
}
+24 −2
Original line number Diff line number Diff line
@@ -28,15 +28,19 @@ import static com.android.internal.accessibility.util.AccessibilityUtils.isUserS
import android.annotation.Nullable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.Flags;
import android.widget.AdapterView;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.List;
@@ -207,6 +211,11 @@ public class AccessibilityShortcutChooserActivity extends Activity {
                isEditMenuMode ? this::onTargetChecked : this::onTargetSelected);
    }

    @VisibleForTesting
    public AlertDialog getMenuDialog() {
        return mMenuDialog;
    }

    private AlertDialog createMenuDialog() {
        final String dialogTitle =
                getString(R.string.accessibility_select_shortcut_menu_title);
@@ -216,12 +225,25 @@ public class AccessibilityShortcutChooserActivity extends Activity {
                .setAdapter(mTargetAdapter, /* listener= */ null)
                .setOnDismissListener(dialog -> finish());

        if (isUserSetupCompleted(this)) {
        boolean allowEditing = isUserSetupCompleted(this);
        boolean showWhenLocked = false;
        if (Flags.allowShortcutChooserOnLockscreen()) {
            final KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
            if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
                allowEditing = false;
                showWhenLocked = true;
            }
        }
        if (allowEditing) {
            final String positiveButtonText =
                    getString(R.string.edit_accessibility_shortcut_menu_button);
            builder.setPositiveButton(positiveButtonText, /* listener= */ null);
        }

        return builder.create();
        final AlertDialog dialog = builder.create();
        if (showWhenLocked) {
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        }
        return dialog;
    }
}
+55 −9
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static com.google.common.truth.Truth.assertThat;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.endsWith;
import static org.mockito.ArgumentMatchers.any;
@@ -39,6 +41,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -47,11 +51,17 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.Flags;
import android.view.accessibility.IAccessibilityManager;

import androidx.lifecycle.Lifecycle;
@@ -89,6 +99,9 @@ public class AccessibilityShortcutChooserActivityTest {
    private ActivityScenario<TestAccessibilityShortcutChooserActivity> mScenario;
    private TestAccessibilityShortcutChooserActivity mActivity;

    @Rule
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Mock
@@ -101,6 +114,8 @@ public class AccessibilityShortcutChooserActivityTest {
    private ApplicationInfo mApplicationInfo;
    @Mock
    private IAccessibilityManager mAccessibilityManagerService;
    @Mock
    private KeyguardManager mKeyguardManager;

    @Before
    public void setUp() throws Exception {
@@ -116,22 +131,19 @@ public class AccessibilityShortcutChooserActivityTest {
                        Collections.singletonList(mAccessibilityServiceInfo)));
        when(mAccessibilityManagerService.isAccessibilityTargetAllowed(
                anyString(), anyInt(), anyInt())).thenReturn(true);
        TestAccessibilityShortcutChooserActivity.setupForTesting(mAccessibilityManagerService);
        mScenario = ActivityScenario.launch(TestAccessibilityShortcutChooserActivity.class);
        mScenario.onActivity(activity -> mActivity = activity);
        mScenario.moveToState(Lifecycle.State.CREATED);
        mScenario.moveToState(Lifecycle.State.STARTED);
        mScenario.moveToState(Lifecycle.State.RESUMED);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
        TestAccessibilityShortcutChooserActivity.setupForTesting(
                mAccessibilityManagerService, mKeyguardManager);
    }

    @After
    public void cleanUp() {
        mScenario.moveToState(Lifecycle.State.DESTROYED);
        mScenario.close();
    }

    @Test
    public void doubleClickTestServiceAndClickDenyButton_permissionDialogDoesNotExist() {
        launchActivity();
        openShortcutsList();

        // Performing the double-click is flaky so retry if needed.
@@ -154,6 +166,7 @@ public class AccessibilityShortcutChooserActivityTest {
            throws Exception {
        when(mAccessibilityManagerService.isAccessibilityTargetAllowed(
                eq(TEST_COMPONENT_NAME.getPackageName()), anyInt(), anyInt())).thenReturn(false);
        launchActivity();
        openShortcutsList();

        onView(withText(TEST_LABEL)).perform(scrollTo(), click());
@@ -165,6 +178,7 @@ public class AccessibilityShortcutChooserActivityTest {
    @Test
    public void popEditShortcutMenuList_oneHandedModeEnabled_shouldBeInListView() {
        TestUtils.setOneHandedModeEnabled(this, /* enabled= */ true);
        launchActivity();
        openShortcutsList();

        onView(allOf(withClassName(endsWith("ListView")), isDisplayed())).perform(swipeUp());
@@ -176,6 +190,7 @@ public class AccessibilityShortcutChooserActivityTest {
    @Test
    public void popEditShortcutMenuList_oneHandedModeDisabled_shouldNotBeInListView() {
        TestUtils.setOneHandedModeEnabled(this, /* enabled= */ false);
        launchActivity();
        openShortcutsList();

        onView(allOf(withClassName(endsWith("ListView")), isDisplayed())).perform(swipeUp());
@@ -184,6 +199,30 @@ public class AccessibilityShortcutChooserActivityTest {
        onView(withText(ONE_HANDED_MODE)).inRoot(isDialog()).check(doesNotExist());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ALLOW_SHORTCUT_CHOOSER_ON_LOCKSCREEN)
    public void createDialog_onLockscreen_hasExpectedContent() {
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
        launchActivity();

        final AlertDialog dialog = mActivity.getMenuDialog();

        assertThat(dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility())
                .isEqualTo(View.GONE);
        assertThat(dialog.getWindow().getAttributes().flags
                & WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
                .isEqualTo(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }

    private void launchActivity() {
        mScenario = ActivityScenario.launch(TestAccessibilityShortcutChooserActivity.class);
        mScenario.onActivity(activity -> mActivity = activity);
        mScenario.moveToState(Lifecycle.State.CREATED);
        mScenario.moveToState(Lifecycle.State.STARTED);
        mScenario.moveToState(Lifecycle.State.RESUMED);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
    }

    private void openShortcutsList() {
        UiObject2 editButton = mDevice.findObject(By.text(EDIT_LABEL));
        if (editButton != null) {
@@ -198,9 +237,13 @@ public class AccessibilityShortcutChooserActivityTest {
    public static class TestAccessibilityShortcutChooserActivity extends
            AccessibilityShortcutChooserActivity {
        private static IAccessibilityManager sAccessibilityManagerService;
        private static KeyguardManager sKeyguardManager;

        public static void setupForTesting(IAccessibilityManager accessibilityManagerService) {
        public static void setupForTesting(
                IAccessibilityManager accessibilityManagerService,
                KeyguardManager keyguardManager) {
            sAccessibilityManagerService = accessibilityManagerService;
            sKeyguardManager = keyguardManager;
        }

        @Override
@@ -210,6 +253,9 @@ public class AccessibilityShortcutChooserActivityTest {
                return new AccessibilityManager(this, new Handler(getMainLooper()),
                        sAccessibilityManagerService, /* userId= */ 0, /* serviceConnect= */ true);
            }
            if (Context.KEYGUARD_SERVICE.equals(name)) {
                return sKeyguardManager;
            }

            return super.getSystemService(name);
        }