Merge "Added condition to prevent menu from opening while screen is locked" into udc-dev

This commit is contained in:
Riley Jones
2023-04-18 19:05:25 +00:00
committed by Android (Google) Code Review
2 changed files with 81 additions and 22 deletions

View File

@@ -19,6 +19,7 @@ package com.android.systemui.accessibility.accessibilitymenu;
import android.Manifest;
import android.accessibilityservice.AccessibilityButtonController;
import android.accessibilityservice.AccessibilityService;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -82,6 +83,9 @@ public class AccessibilityMenuService extends AccessibilityService
// TODO(b/136716947): Support multi-display once a11y framework side is ready.
private DisplayManager mDisplayManager;
private KeyguardManager mKeyguardManager;
private final DisplayManager.DisplayListener mDisplayListener =
new DisplayManager.DisplayListener() {
int mRotation;
@@ -114,7 +118,7 @@ public class AccessibilityMenuService extends AccessibilityService
private final BroadcastReceiver mToggleMenuReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mA11yMenuLayout.toggleVisibility();
toggleVisibility();
}
};
@@ -159,10 +163,7 @@ public class AccessibilityMenuService extends AccessibilityService
*/
@Override
public void onClicked(AccessibilityButtonController controller) {
if (SystemClock.uptimeMillis() - mLastTimeTouchedOutside
> BUTTON_CLICK_TIMEOUT) {
mA11yMenuLayout.toggleVisibility();
}
toggleVisibility();
}
/**
@@ -209,6 +210,7 @@ public class AccessibilityMenuService extends AccessibilityService
mDisplayManager = getSystemService(DisplayManager.class);
mDisplayManager.registerDisplayListener(mDisplayListener, null);
mAudioManager = getSystemService(AudioManager.class);
mKeyguardManager = getSystemService(KeyguardManager.class);
sInitialized = true;
}
@@ -379,4 +381,12 @@ public class AccessibilityMenuService extends AccessibilityService
}
return false;
}
private void toggleVisibility() {
boolean locked = mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
if (!locked && SystemClock.uptimeMillis() - mLastTimeTouchedOutside
> BUTTON_CLICK_TIMEOUT) {
mA11yMenuLayout.toggleVisibility();
}
}
}

View File

@@ -33,6 +33,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.app.UiAutomation;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -44,6 +45,7 @@ import android.media.AudioManager;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -69,15 +71,19 @@ public class AccessibilityMenuServiceTest {
private static final int CLICK_ID = AccessibilityNodeInfo.ACTION_CLICK;
private static final int TIMEOUT_SERVICE_STATUS_CHANGE_S = 5;
private static final int TIMEOUT_UI_CHANGE_S = 10;
private static final int TIMEOUT_UI_CHANGE_S = 5;
private static final int NO_GLOBAL_ACTION = -1;
private static final String INPUT_KEYEVENT_KEYCODE_BACK = "input keyevent KEYCODE_BACK";
private static final String TEST_PIN = "1234";
private static Instrumentation sInstrumentation;
private static UiAutomation sUiAutomation;
private static AtomicInteger sLastGlobalAction;
private static AccessibilityManager sAccessibilityManager;
private static PowerManager sPowerManager;
private static KeyguardManager sKeyguardManager;
private static DisplayManager sDisplayManager;
@BeforeClass
public static void classSetup() throws Throwable {
@@ -85,8 +91,14 @@ public class AccessibilityMenuServiceTest {
sInstrumentation = InstrumentationRegistry.getInstrumentation();
sUiAutomation = sInstrumentation.getUiAutomation(
UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
sUiAutomation.adoptShellPermissionIdentity(
UiAutomation.ALL_PERMISSIONS.toArray(new String[0]));
final Context context = sInstrumentation.getTargetContext();
sAccessibilityManager = context.getSystemService(AccessibilityManager.class);
sPowerManager = context.getSystemService(PowerManager.class);
sKeyguardManager = context.getSystemService(KeyguardManager.class);
sDisplayManager = context.getSystemService(DisplayManager.class);
// Disable all a11yServices if any are active.
if (!sAccessibilityManager.getEnabledAccessibilityServiceList(
@@ -123,12 +135,16 @@ public class AccessibilityMenuServiceTest {
@AfterClass
public static void classTeardown() throws Throwable {
clearPin();
Settings.Secure.putString(sInstrumentation.getTargetContext().getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
}
@Before
public void setup() throws Throwable {
clearPin();
wakeUpScreen();
sUiAutomation.executeShellCommand("input keyevent KEYCODE_MENU");
openMenu();
}
@@ -138,11 +154,43 @@ public class AccessibilityMenuServiceTest {
sLastGlobalAction.set(NO_GLOBAL_ACTION);
}
private static void clearPin() throws Throwable {
sUiAutomation.executeShellCommand("locksettings clear --old " + TEST_PIN);
TestUtils.waitUntil("Device did not register as unlocked & insecure.",
TIMEOUT_SERVICE_STATUS_CHANGE_S,
() -> !sKeyguardManager.isDeviceSecure());
}
private static void setPin() throws Throwable {
sUiAutomation.executeShellCommand("locksettings set-pin " + TEST_PIN);
TestUtils.waitUntil("Device did not recognize as locked & secure.",
TIMEOUT_SERVICE_STATUS_CHANGE_S,
() -> sKeyguardManager.isDeviceSecure());
}
private static boolean isMenuVisible() {
AccessibilityNodeInfo root = sUiAutomation.getRootInActiveWindow();
return root != null && root.getPackageName().toString().equals(PACKAGE_NAME);
}
private static void wakeUpScreen() throws Throwable {
sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
TestUtils.waitUntil("Screen did not wake up.",
TIMEOUT_UI_CHANGE_S,
() -> sPowerManager.isInteractive());
}
private static void closeScreen() throws Throwable {
Display display = sDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
setPin();
sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
TestUtils.waitUntil("Screen did not close.",
TIMEOUT_UI_CHANGE_S,
() -> !sPowerManager.isInteractive()
&& display.getState() == Display.STATE_OFF
);
}
private static void openMenu() throws Throwable {
Intent intent = new Intent(PACKAGE_NAME + INTENT_TOGGLE_MENU);
sInstrumentation.getContext().sendBroadcast(intent);
@@ -381,23 +429,24 @@ public class AccessibilityMenuServiceTest {
@Test
public void testOnScreenLock_closesMenu() throws Throwable {
openMenu();
Context context = sInstrumentation.getTargetContext();
PowerManager powerManager = context.getSystemService(PowerManager.class);
assertThat(powerManager).isNotNull();
assertThat(powerManager.isInteractive()).isTrue();
sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
TestUtils.waitUntil("Screen did not become locked",
TIMEOUT_UI_CHANGE_S,
() -> !powerManager.isInteractive());
sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
TestUtils.waitUntil("Screen did not wake up",
TIMEOUT_UI_CHANGE_S,
() -> powerManager.isInteractive());
closeScreen();
wakeUpScreen();
assertThat(isMenuVisible()).isFalse();
}
@Test
public void testOnScreenLock_cannotOpenMenu() throws Throwable {
closeScreen();
wakeUpScreen();
boolean timedOut = false;
try {
openMenu();
} catch (AssertionError e) {
// Expected
timedOut = true;
}
assertThat(timedOut).isTrue();
}
}