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

Commit a7b710fe authored by Maria Petrisor's avatar Maria Petrisor
Browse files

Add Lock global action to Power Menu

Add a Lock Power Menu action that does not require strong auth, as
opposed on the Lockdown action. This enables users to unlock with
fingerprint, for example. The new Lock action will only be applied
on desktop devices (via the desktop config.xml), where it will
replace the Lockdown button.

Bug: 393319004
Test: atest GlobalActionsDialogLiteTest
Test: manual verification on desktop device
Flag: NONE. The global action will only be configured for desktop
Change-Id: Idd124491c6b1ccf1368726b96b37974949e7d34b
parent 73d957e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3883,6 +3883,7 @@
         "users" = list of users
         "restart" = restart device
         "emergency" = Launch emergency dialer
         "lock" = Lock device without requiring strong authentication
         "lockdown" = Lock down device until the user authenticates
         "logout" =  Logout the current user
         "system_update" = Launch System Update screen
+3 −0
Original line number Diff line number Diff line
@@ -867,6 +867,9 @@
    <!-- label for item that locks the phone and enforces that it can't be unlocked without strong authentication. [CHAR LIMIT=24] -->
    <string name="global_action_lockdown">Lockdown</string>
    <!-- label for item in phone options dialog that locks the phone and doesn't enforce unlocking with strong authentication. [CHAR LIMIT=24] -->
    <string name="global_action_unrestricted_lock">Lock</string>
    <!-- @deprecated No longer used. -->
    <string name="status_bar_notification_info_overflow">999+</string>
+1 −0
Original line number Diff line number Diff line
@@ -1993,6 +1993,7 @@
  <java-symbol type="string" name="global_action_silent_mode_on_status" />
  <java-symbol type="string" name="global_action_toggle_silent_mode" />
  <java-symbol type="string" name="global_action_lockdown" />
  <java-symbol type="string" name="global_action_unrestricted_lock" />
  <java-symbol type="string" name="global_action_voice_assist" />
  <java-symbol type="string" name="global_action_assist" />
  <java-symbol type="string" name="global_action_screenshot" />
+46 −1
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
    private static final String GLOBAL_ACTION_KEY_USERS = "users";
    private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
    static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
    static final String GLOBAL_ACTION_KEY_LOCK = "lock";
    private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
    private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
    static final String GLOBAL_ACTION_KEY_RESTART = "restart";
@@ -359,7 +360,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
        GA_CLOSE_TIMEOUT(2148),

        @UiEvent(doc = "The global actions standby button was pressed.")
        GA_STANDBY_PRESS(2210);
        GA_STANDBY_PRESS(2210),

        @UiEvent(doc = "The global actions lock button was pressed.")
        GA_LOCK_PRESS(2402);

        private final int mId;

@@ -711,6 +715,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
                if (shouldDisplayLockdown(currentUser.get())) {
                    addIfShouldShowAction(tempActions, new LockDownAction());
                }
            } else if (GLOBAL_ACTION_KEY_LOCK.equals(actionKey)) {
                addIfShouldShowAction(tempActions, new LockAction());
            } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) {
                addIfShouldShowAction(tempActions, getVoiceAssistAction());
            } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {
@@ -1438,6 +1444,45 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
        }
    }

    @VisibleForTesting
    class LockAction extends SinglePressAction {
        LockAction() {
            super(com.android.systemui.res.R.drawable.ic_global_actions_lockdown,
                    R.string.global_action_unrestricted_lock);
        }

        @Override
        public void onPress() {
            mLockPatternUtils.requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, UserHandle.USER_ALL);

            mUiEventLogger.log(GlobalActionsEvent.GA_LOCK_PRESS);
            try {
                mIWindowManager.lockNow(null);
                // Lock profiles (if any) on the background thread.
                mBackgroundExecutor.execute(() -> lockProfiles());
            } catch (RemoteException e) {
                Log.e(TAG, "Error while trying to lock device.", e);
            }
        }

        @Override
        public boolean showDuringKeyguard() {
            return false;
        }

        @Override
        public boolean showBeforeProvisioning() {
            return false;
        }

        @Override
        public boolean shouldShow() {
            // Only show the lock button when the device can show a lock screen.
            return mKeyguardStateController.isMethodSecure();
        }
    }


    private void lockProfiles() {
        final int currentUserId = getCurrentUser().id;
        final int[] profileIds = mUserManager.getEnabledProfileIds(currentUserId);
+120 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -991,6 +992,125 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
        dialog.dismiss();
    }

    @Test
    public void testShouldLogLockPress() {
        GlobalActionsDialogLite.LockAction lockAction =
                mGlobalActionsDialogLite.new LockAction();
        lockAction.onPress();
        verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_LOCK_PRESS);
    }

    @Test
    public void testCreateActionItems_lockEnabled_doesShowLock() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
        doReturn(true).when(mKeyguardStateController).isMethodSecure();
        doCallRealMethod()
                .when(mGlobalActionsDialogLite)
                .shouldShowAction(any(GlobalActionsDialogLite.LockAction.class));
        String[] actions = {
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCK,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();

        mGlobalActionsDialogLite.showOrHideDialog(
            /* keyguardShowing= */ false,
            /* isDeviceProvisioned= */ true,
            /* expandable= */ null,
            /* displayId= */ Display.DEFAULT_DISPLAY);

        assertItemsOfType(mGlobalActionsDialogLite.mItems,
                GlobalActionsDialogLite.EmergencyAction.class,
                GlobalActionsDialogLite.LockAction.class,
                GlobalActionsDialogLite.ShutDownAction.class,
                GlobalActionsDialogLite.RestartAction.class);
    }

    @Test
    public void testCreateActionItems_keyguardShowing_doesNotShowLock() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
        doReturn(true).when(mKeyguardStateController).isMethodSecure();
        doCallRealMethod()
                .when(mGlobalActionsDialogLite)
                .shouldShowAction(any(GlobalActionsDialogLite.LockAction.class));
        String[] actions = {
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCK,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();

        mGlobalActionsDialogLite.showOrHideDialog(
            /* keyguardShowing= */ true,
            /* isDeviceProvisioned= */ true,
            /* expandable= */ null,
            /* displayId= */ Display.DEFAULT_DISPLAY);

        assertNoItemsOfType(mGlobalActionsDialogLite.mItems,
                GlobalActionsDialogLite.LockAction.class);
    }

    @Test
    public void testCreateActionItems_deviceNotProvisioned_doesNotShowLock() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
        doReturn(true).when(mKeyguardStateController).isMethodSecure();
        doCallRealMethod()
                .when(mGlobalActionsDialogLite)
                .shouldShowAction(any(GlobalActionsDialogLite.LockAction.class));
        String[] actions = {
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCK,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();

        mGlobalActionsDialogLite.showOrHideDialog(
            /* keyguardShowing= */ false,
            /* isDeviceProvisioned= */ false,
            /* expandable= */ null,
            /* displayId= */ Display.DEFAULT_DISPLAY);

        assertNoItemsOfType(mGlobalActionsDialogLite.mItems,
                GlobalActionsDialogLite.LockAction.class);
    }

    @Test
    public void testCreateActionItems_noLockScreen_doesNotShowLock() {
        mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
        doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
        doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayEmergency();
        doReturn(false).when(mKeyguardStateController).isMethodSecure();
        doCallRealMethod()
                .when(mGlobalActionsDialogLite)
                .shouldShowAction(any(GlobalActionsDialogLite.LockAction.class));
        String[] actions = {
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCK,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
        };
        doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();

        mGlobalActionsDialogLite.showOrHideDialog(
            /* keyguardShowing= */ false,
            /* isDeviceProvisioned= */ true,
            /* expandable= */ null,
            /* displayId= */ Display.DEFAULT_DISPLAY);

        assertNoItemsOfType(mGlobalActionsDialogLite.mItems,
                GlobalActionsDialogLite.LockAction.class);
    }

    private UserInfo mockCurrentUser(int flags) {
        return new UserInfo(10, "A User", flags);