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

Commit 5c34b983 authored by Josh Tsuji's avatar Josh Tsuji Committed by Android (Google) Code Review
Browse files

Merge "Lock during user switch to secure user during keyguard going away." into main

parents 3088c286 c2bfff3f
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -25,10 +25,13 @@ import android.view.IRemoteAnimationFinishedCallback
import android.view.RemoteAnimationTarget
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.WindowManagerLockscreenVisibilityManager
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardShowWhileAwakeInteractor
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import com.android.window.flags.Flags
@@ -63,6 +66,9 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
    @Mock
    private lateinit var keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor
    @Mock private lateinit var keyguardTransitions: KeyguardTransitions
    @Mock private lateinit var lockPatternUtils: LockPatternUtils
    @Mock private lateinit var keyguardShowWhileAwakeInteractor: KeyguardShowWhileAwakeInteractor
    @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor

    @Before
    fun setUp() {
@@ -77,6 +83,9 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
                keyguardSurfaceBehindAnimator = keyguardSurfaceBehindAnimator,
                keyguardDismissTransitionInteractor = keyguardDismissTransitionInteractor,
                keyguardTransitions = keyguardTransitions,
                selectedUserInteractor = selectedUserInteractor,
                lockPatternUtils = lockPatternUtils,
                keyguardShowWhileAwakeInteractor = keyguardShowWhileAwakeInteractor,
            )
    }

@@ -236,6 +245,8 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
            .whenever(keyguardDismissTransitionInteractor)
            .startDismissKeyguardTransition(any(), any())

        whenever(selectedUserInteractor.getSelectedUserId()).thenReturn(-1)

        underTest.onKeyguardGoingAwayRemoteAnimationStart(
            transit = 0,
            apps = arrayOf(mock<RemoteAnimationTarget>()),
+5 −4
Original line number Diff line number Diff line
@@ -124,7 +124,6 @@ import com.android.settingslib.Utils;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dumpable;
import com.android.systemui.Flags;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
@@ -301,7 +300,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, CoreSt
    private final Provider<SceneInteractor> mSceneInteractor;
    private final Provider<AlternateBouncerInteractor> mAlternateBouncerInteractor;
    private final Provider<CommunalSceneInteractor> mCommunalSceneInteractor;
    private final KeyguardServiceShowLockscreenInteractor mKeyguardServiceShowLockscreenInteractor;
    private final Provider<KeyguardServiceShowLockscreenInteractor>
            mKeyguardServiceShowLockscreenInteractor;
    private final AuthController mAuthController;
    private final UiEventLogger mUiEventLogger;
    private final Set<String> mAllowFingerprintOnOccludingActivitiesFromPackage;
@@ -2219,7 +2219,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, CoreSt
            Provider<JavaAdapter> javaAdapter,
            Provider<SceneInteractor> sceneInteractor,
            Provider<CommunalSceneInteractor> communalSceneInteractor,
            KeyguardServiceShowLockscreenInteractor keyguardServiceShowLockscreenInteractor) {
            Provider<KeyguardServiceShowLockscreenInteractor>
                    keyguardServiceShowLockscreenInteractor) {
        mContext = context;
        mSubscriptionManager = subscriptionManager;
        mUserTracker = userTracker;
@@ -2553,7 +2554,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, CoreSt

        if (KeyguardWmStateRefactor.isEnabled()) {
            mJavaAdapter.get().alwaysCollectFlow(
                    mKeyguardServiceShowLockscreenInteractor.getShowNowEvents(),
                    mKeyguardServiceShowLockscreenInteractor.get().getShowNowEvents(),
                    this::onKeyguardServiceShowLockscreenNowEvents
            );
        }
+2 −1
Original line number Diff line number Diff line
@@ -673,7 +673,8 @@ public class KeyguardService extends Service {
            if (SceneContainerFlag.isEnabled()) {
                mDeviceEntryInteractorLazy.get().lockNow("doKeyguardTimeout");
            } else if (KeyguardWmStateRefactor.isEnabled()) {
                mKeyguardServiceShowLockscreenInteractor.onKeyguardServiceDoKeyguardTimeout();
                mKeyguardServiceShowLockscreenInteractor
                        .onKeyguardServiceDoKeyguardTimeout(options);
            }

            mKeyguardViewMediator.doKeyguardTimeout(options);
+52 −4
Original line number Diff line number Diff line
@@ -22,11 +22,14 @@ import android.util.Log
import android.view.IRemoteAnimationFinishedCallback
import android.view.RemoteAnimationTarget
import android.view.WindowManager
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardShowWhileAwakeInteractor
import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.window.flags.Flags
import com.android.wm.shell.keyguard.KeyguardTransitions
import java.util.concurrent.Executor
@@ -46,6 +49,9 @@ constructor(
    private val keyguardSurfaceBehindAnimator: KeyguardSurfaceBehindParamsApplier,
    private val keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor,
    private val keyguardTransitions: KeyguardTransitions,
    private val selectedUserInteractor: SelectedUserInteractor,
    private val lockPatternUtils: LockPatternUtils,
    private val keyguardShowWhileAwakeInteractor: KeyguardShowWhileAwakeInteractor,
) {

    /**
@@ -92,12 +98,23 @@ constructor(
     *   second timeout).
     */
    private var isKeyguardGoingAway = false
        private set(value) {
        private set(goingAway) {
            // TODO(b/278086361): Extricate the keyguard state controller.
            keyguardStateController.notifyKeyguardGoingAway(value)
            field = value
            keyguardStateController.notifyKeyguardGoingAway(goingAway)

            if (goingAway) {
                keyguardGoingAwayRequestedForUserId = selectedUserInteractor.getSelectedUserId()
            }

            field = goingAway
        }

    /**
     * The current user ID when we asked WM to start the keyguard going away animation. This is used
     * for validation when user switching occurs during unlock.
     */
    private var keyguardGoingAwayRequestedForUserId: Int = -1

    /** Callback provided by WM to call once we're done with the going away animation. */
    private var goingAwayRemoteAnimationFinishedCallback: IRemoteAnimationFinishedCallback? = null

@@ -171,6 +188,14 @@ constructor(
        nonApps: Array<RemoteAnimationTarget>,
        finishedCallback: IRemoteAnimationFinishedCallback,
    ) {
        goingAwayRemoteAnimationFinishedCallback = finishedCallback

        if (maybeStartTransitionIfUserSwitchedDuringGoingAway()) {
            Log.d(TAG, "User switched during keyguard going away - ending remote animation.")
            endKeyguardGoingAwayAnimation()
            return
        }

        // If we weren't expecting the keyguard to be going away, WM triggered this transition.
        if (!isKeyguardGoingAway) {
            // Since WM triggered this, we're likely not transitioning to GONE yet. See if we can
@@ -198,7 +223,6 @@ constructor(
        }

        if (apps.isNotEmpty()) {
            goingAwayRemoteAnimationFinishedCallback = finishedCallback
            keyguardSurfaceBehindAnimator.applyParamsToSurface(apps[0])
        } else {
            // Nothing to do here if we have no apps, end the animation, which will cancel it and WM
@@ -211,6 +235,7 @@ constructor(
        // If WM cancelled the animation, we need to end immediately even if we're still using the
        // animation.
        endKeyguardGoingAwayAnimation()
        maybeStartTransitionIfUserSwitchedDuringGoingAway()
    }

    /**
@@ -301,6 +326,29 @@ constructor(
        }
    }

    /**
     * If necessary, start a transition to show/hide keyguard in response to a user switch during
     * keyguard going away.
     *
     * Returns [true] if a transition was started, or false if a transition was not necessary.
     */
    private fun maybeStartTransitionIfUserSwitchedDuringGoingAway(): Boolean {
        val currentUser = selectedUserInteractor.getSelectedUserId()
        if (currentUser != keyguardGoingAwayRequestedForUserId) {
            if (lockPatternUtils.isSecure(currentUser)) {
                keyguardShowWhileAwakeInteractor.onSwitchedToSecureUserWhileKeyguardGoingAway()
            } else {
                keyguardDismissTransitionInteractor.startDismissKeyguardTransition(
                    reason = "User switch during keyguard going away, and new user is insecure"
                )
            }

            return true
        } else {
            return false
        }
    }

    companion object {
        private val TAG = "WindowManagerLsVis"
    }
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.data.repository

import android.os.IRemoteCallback
import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject

/**
 * Holds an IRemoteCallback along with the current user ID at the time the callback was provided.
 */
data class ShowLockscreenCallback(val userId: Int, val remoteCallback: IRemoteCallback)

/** Maintains state related to KeyguardService requests to show the lockscreen. */
@SysUISingleton
class KeyguardServiceShowLockscreenRepository @Inject constructor() {
    val showLockscreenCallbacks = ArrayList<ShowLockscreenCallback>()

    /**
     * Adds a callback that we'll notify when we show the lockscreen (or affirmatively decide not to
     * show it).
     */
    fun addShowLockscreenCallback(forUser: Int, callback: IRemoteCallback) {
        synchronized(showLockscreenCallbacks) {
            showLockscreenCallbacks.add(ShowLockscreenCallback(forUser, callback))
        }
    }

    companion object {
        private const val TAG = "ShowLockscreenRepository"
    }
}
Loading