diff options
| author | 2023-10-07 00:24:13 +0000 | |
|---|---|---|
| committer | 2023-10-10 18:47:58 +0000 | |
| commit | 4623b566e5b2d4091dc562109d6c9a15c730d821 (patch) | |
| tree | 2ed2828ae9136fe71fe6f06b6b1bc10f54d4aad9 | |
| parent | 7ddc262b184e5dc47026e08e0fb276bbf1ea49ea (diff) | |
Allows the a11y volume shortcut disambig dialog to show on lock screen.
The edit button is not shown when the dialog is triggerred while on the
lock screen, to prevent editing shortcuts while the device is locked.
Bug: 303871725
Test: Set up 2+ features with volume key shortcut. Press power button to
go to lockscreen. Trigger the volume key shortcut. Observe dialog
appears without edit option.
Test: atest AccessibilityShortcutChooserActivityTest
Change-Id: Ia2ec0f9d01ffff0d51d23b491d55ef84d575f09d
3 files changed, 87 insertions, 12 deletions
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig index e31ad82d3f55..85dadd4a061d 100644 --- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig +++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig @@ -5,4 +5,11 @@ flag { name: "force_invert_color" description: "Enable force force-dark for smart inversion and dark theme everywhere" bug: "282821643" -}
\ No newline at end of file +} + +flag { + namespace: "accessibility" + name: "allow_shortcut_chooser_on_lockscreen" + description: "Allows the a11y shortcut disambig dialog to appear on the lockscreen" + bug: "303871725" +} diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java index 5dd558a5f850..987c14c6ab51 100644 --- a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java @@ -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; } } diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java index 681ba9c353e5..06b62f85bede 100644 --- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java @@ -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; @@ -90,6 +100,9 @@ public class AccessibilityShortcutChooserActivityTest { private TestAccessibilityShortcutChooserActivity mActivity; @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Mock private AccessibilityServiceInfo mAccessibilityServiceInfo; @@ -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); } |