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

Commit 3971240a authored by Riley Jones's avatar Riley Jones
Browse files

Added condition to prevent menu from opening while screen is locked

Bug: 277299298
Test: install apk, atest AccessibilityMenuServiceTests
Change-Id: I5436b4ff12d4b7a421f2d739e790a02652e0d258
parent 2bd76f57
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -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();
        }
    }
}
+65 −16
Original line number Diff line number Diff line
@@ -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();
        closeScreen();
        wakeUpScreen();

        sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
        TestUtils.waitUntil("Screen did not become locked",
                TIMEOUT_UI_CHANGE_S,
                () -> !powerManager.isInteractive());
        assertThat(isMenuVisible()).isFalse();
    }

        sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
        TestUtils.waitUntil("Screen did not wake up",
                TIMEOUT_UI_CHANGE_S,
                () -> powerManager.isInteractive());
    @Test
    public void testOnScreenLock_cannotOpenMenu() throws Throwable {
        closeScreen();
        wakeUpScreen();

        assertThat(isMenuVisible()).isFalse();
        boolean timedOut = false;
        try {
            openMenu();
        } catch (AssertionError e) {
            // Expected
            timedOut = true;
        }
        assertThat(timedOut).isTrue();
    }
}