• 使用指纹的锁屏解锁流程


    @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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    指纹解锁成功后,会在注释 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    其中 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

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

    public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
            boolean isStrongBiometric) {
        startWakeAndUnlock(calculateMode(biometricSourceType, isStrongBiometric));//1
    }
    
    • 1
    • 2
    • 3
    • 4
    private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType,
            boolean isStrongBiometric) {
        if (biometricSourceType == BiometricSourceType.FACE
                || biometricSourceType == BiometricSourceType.IRIS) {
            return calculateModeForPassiveAuth(isStrongBiometric);
        } else {
            return calculateModeForFingerprint(isStrongBiometric);//2
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    屏幕点亮的时候,进行指纹解锁,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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    注释 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    public void notifyKeyguardAuthenticated(boolean strongAuth) {
        ensureView();//1
        mKeyguardViewController.finish(strongAuth, KeyguardUpdateMonitor.getCurrentUser());//2 
    }
    
    • 1
    • 2
    • 3
    • 4
    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    public void finish(boolean strongAuth, int currentUser) {
        mSecurityCallback.finish(strongAuth, currentUser);
    }
    
    • 1
    • 2
    • 3
    //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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    走到注释 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129

    这里走了注释 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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    首次调用该函数时因为 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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    继续在注释 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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    此时由于锁屏界面还未消失,所以注释 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    该函数最终在注释 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156

    注释 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

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

  • 相关阅读:
    大学生餐饮主题网页制作 美食网页设计模板 学生静态网页作业成品 dreamweaver美食甜品蛋糕HTML网站制作
    spring data JPA 学习
    计算机毕业设计SSM电力公司员工安全培训系统【附源码数据库】
    加油站智能视频监控系统方案
    C#WinFrom下载本地文件
    PageRank(上):数据分析 | 数据挖掘 | 十大算法之一
    2023年【煤炭生产经营单位(安全生产管理人员)】证考试及煤炭生产经营单位(安全生产管理人员)模拟考试题库
    ArcObjects SDK开发 007 自定义App-Command-Tool框架
    运算符
    大一html5期末大作业 :基于html实现传统文化网页设计题材
  • 原文地址:https://blog.csdn.net/lzs781/article/details/127401036