使用指纹的锁屏解锁流程

@startuml
[-> BiometricUnlockController: onBiometricAuthenticated
BiometricUnlockController->BiometricUnlockController: startWakeAndUnlock()
BiometricUnlockController->StatusBarKeyguardViewManager:notifyKeyguardAuthenticated()
StatusBarKeyguardViewManager->KeyguardBouncer:notifyKeyguardAuthenticated
KeyguardBouncer->KeyguardHostViewController:finish
KeyguardHostViewController->SecurityCallback:finish
SecurityCallback->ViewMediatorCallback:keyguardDone(strongAuth, targetUserId)
ViewMediatorCallback->KeyguardViewMediator: tryKeyguardDone()
KeyguardViewMediator->StatusBarKeyguardViewManager:startPreHideAnimation(mHideAnimationFinishedRunnable)
StatusBarKeyguardViewManager->KeyguardViewMediator:mHideAnimationFinishedRunnable.run()
KeyguardViewMediator->KeyguardViewMediator:tryKeyguardDone()
KeyguardViewMediator->KeyguardViewMediator:handleKeyguardDone()
KeyguardViewMediator->KeyguardViewMediator:handleHide()
KeyguardViewMediator->KeyguardViewMediator: mKeyguardGoingAwayRunnable.run()
note over KeyguardViewMediator : PhoneWindowManager 将会在 AppTransition 执行结束后通知 KeyguardService
KeyguardViewMediator->KeyguardViewMediator:handleStartKeyguardExitAnimation()
KeyguardViewMediator->StatusBarKeyguardViewManager:hide()
@enduml

在这里插入图片描述

com.android.keyguard.KeyguardUpdateMonitor#onFingerprintAuthenticated

@VisibleForTesting
protected void onFingerprintAuthenticated(int userId, boolean isStrongBiometric) {
    Assert.isMainThread();
    Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
    mUserFingerprintAuthenticated.put(userId,
            new BiometricAuthenticated(true, isStrongBiometric));
    // Update/refresh trust state only if user can skip bouncer
    if (getUserCanSkipBouncer(userId)) {
        mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
    }
    // Don't send cancel if authentication succeeds
    mFingerprintCancelSignal = null;
    updateBiometricListeningState();
    for (int i = 0; i < mCallbacks.size(); i++) {
        KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
        if (cb != null) {
            cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT,
                    isStrongBiometric);//1
        }
    }

    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
            FINGERPRINT_CONTINUE_DELAY_MS);

    // Only authenticate fingerprint once when assistant is visible
    mAssistantVisible = false;

    // Report unlock with strong or non-strong biometric
    reportSuccessfulBiometricUnlock(isStrongBiometric, userId);

    Trace.endSection();
}

指纹解锁成功后,会在注释 1 处调用注册到 KeyguardUpdateMonitor 的 Callback ,其中包括:

04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.policy.KeyguardStateControllerImpl$UpdateMonitorCallback@5e3a4c1
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.keyguard.KeyguardSliceProvider$2@555416f
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.classifier.FalsingCollectorImpl$2@6d617e5
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.sonymobile.keyguard.statistics.LockscreenStatisticsFingerprintAccuracyReporter@71a354b
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.doze.DozeLog$1@3d0dc47
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.BiometricUnlockController@8f59c74
04-29 22:31:10.583 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController$1@a0a0be0
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.KeyguardIndicationController$BaseKeyguardCallback@fd4f972
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.KeyguardIndicationController$4@e68fa40
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.sonymobile.keyguard.aod.FingerPrintFeedBackView$FingerprintFBCallBack@7dda55a
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.ScrimController$KeyguardVisibilityCallback@9f98ed2
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.notification.collection.coordinator.KeyguardCoordinator$6@380d706
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.KeyguardBouncer$1@2584c90
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager$3@e4ca989
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.StatusBar$5@b421d8e
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.wmshell.WMShell$2@95f5b5a
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.wmshell.WMShell$4@977d681
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.wmshell.WMShell$7@427d326
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.NotificationPanelViewController$1@a68d435
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.statusbar.phone.KeyguardBottomAreaView$10@1c33f70
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.EmergencyButtonController$1@e1652e9
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.LockIconViewController$3@5fa7b6e
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.KeyguardStatusViewController$2@256420f
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.AnimatableClockController$4@f40e934
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.AnimatableClockController$4@7e9535d
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.biometrics.AuthRippleController$keyguardUpdateMonitorCallback$1@b0147f
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.systemui.keyguard.KeyguardViewMediator$2@3b8279e
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.KeyguardHostViewController$1@3a7df7b
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.KeyguardPINView$1@8c81870
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.KeyguardMessageAreaController$1@b44b7e9
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.EmergencyButtonController$1@3817c6e
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.CarrierTextManager$2@9a65f9a
04-29 22:31:10.584 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.CarrierTextManager$2@3d5a25a
04-29 22:31:10.585 29196 29196 D KeyguardUpdateMonitor: onFingerprintAuthenticated: com.android.keyguard.CarrierTextManager$2@4ec50f9

其中 AuthRippleController 负责绘制波澜效果
指纹解锁成功的消息通过回调传递给 BiometricUnlockController
推动 Keyguard 继续走消去流程的是 BiometricUnlockController 的 callback
com.android.systemui.statusbar.phone.BiometricUnlockController#onBiometricAuthenticated

@Override
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
        boolean isStrongBiometric) {
    Trace.beginSection("BiometricUnlockController#onBiometricAuthenticated");
    if (mUpdateMonitor.isGoingToSleep()) {
        mPendingAuthenticated = new PendingAuthenticated(userId, biometricSourceType,
                isStrongBiometric);
        Trace.endSection();
        return;
    }
    mBiometricType = biometricSourceType;
    mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
            .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
    Optional.ofNullable(BiometricUiEvent.SUCCESS_EVENT_BY_SOURCE_TYPE.get(biometricSourceType))
            .ifPresent(UI_EVENT_LOGGER::log);

    boolean unlockAllowed =
            mKeyguardStateController.isOccluded()
                    || mKeyguardBypassController.onBiometricAuthenticated(
                            biometricSourceType, isStrongBiometric);
    if (unlockAllowed) {
        mKeyguardViewMediator.userActivity();
        startWakeAndUnlock(biometricSourceType, isStrongBiometric);//1
    } else {
        Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
    }
}

在注释 1 处调用 com.android.systemui.statusbar.phone.BiometricUnlockController#startWakeAndUnlock(BiometricSourceType, boolean)

public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
        boolean isStrongBiometric) {
    startWakeAndUnlock(calculateMode(biometricSourceType, isStrongBiometric));//1
}
private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType,
        boolean isStrongBiometric) {
    if (biometricSourceType == BiometricSourceType.FACE
            || biometricSourceType == BiometricSourceType.IRIS) {
        return calculateModeForPassiveAuth(isStrongBiometric);
    } else {
        return calculateModeForFingerprint(isStrongBiometric);//2
    }
}


private @WakeAndUnlockMode int calculateModeForFingerprint(boolean isStrongBiometric) {
    boolean unlockingAllowed =
            mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
    boolean deviceDreaming = mUpdateMonitor.isDreaming();

    if (!mUpdateMonitor.isDeviceInteractive()) {
        if (!mKeyguardViewController.isShowing()) {
            return MODE_ONLY_WAKE;
        } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
            return MODE_WAKE_AND_UNLOCK_PULSING;
        } else if (unlockingAllowed || !mKeyguardStateController.isMethodSecure()) {
            return MODE_WAKE_AND_UNLOCK;
        } else {
            return MODE_SHOW_BOUNCER;
        }
    }
    if (unlockingAllowed && deviceDreaming) {
        return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
    }
    if (mKeyguardViewController.isShowing()) {
        if (mKeyguardViewController.bouncerIsOrWillBeShowing() && unlockingAllowed) {
            return MODE_DISMISS_BOUNCER;
        } else if (unlockingAllowed) {
            return MODE_UNLOCK_COLLAPSING;//3
        } else if (!mKeyguardViewController.isBouncerShowing()) {
            return MODE_SHOW_BOUNCER;
        }
    }
    return MODE_NONE;
}

屏幕点亮的时候,进行指纹解锁,log输出为 BiometricUnlockCtrl: startWakeAndUnlock(5),即 MODE_UNLOCK_COLLAPSING,该整型将作为参数传递给 com.android.systemui.statusbar.phone.BiometricUnlockController#startWakeAndUnlock(int)

public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
    Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
    boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
    mMode = mode;
    mHasScreenTurnedOnSinceAuthenticating = false;
    if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
        // If we are waking the device up while we are pulsing the clock and the
        // notifications would light up first, creating an unpleasant animation.
        // Defer changing the screen brightness by forcing doze brightness on our window
        // until the clock and the notifications are faded out.
        mNotificationShadeWindowController.setForceDozeBrightness(true);
    }
    // During wake and unlock, we need to draw black before waking up to avoid abrupt
    // brightness changes due to display state transitions.
    boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
    boolean delayWakeUp = mode == MODE_WAKE_AND_UNLOCK && alwaysOnEnabled && mWakeUpDelay > 0;
    Runnable wakeUp = ()-> {
        if (!wasDeviceInteractive) {
            if (DEBUG_BIO_WAKELOCK) {
                Log.i(TAG, "bio wakelock: Authenticated, waking up...");
            }
            mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
                    "android.policy:BIOMETRIC");
        }
        if (delayWakeUp) {
            mKeyguardViewMediator.onWakeAndUnlocking();
        }
        Trace.beginSection("release wake-and-unlock");
        releaseBiometricWakeLock();
        Trace.endSection();
    };

    if (!delayWakeUp && mMode != MODE_NONE) {
        wakeUp.run();
    }
    switch (mMode) {
        case MODE_DISMISS_BOUNCER:
        case MODE_UNLOCK_FADING:
            Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
            mKeyguardViewController.notifyKeyguardAuthenticated(
                    false /* strongAuth */);
            Trace.endSection();
            break;
        case MODE_UNLOCK_COLLAPSING:
            Trace.beginSection("MODE_UNLOCK_COLLAPSING");
            if (!wasDeviceInteractive) {
                mPendingShowBouncer = true;
            } else {
                mPendingShowBouncer = false;
                mKeyguardViewController.notifyKeyguardAuthenticated(
                        false /* strongAuth */);//1
            }
            Trace.endSection();
            break;
        case MODE_SHOW_BOUNCER:
            Trace.beginSection("MODE_SHOW_BOUNCER");
            if (!wasDeviceInteractive) {
                mPendingShowBouncer = true;
            } else {
                showBouncer();
            }
            Trace.endSection();
            break;
        case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
        case MODE_WAKE_AND_UNLOCK_PULSING:
        case MODE_WAKE_AND_UNLOCK:
            if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
                Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
                mMediaManager.updateMediaMetaData(false /* metaDataChanged */,
                        true /* allowEnterAnimation */);
            } else if (mMode == MODE_WAKE_AND_UNLOCK){
                Trace.beginSection("MODE_WAKE_AND_UNLOCK");
            } else {
                Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
                mUpdateMonitor.awakenFromDream();
            }
            mNotificationShadeWindowController.setNotificationShadeFocusable(false);
            if (delayWakeUp) {
                mHandler.postDelayed(wakeUp, mWakeUpDelay);
            } else {
                mKeyguardViewMediator.onWakeAndUnlocking();
            }
            Trace.endSection();
            break;
        case MODE_ONLY_WAKE:
        case MODE_NONE:
            break;
    }
    onModeChanged(mMode);
    if (mBiometricModeListener != null) {
        mBiometricModeListener.notifyBiometricAuthModeChanged();
    }
    Trace.endSection();
}

注释 1 处的 mKeyguardViewController 为 StatusBarKeyguardViewManager,所以该处调用了 com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager#notifyKeyguardAuthenticated

public void notifyKeyguardAuthenticated(boolean strongAuth) {
    mBouncer.notifyKeyguardAuthenticated(strongAuth);//1

    if (mAlternateAuthInterceptor != null && isShowingAlternateAuthOrAnimating()) {
        resetAlternateAuth(false);
        executeAfterKeyguardGoneAction();
    }
}

注释 1 处调了 com.android.systemui.statusbar.phone.KeyguardBouncer#notifyKeyguardAuthenticated

public void notifyKeyguardAuthenticated(boolean strongAuth) {
    ensureView();//1
    mKeyguardViewController.finish(strongAuth, KeyguardUpdateMonitor.getCurrentUser());//2 
}
protected void ensureView() {
    // Removal of the view might be deferred to reduce unlock latency,
    // in this case we need to force the removal, otherwise we'll
    // end up in an unpredictable state.
    boolean forceRemoval = mHandler.hasCallbacks(mRemoveViewRunnable);
    if (mRoot == null || forceRemoval) {
        inflateView();
    }
}

因为 mRoot 存在,所以注释 1 的代码并没有什么意义,继续注释 2 的逻辑,mKeyguardViewController 即 KeyguardHostViewController,该处调用为
com.android.keyguard.KeyguardHostViewController#finish

public void finish(boolean strongAuth, int currentUser) {
    mSecurityCallback.finish(strongAuth, currentUser);
}
//com.android.keyguard.KeyguardHostViewController#mSecurityCallback
private final SecurityCallback mSecurityCallback = new SecurityCallback() {

    @Override
    public boolean dismiss(boolean authenticated, int targetUserId,
            boolean bypassSecondaryLockScreen) {
        return mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
                authenticated, targetUserId, bypassSecondaryLockScreen);
    }

    @Override
    public void userActivity() {
        mViewMediatorCallback.userActivity();
    }

    @Override
    public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
        mViewMediatorCallback.setNeedsInput(needsInput);
    }

    /**
     * Authentication has happened and it's time to dismiss keyguard. This function
     * should clean up and inform KeyguardViewMediator.
     *
     * @param strongAuth whether the user has authenticated with strong authentication like
     *                   pattern, password or PIN but not by trust agents or fingerprint
     * @param targetUserId a user that needs to be the foreground user at the dismissal
     *                    completion.
     */
    @Override
    public void finish(boolean strongAuth, int targetUserId) {
        // If there's a pending runnable because the user interacted with a widget
        // and we're leaving keyguard, then run it.
        boolean deferKeyguardDone = false;
        if (mDismissAction != null) {
            deferKeyguardDone = mDismissAction.onDismiss();
            mDismissAction = null;
            mCancelAction = null;
        }
        if (mViewMediatorCallback != null) {
            if (deferKeyguardDone) {
                mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
            } else {
                mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);//1
            }
        }
    }

    @Override
    public void reset() {
        mViewMediatorCallback.resetKeyguard();
    }

    @Override
    public void onCancelClicked() {
        mViewMediatorCallback.onCancelClicked();
    }
};

走到注释 1 处,开始进入解锁流程 mViewMediatorCallback 来自 com.android.systemui.keyguard.KeyguardViewMediator#mViewMediatorCallback

ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {

    @Override
    public void userActivity() {
        KeyguardViewMediator.this.userActivity();
    }

    @Override
    public void keyguardDone(boolean strongAuth, int targetUserId) {
        if (targetUserId != ActivityManager.getCurrentUser()) {
            return;
        }
        if (DEBUG) Log.d(TAG, "keyguardDone");
        tryKeyguardDone();//1
    }

    @Override
    public void keyguardDoneDrawing() {
        Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDoneDrawing");
        mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
        Trace.endSection();
    }

    @Override
    public void setNeedsInput(boolean needsInput) {
        mKeyguardViewControllerLazy.get().setNeedsInput(needsInput);
    }

    @Override
    public void keyguardDonePending(boolean strongAuth, int targetUserId) {
        Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending");
        if (DEBUG) Log.d(TAG, "keyguardDonePending");
        if (targetUserId != ActivityManager.getCurrentUser()) {
            Trace.endSection();
            return;
        }

        mKeyguardDonePending = true;
        mHideAnimationRun = true;
        mHideAnimationRunning = true;
        mKeyguardViewControllerLazy.get()
                .startPreHideAnimation(mHideAnimationFinishedRunnable);
        mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
                KEYGUARD_DONE_PENDING_TIMEOUT_MS);
        Trace.endSection();
    }

    @Override
    public void keyguardGone() {
        Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardGone");
        if (DEBUG) Log.d(TAG, "keyguardGone");
        mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false);
        mKeyguardDisplayManager.hide();
        Trace.endSection();
    }

    @Override
    public void readyForKeyguardDone() {
        Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#readyForKeyguardDone");
        if (mKeyguardDonePending) {
            mKeyguardDonePending = false;
            tryKeyguardDone();
        }
        Trace.endSection();
    }

    @Override
    public void resetKeyguard() {
        resetStateLocked();
    }

    @Override
    public void onCancelClicked() {
        mKeyguardViewControllerLazy.get().onCancelClicked();
    }

    @Override
    public void onBouncerVisiblityChanged(boolean shown) {
        synchronized (KeyguardViewMediator.this) {
            adjustStatusBarLocked(shown, false);
        }
    }

    @Override
    public void playTrustedSound() {
        KeyguardViewMediator.this.playTrustedSound();
    }

    @Override
    public boolean isScreenOn() {
        return mDeviceInteractive;
    }

    @Override
    public int getBouncerPromptReason() {
        int currentUser = KeyguardUpdateMonitor.getCurrentUser();
        boolean trust = mUpdateMonitor.isTrustUsuallyManaged(currentUser);
        boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
        boolean any = trust || biometrics;
        KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
                mUpdateMonitor.getStrongAuthTracker();
        int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);

        if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
            return KeyguardSecurityView.PROMPT_REASON_RESTART;
        } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
        } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
        } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
        } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
        } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE;
        } else if (any && (strongAuth
                & STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT) != 0) {
            return KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT;
        }
        return KeyguardSecurityView.PROMPT_REASON_NONE;
    }

    @Override
    public CharSequence consumeCustomMessage() {
        final CharSequence message = mCustomMessage;
        mCustomMessage = null;
        return message;
    }
};

这里走了注释 1 的逻辑,即下一步调用了
com.android.systemui.keyguard.KeyguardViewMediator#tryKeyguardDone

private void tryKeyguardDone() {
    if (DEBUG) {
        Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - "
                + mHideAnimationRun + " animRunning - " + mHideAnimationRunning);
    }
    if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
        handleKeyguardDone();
    } else if (!mHideAnimationRun) {
        if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
        mHideAnimationRun = true; //1
        mHideAnimationRunning = true;
        mKeyguardViewControllerLazy.get()
                .startPreHideAnimation(mHideAnimationFinishedRunnable);//1
    }
}

首次调用该函数时因为 mHideAnimationRun 仍然为 false,所以走了下面的分支,首先在注释 1 处,将 mHideAnimationRun 置为 true,然后在注释 2 处开始执行播放解锁前的 hide 动画,动画播放结束后,将调用 mHideAnimationFinishedRunnable 回调
com.android.systemui.keyguard.KeyguardViewMediator#mHideAnimationFinishedRunnable

private final Runnable mHideAnimationFinishedRunnable = () -> {
    Log.e(TAG, "mHideAnimationFinishedRunnable#run");
    mHideAnimationRunning = false;
    tryKeyguardDone();//1
};

private void tryKeyguardDone() {
    if (DEBUG) {
        Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - "
                + mHideAnimationRun + " animRunning - " + mHideAnimationRunning);
    }
    if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) {
        handleKeyguardDone();//2
    } else if (!mHideAnimationRun) {
        if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
        mHideAnimationRun = true;
        mHideAnimationRunning = true;
        mKeyguardViewControllerLazy.get()
                .startPreHideAnimation(mHideAnimationFinishedRunnable);
    }
}

在 mHideAnimationFinishedRunnable 中将第二次调用 tryKeyguardDone(),这一次因为 mHideAnimationRun 在上一次调用时被置为了 true,所以走了上面的分支,即执行了注释 2 的逻辑
com.android.systemui.keyguard.KeyguardViewMediator#handleKeyguardDone

private void handleKeyguardDone() {
    Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
    final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
    mUiBgExecutor.execute(() -> {
        if (mLockPatternUtils.isSecure(currentUser)) {
            mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
        }
    });
    if (DEBUG) Log.d(TAG, "handleKeyguardDone");
    synchronized (this) {
        resetKeyguardDonePendingLocked();
    }


    if (mGoingToSleep) {
        mUpdateMonitor.clearBiometricRecognized();
        Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
        return;
    }
    if (mExitSecureCallback != null) {
        try {
            mExitSecureCallback.onKeyguardExitResult(true /* authenciated */);
        } catch (RemoteException e) {
            Slog.w(TAG, "Failed to call onKeyguardExitResult()", e);
        }

        mExitSecureCallback = null;

        // after succesfully exiting securely, no need to reshow
        // the keyguard when they've released the lock
        mExternallyEnabled = true;
        mNeedToReshowWhenReenabled = false;
        updateInputRestricted();
    }

    handleHide();//1
    mUpdateMonitor.clearBiometricRecognized();
    Trace.endSection();
}

继续在注释 1 处调用
com.android.systemui.keyguard.KeyguardViewMediator#handleHide

private void handleHide() {
    Trace.beginSection("KeyguardViewMediator#handleHide");

    // It's possible that the device was unlocked in a dream state. It's time to wake up.
    if (mAodShowing) {
        PowerManager pm = mContext.getSystemService(PowerManager.class);
        pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
                "com.android.systemui:BOUNCER_DOZING");
    }

    synchronized (KeyguardViewMediator.this) {
        if (DEBUG) Log.d(TAG, "handleHide");

        if (mustNotUnlockCurrentUser()) {
            // In split system user mode, we never unlock system user. The end user has to
            // switch to another user.
            // TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
            // still completes and makes the screen blank.
            if (DEBUG) Log.d(TAG, "Split system user, quit unlocking.");
            mKeyguardExitAnimationRunner = null;
            return;
        }
        mHiding = true;

        if (mShowing && !mOccluded) {//1
            mKeyguardGoingAwayRunnable.run();//2
        } else {
            // TODO(bc-unlock): Fill parameters
            handleStartKeyguardExitAnimation(
                    SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
                    mHideAnimation.getDuration(), null /* apps */,  null /* wallpapers */,
                    null /* nonApps */, null /* finishedCallback */);
        }
    }
    Trace.endSection();
}

此时由于锁屏界面还未消失,所以注释 1 的判断成立,走了注释 2 的逻辑
com.android.systemui.keyguard.KeyguardViewMediator#mKeyguardGoingAwayRunnable

private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
    @Override
    public void run() {
        Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
        if (DEBUG) Log.d(TAG, "keyguardGoingAway");
        mKeyguardViewControllerLazy.get().keyguardGoingAway();

        int flags = 0;
        if (mKeyguardViewControllerLazy.get().shouldDisableWindowAnimationsForUnlock()
                || (mWakeAndUnlocking && !mPulsing)
                || isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()) {
            flags |= WindowManagerPolicyConstants
                    .KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
        }
        if (mKeyguardViewControllerLazy.get().isGoingToNotificationShade()
                || (mWakeAndUnlocking && mPulsing)) {
            flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
        }
        if (mKeyguardViewControllerLazy.get().isUnlockWithWallpaper()) {
            flags |= KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
        }
        if (mKeyguardViewControllerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
            flags |= WindowManagerPolicyConstants
                    .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
        }

        mUpdateMonitor.setKeyguardGoingAway(true);
        mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(true);

        // Don't actually hide the Keyguard at the moment, wait for window
        // manager until it tells us it's safe to do so with
        // startKeyguardExitAnimation.
        // Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager will be in
        // order.
        final int keyguardFlag = flags;
        mUiBgExecutor.execute(() -> {
            try {
                ActivityTaskManager.getService().keyguardGoingAway(keyguardFlag);//1
            } catch (RemoteException e) {
                Log.e(TAG, "Error while calling WindowManager", e);
            }
        });
        Trace.endSection();
    }
};

该函数最终在注释 1 处将锁屏即将消失的信息传递给了 ATM,ATM 开始安排锁屏后面的 Activity (比如 Launcher )执行进场动画,当后面的 Activity 动画执行完,将通过回调通知锁屏,锁屏最终会调用
com.android.systemui.keyguard.KeyguardViewMediator#handleStartKeyguardExitAnimation,至此才开始处理锁屏界面消失的逻辑

private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration,
        RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
        RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
    Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
    if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
            + " fadeoutDuration=" + fadeoutDuration);
    synchronized (KeyguardViewMediator.this) {

        // Tell ActivityManager that we canceled the keyguard animation if
        // handleStartKeyguardExitAnimation was called but we're not hiding the keyguard, unless
        // we're animating the surface behind the keyguard and will be hiding the keyguard
        // shortly.
        if (!mHiding
                && !mSurfaceBehindRemoteAnimationRequested
                && !mKeyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture()) {
            if (finishedCallback != null) {
                // There will not execute animation, send a finish callback to ensure the remote
                // animation won't hanging there.
                try {
                    finishedCallback.onAnimationFinished();
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failed to call onAnimationFinished", e);
                }
            }
            setShowingLocked(mShowing, true /* force */);
            return;
        }
        mHiding = false;
        IRemoteAnimationRunner runner = mKeyguardExitAnimationRunner;
        mKeyguardExitAnimationRunner = null;

        if (mWakeAndUnlocking && mDrawnCallback != null) {

            // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
            // the next draw from here so we don't have to wait for window manager to signal
            // this to our ViewRootImpl.
            mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw();
            notifyDrawn(mDrawnCallback);
            mDrawnCallback = null;
        }

        LatencyTracker.getInstance(mContext)
                .onActionEnd(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK);

        if (KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation && runner != null
                && finishedCallback != null) {
            // Wrap finishedCallback to clean up the keyguard state once the animation is done.
            IRemoteAnimationFinishedCallback callback =
                    new IRemoteAnimationFinishedCallback() {
                        @Override
                        public void onAnimationFinished() throws RemoteException {
                            try {
                                finishedCallback.onAnimationFinished();
                            } catch (RemoteException e) {
                                Slog.w(TAG, "Failed to call onAnimationFinished", e);
                            }
                            onKeyguardExitFinished();
                            mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
                                    0 /* fadeoutDuration */);
                            InteractionJankMonitor.getInstance()
                                    .end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                        }

                        @Override
                        public IBinder asBinder() {
                            return finishedCallback.asBinder();
                        }
                    };
            try {
                InteractionJankMonitor.getInstance().begin(
                        createInteractionJankMonitorConf("RunRemoteAnimation"));
                runner.onAnimationStart(WindowManager.TRANSIT_KEYGUARD_GOING_AWAY, apps,
                        wallpapers, nonApps, callback);
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed to call onAnimationStart", e);
            }

        // When remaining on the shade, there's no need to do a fancy remote animation,
        // it will dismiss the panel in that case.
        } else if (KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation
                && !mStatusBarStateController.leaveOpenOnKeyguardHide()
                && apps != null && apps.length > 0) {
            mSurfaceBehindRemoteAnimationFinishedCallback = finishedCallback;
            mSurfaceBehindRemoteAnimationRunning = true;

            InteractionJankMonitor.getInstance().begin(
                    createInteractionJankMonitorConf("DismissPanel"));

            // Pass the surface and metadata to the unlock animation controller.
            mKeyguardUnlockAnimationControllerLazy.get().notifyStartKeyguardExitAnimation(
                    apps[0], startTime, mSurfaceBehindRemoteAnimationRequested);
        } else {
            InteractionJankMonitor.getInstance().begin(
                    createInteractionJankMonitorConf("RemoteAnimationDisabled"));

            mKeyguardViewControllerLazy.get().hide(startTime, fadeoutDuration);//1

            // TODO(bc-animation): When remote animation is enabled for keyguard exit animation,
            // apps, wallpapers and finishedCallback are set to non-null. nonApps is not yet
            // supported, so it's always null.
            mContext.getMainExecutor().execute(() -> {
                if (finishedCallback == null) {
                    InteractionJankMonitor.getInstance().end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                    return;
                }

                // TODO(bc-unlock): Sample animation, just to apply alpha animation on the app.
                final SyncRtSurfaceTransactionApplier applier =
                        new SyncRtSurfaceTransactionApplier(
                                mKeyguardViewControllerLazy.get().getViewRootImpl().getView());
                final RemoteAnimationTarget primary = apps[0];
                ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
                anim.setDuration(400 /* duration */);
                anim.setInterpolator(Interpolators.LINEAR);
                anim.addUpdateListener((ValueAnimator animation) -> {
                    SyncRtSurfaceTransactionApplier.SurfaceParams params =
                            new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
                                    primary.leash)
                                    .withAlpha(animation.getAnimatedFraction())
                                    .build();
                    applier.scheduleApply(params);
                });
                anim.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        try {
                            finishedCallback.onAnimationFinished();
                        } catch (RemoteException e) {
                            Slog.e(TAG, "RemoteException");
                        } finally {
                            InteractionJankMonitor.getInstance()
                                    .end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                        }
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        try {
                            finishedCallback.onAnimationFinished();
                        } catch (RemoteException e) {
                            Slog.e(TAG, "RemoteException");
                        } finally {
                            InteractionJankMonitor.getInstance()
                                    .cancel(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                        }
                    }
                });
                anim.start();
            });

            onKeyguardExitFinished();
        }
    }

    Trace.endSection();
}

注释 1 控制锁屏的界面的渐变与消失
com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager#hide

public void hide(long startTime, long fadeoutDuration) {
    mShowing = false;
    mKeyguardStateController.notifyKeyguardState(mShowing,
            mKeyguardStateController.isOccluded());
    launchPendingWakeupAction();

    if (mKeyguardUpdateManager.needsSlowUnlockTransition()) {
        fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
    }
    long uptimeMillis = SystemClock.uptimeMillis();
    long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);

    if (mStatusBar.isInLaunchTransition()
            || mKeyguardStateController.isFlingingToDismissKeyguard()) {// 注释 1
        final boolean wasFlingingToDismissKeyguard =
                mKeyguardStateController.isFlingingToDismissKeyguard();
        mStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
            @Override
            public void run() {
                mNotificationShadeWindowController.setKeyguardShowing(false);
                mNotificationShadeWindowController.setKeyguardFadingAway(true);
                hideBouncer(true /* destroyView */);
                updateStates();
            }
        }, new Runnable() {
            @Override
            public void run() {
                mStatusBar.hideKeyguard();
                mNotificationShadeWindowController.setKeyguardFadingAway(false);

                if (wasFlingingToDismissKeyguard) {
                    mStatusBar.finishKeyguardFadingAway();
                }

                mViewMediatorCallback.keyguardGone();
                executeAfterKeyguardGoneAction();
            }
        });
    } else {
        executeAfterKeyguardGoneAction();
        boolean wakeUnlockPulsing =
                mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING;
        boolean needsFading = needsBypassFading();
        if (needsFading) {
            delay = 0;
            fadeoutDuration = KeyguardBypassController.BYPASS_FADE_DURATION;
        } else if (wakeUnlockPulsing) {
            delay = 0;
            fadeoutDuration = 240;
        }
        mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration, needsFading);
        mBiometricUnlockController.startKeyguardFadingAway();
        hideBouncer(true /* destroyView */); //注释2
        if (wakeUnlockPulsing) {// 注释 3
            if (needsFading) {
                ViewGroupFadeHelper.fadeOutAllChildrenExcept(
                        mNotificationPanelViewController.getView(),
                        mNotificationContainer,
                        fadeoutDuration,
                                () -> {
                    mStatusBar.hideKeyguard();
                    onKeyguardFadedAway();
                });
            } else {
                mStatusBar.fadeKeyguardWhilePulsing();
            }
            wakeAndUnlockDejank();
        } else {
            boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
            if (!staying) {
                mNotificationShadeWindowController.setKeyguardFadingAway(true);
                if (needsFading) {
                    ViewGroupFadeHelper.fadeOutAllChildrenExcept(
                            mNotificationPanelViewController.getView(),
                            mNotificationContainer,
                            fadeoutDuration,
                            () -> {
                                mStatusBar.hideKeyguard();
                            });
                } else {
                    mStatusBar.hideKeyguard(); // 注释4
                }
                // hide() will happen asynchronously and might arrive after the scrims
                // were already hidden, this means that the transition callback won't
                // be triggered anymore and StatusBarWindowController will be forever in
                // the fadingAway state.
                mStatusBar.updateScrimController();
                wakeAndUnlockDejank();
            } else {
                mStatusBar.hideKeyguard();
                mStatusBar.finishKeyguardFadingAway();
                mBiometricUnlockController.finishKeyguardFadingAway();
            }
        }
        updateStates(); // 注释5
        mNotificationShadeWindowController.setKeyguardShowing(false);
        mViewMediatorCallback.keyguardGone();
    }
    SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
            SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__HIDDEN);
}

注释 1 的判断语句不成立,所以走 else 流程,调用注释 2 处的代码移除 bouncer view。随后,由于注释 3 处的条件也不成立,走 else 流程,最终走到注释 4 将通知与桌面时钟隐藏。最后调用注释 5 更新 Keyguard 的状态

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值