[Android]Keyguard 相关代码调用流程梳理

System UI

1.Introduction

1.0 注

梳理SystemUI - keyguard相关的代码执行流程,这里只梳理了一些关键方法的调用路径,可以提供一个参考,由于已经离职换了工作方向,相关的东西不会再有后续了~~

1.1 System UI

SystemUI: Android的系统界面,它包括了界面上方的状态栏status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard,电源界面PowerUI,近期任务界面Recent Task等。

1.2 代码路径

<source-code-path>/framework/base/packages/SystemUI

1.3 具体实现

  • Status Bar 系统上方的状态栏
  • Navigator Bar 系统下方的导航栏
  • Keyguard 锁屏界面
  • PowerUI 电源界面
  • Recents Screen 近期任务界面
  • VolumeUI 音量调节对话框
  • Stack Divider 分屏功能调节器
  • PipUI 画中画界面
  • Screenshot 截屏界面
  • RingtonePlayer 铃声播放器界面
  • Settings Activity 系统设置中用到的一些界面,例如:NetworkOverLimitActivity,UsbDebuggingActivity等。

1.4 System UI 启动流程

  1. framework/base/service/java/com/android/server/SystemServer.java: main() -> SystemServer().run();
  2. run() -> startBootstrapServices()
    -> startOtherServices() -> mActivityManagerService.systemReady -> startSystemUi() 在该方法中启动SystemUI
  3. startSystemUi() -> framework/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java: onCreate()
  4. onCreate() -> ((SystemUIApplication) getApplication()).startServicesIfNeeded()
  5. 读取service中预存的每个SystemUI相关类的反射,创建对应实例并启动相应的SystemUI进程

2. Keyguard

2.1 Keyguard

即Android 中处理锁屏(电源键按下、屏幕显示时间超时)、解锁(滑动、图案、指纹、声音、人脸、虹膜等)、锁屏下显示通知管理者。

2.2 KeyguardService的系统状态入口

void onStartedGoingToSleep(int pmSleepReason);
void onFinishedGoingToSleep(int pmSleepReason, boolean cameraGestureTriggered);
void onStartedWakingUp(int pmWakeReason,  boolean cameraGestureTriggered);
void onFinishedWakingUp();
void onScreenTurningOn(IKeyguardDrawnCallback callback);
void onScreenTurnedOn();
void onScreenTurningOff();
void onScreenTurnedOff();
void onSystemReady();
void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
void onShortPowerPressedGoHome();

2.3 Keyguard启动 - onSystemReady

1.KeyguardService.onSystemReady()
public void onSystemReady() {
    Trace.beginSection("KeyguardService.mBinder#onSystemReady");
    checkPermission(); // 避免死锁并检查权限
    mKeyguardViewMediator.onSystemReady(); // 进入锁屏入口
    Trace.endSection();
}
2.KeyguardViewMediator.handleSystemReady()
private void handleSystemReady() {
    synchronized (this) {
        if (DEBUG) Log.d(TAG, "onSystemReady");
        mSystemReady = true;
        doKeyguardLocked(null); // 锁屏预处理判断等操作
        mUpdateMonitor.registerCallback(mUpdateCallback);
    }
    // Most services aren't available until the system reaches the ready state, so we
    // send it here when the device first boots.
    maybeSendUserPresentBroadcast();
}
3.KeyguardViewMediator.doKeyguardLocked()
private void doKeyguardLocked(Bundle options) {
    if (KeyguardUpdateMonitor.CORE_APPS_ONLY) {
        // Don't show keyguard during half-booted cryptkeeper stage.
        if (DEBUG) Log.d(TAG, "doKeyguard: not showing because booting to cryptkeeper");
        return;
    }

    // if another app is disabling us, don't show
    if (!mExternallyEnabled) {
        if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");

        mNeedToReshowWhenReenabled = true;
        return;
    }

    // if the keyguard is already showing, don't bother. check flags in both files
    // to account for the hiding animation which results in a delay and discrepancy
    // between flags
    if (mShowing && mKeyguardViewControllerLazy.get().isShowing()) {
        if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
        resetStateLocked();
        return;
    }

    // In split system user mode, we never unlock system user.
    if (!mustNotUnlockCurrentUser()
            || !mUpdateMonitor.isDeviceProvisioned()) {

        // if the setup wizard hasn't run yet, don't show
        final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
        final boolean absent = SubscriptionManager.isValidSubscriptionId(
                mUpdateMonitor.getNextSubIdForState(TelephonyManager.SIM_STATE_ABSENT));
        final boolean disabled = SubscriptionManager.isValidSubscriptionId(
                mUpdateMonitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PERM_DISABLED));
        final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                || ((absent || disabled) && requireSim);

        if (!lockedOrMissing && shouldWaitForProvisioning()) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
                    + " and the sim is not locked or missing");
            return;
        }

        boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
        if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
                && !lockedOrMissing && !forceShow) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
            return;
        }

        if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
            if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
            // Without this, settings is not enabled until the lock screen first appears
            setShowingLocked(false);
            hideLocked();
            return;
        }
    }

    if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
    showLocked(options);
}
4.KeyguardViewMediator.showLocked()
private void showLocked(Bundle options) {
    Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");
    if (DEBUG) Log.d(TAG, "showLocked");
    // ensure we stay awake until we are finished displaying the keyguard
    mShowKeyguardWakeLock.acquire(); // 获取PARTIAL_WAKE_LOCK,不受电源键影响,不让CPU进入休眠状态
    Message msg = mHandler.obtainMessage(SHOW, options);
    mHandler.sendMessage(msg); // send SHOW类型的消息
    Trace.endSection();
}
5.KeyguardViewMediator.handleMessage() -> handleShow()
private void handleShow(Bundle options) {
    Trace.beginSection("KeyguardViewMediator#handleShow");
    final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
    if (mLockPatternUtils.isSecure(currentUser)) {
        mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);
    }
    synchronized (KeyguardViewMediator.this) {
        if (!mSystemReady) {
            if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
            return;
        } else {
            if (DEBUG) Log.d(TAG, "handleShow");
        }

        mHiding = false;
        mWakeAndUnlocking = false;
        setShowingLocked(true);
        mStatusBarKeyguardViewManager.show(options); 
        resetKeyguardDonePendingLocked();
        mHideAnimationRun = false;
        adjustStatusBarLocked();
        userActivity();
        mUpdateMonitor.setKeyguardGoingAway(false /* away */);
        mStatusBarWindowController.setKeyguardGoingAway(false /* goingAway */);
        mShowKeyguardWakeLock.release();
    }
    mKeyguardDisplayManager.show();
    Trace.endSection();
}
6.StatusBarKeyguardViewManager.show()
public void show(Bundle options) {
    mShowing = true;
    mStatusBarWindowController.setKeyguardShowing(true);
    mKeyguardMonitor.notifyKeyguardState(
            mShowing, mKeyguardMonitor.isSecure(), mKeyguardMonitor.isOccluded());
    reset(true /* hideBouncerWhenShowing */);
    StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
        StatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
}
7.StatusBarKeyguardViewManager.reset()
  public void reset(boolean hideBouncerWhenShowing) {
        if (mShowing) {
            if (mOccluded && !mDozing) {
                mStatusBar.hideKeyguard();
                if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
                    hideBouncer(false /* destroyView */);
                }
            } else {
                showBouncerOrKeyguard(hideBouncerWhenShowing);
            }
            KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
            updateStates();
        }
    }

UpdateMonitor.handleKeyguardReset

private void handleKeyguardReset() {
    if (DEBUG) Log.d(TAG, "handleKeyguardReset");
    updateBiometricListeningState();
    mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
}
8.StatusBarKeyguardViewManager.showBouncerOrKeyguard()

protected void showBouncerOrKeyguard() {
    if (mBouncer.needsFullscreenBouncer()) {//是否需要显示密码锁屏界面
            // The keyguard might be showing (already). So we need to hide it.
        mPhoneStatusBar.hideKeyguard();//隐藏锁屏,显示密码解锁界面
        mBouncer.show(true /* resetSecuritySelection */);
    } else {
        mPhoneStatusBar.showKeyguard();//显示锁屏,隐藏密码解锁界面
        mBouncer.hide(false /* destroyView */);
        mBouncer.prepare();
    }
}
9.StatusBar.showKeyguard() / hideKeyguard()
public void showKeyguard() {
    mStatusBarStateController.setKeyguardRequested(true);
    mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
    updateIsKeyguard();
    mAssistManagerLazy.get().onLockscreenShown();
}

public boolean hideKeyguard() {
    mStatusBarStateController.setKeyguardRequested(false);
    return updateIsKeyguard();
}
10.KeyguardBouncer.show()
10.1 show
public void show(boolean resetSecuritySelection, boolean isScrimmed) {
    final int keyguardUserId = KeyguardUpdateMonitor.getCurrentUser();
    if (keyguardUserId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser()) {
        // In split system user mode, we never unlock system user.
        return;
    }
    ensureView();
    mIsScrimmed = isScrimmed;

    // On the keyguard, we want to show the bouncer when the user drags up, but it's
    // not correct to end the falsing session. We still need to verify if those touches
    // are valid.
    // Later, at the end of the animation, when the bouncer is at the top of the screen,
    // onFullyShown() will be called and FalsingManager will stop recording touches.
    if (isScrimmed) {
        setExpansion(EXPANSION_VISIBLE);
    }

    if (resetSecuritySelection) {
        // showPrimarySecurityScreen() updates the current security method. This is needed in
        // case we are already showing and the current security method changed.
        showPrimarySecurityScreen(); 
        // ---> KeyguardViewController.showPrimarySecurityScreen();
        // ---> KeyguardSecurityContainerController.showPrimarySecurityScreen(false);
        // ---> KeyguardSecurityContainerController.showSecurityScreen()
    }

    if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {
        return;
    }

    final int activeUserId = KeyguardUpdateMonitor.getCurrentUser();
    final boolean isSystemUser =
            UserManager.isSplitSystemUser() && activeUserId == UserHandle.USER_SYSTEM;
    final boolean allowDismissKeyguard = !isSystemUser && activeUserId == keyguardUserId;

    // If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is
    // set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.
    if (allowDismissKeyguard && mKeyguardViewController.dismiss(activeUserId)) {
        return;
    }

    // This condition may indicate an error on Android, so log it.
    if (!allowDismissKeyguard) {
        Log.w(TAG, "User can't dismiss keyguard: " + activeUserId + " != " + keyguardUserId);
    }

    mShowingSoon = true;

    // Split up the work over multiple frames.
    DejankUtils.removeCallbacks(mResetRunnable);
    if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()
            && !mKeyguardUpdateMonitor.userNeedsStrongAuth()
            && !mKeyguardBypassController.getBypassEnabled()) {
        mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
    } else {
        DejankUtils.postAfterTraversal(mShowRunnable);
    }

    mCallback.onBouncerVisiblityChanged(true /* shown */);
    dispatchStartingToShow();
}
10.2 KeyguardSecurityContainerController.showSecurityScreen
void showSecurityScreen(SecurityMode securityMode) {
    if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");

    if (securityMode == SecurityMode.Invalid || securityMode == mCurrentSecurityMode) {
        return;
    }

    KeyguardInputViewController<KeyguardInputView> oldView = getCurrentSecurityController();

    // Emulate Activity life cycle
    if (oldView != null) {
        oldView.onPause();
    }

    KeyguardInputViewController<KeyguardInputView> newView = changeSecurityMode(securityMode);
    if (newView != null) {
        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
        mSecurityViewFlipperController.show(newView);
        mView.updateLayoutForSecurityMode(securityMode);
    }

    mSecurityCallback.onSecurityModeChanged(
            securityMode, newView != null && newView.needsInput());
}
10.3 getCurrentSecurityController & changeSecurityMode
private KeyguardInputViewController<KeyguardInputView> getCurrentSecurityController() {
    return mSecurityViewFlipperController
            .getSecurityView(mCurrentSecurityMode, mKeyguardSecurityCallback);
}

private KeyguardInputViewController<KeyguardInputView> changeSecurityMode(
        SecurityMode securityMode) {
    mCurrentSecurityMode = securityMode;
    return getCurrentSecurityController();
}
11.KeyguardBouncer.hide()
public void hide(boolean destroyView) {
    if (isShowing()) {
        SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
                SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
        mDismissCallbackRegistry.notifyDismissCancelled();
    }
    mIsScrimmed = false;
    mFalsingCollector.onBouncerHidden();
    mCallback.onBouncerVisiblityChanged(false /* shown */);
    cancelShowRunnable();
    if (mKeyguardViewController != null) {
        mKeyguardViewController.cancelDismissAction();
        mKeyguardViewController.cleanUp();
    }
    mIsAnimatingAway = false;
    if (mRoot != null) {
        setVisibility(View.INVISIBLE);
        if (destroyView) {

            // We have a ViewFlipper that unregisters a broadcast when being detached, which may
            // be slow because of AM lock contention during unlocking. We can delay it a bit.
            mHandler.postDelayed(mRemoveViewRunnable, 50);
        }
    }
}
public void cleanUp() {
    mKeyguardSecurityContainerController.onPause();
}
12.KeyguardBouncer.prepare()
public void prepare() {
    boolean wasInitialized = mRoot != null;
    ensureView();
    if (wasInitialized) {
        showPrimarySecurityScreen();
    }
    mBouncerPromptReason = mCallback.getBouncerPromptReason();
}

2.4 onStartGoingToSleep

在这里插入图片描述

1.KeyguardMediator.onStartedGoingToSleep
public void onStartedGoingToSleep(@WindowManagerPolicyConstants.OffReason int offReason) {
    if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + offReason + ")");
    synchronized (this) {
        mDeviceInteractive = false;
        mPowerGestureIntercepted = false;
        mGoingToSleep = true;

        // Lock immediately based on setting if secure (user has a pin/pattern/password).
        // This also "locks" the device when not secure to provide easy access to the
        // camera while preventing unwanted input.
        int currentUser = KeyguardUpdateMonitor.getCurrentUser();
        final boolean lockImmediately =
                mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
                        || !mLockPatternUtils.isSecure(currentUser);
        long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
        mLockLater = false;
        if (mExitSecureCallback != null) {
            if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
            try {
                mExitSecureCallback.onKeyguardExitResult(false);
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
            }
            mExitSecureCallback = null;
            if (!mExternallyEnabled) {
                hideLocked();
            }
        } else if (mShowing) {
            mPendingReset = true;
        } else if (
                (offReason == WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT
                        && timeout > 0)
                        || (offReason == WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER
                        && !lockImmediately)) {
            doKeyguardLaterLocked(timeout);
            mLockLater = true;
        } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
            mPendingLock = true;
        }

        if (mPendingLock) {
            playSounds(true);
        }
    }

    mUpdateMonitor.dispatchStartedGoingToSleep(offReason);

    // Reset keyguard going away state so we can start listening for fingerprint. We
    // explicitly DO NOT want to call
    // mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false)
    // here, since that will mess with the device lock state.
    mUpdateMonitor.dispatchKeyguardGoingAway(false);

    notifyStartedGoingToSleep();
}
2.KeyguardViewMediator.hideLocked
private void hideLocked() {
    Trace.beginSection("KeyguardViewMediator#hideLocked");
    if (DEBUG) Log.d(TAG, "hideLocked");
    Message msg = mHandler.obtainMessage(HIDE);
    mHandler.sendMessage(msg);
    Trace.endSection();
}
3.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) {
            mKeyguardGoingAwayRunnable.run();
        } else {
            // TODO(bc-unlock): Fill parameters
            handleStartKeyguardExitAnimation(
                    SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
                    mHideAnimation.getDuration(), null /* apps */,  null /* wallpapers */,
                    null /* nonApps */, null /* finishedCallback */);
        }
    }
    Trace.endSection();
}
4.KeyguardGoingAwayRunnable.run
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); // 调用 4.1
        } catch (RemoteException e) {
            Log.e(TAG, "Error while calling WindowManager", e);
        }
    });
    Trace.endSection();
}

4.1 KeyguardController.keyguardGoingAway

void keyguardGoingAway(int flags) {
    if (!mKeyguardShowing) {
        return;
    }
    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "keyguardGoingAway");
    mService.deferWindowLayout();
    mKeyguardGoingAway = true;
    try {
        EventLogTags.writeWmSetKeyguardShown(
                1 /* keyguardShowing */,
                mAodShowing ? 1 : 0,
                1 /* keyguardGoingAway */,
                "keyguardGoingAway");
        mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
                TRANSIT_KEYGUARD_GOING_AWAY, convertTransitFlags(flags));
        updateKeyguardSleepToken();

        // Some stack visibility might change (e.g. docked stack)
        mRootWindowContainer.resumeFocusedTasksTopActivities();
        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
        mRootWindowContainer.addStartingWindowsForVisibleActivities();
        mWindowManager.executeAppTransition();
    } finally {
        mService.continueWindowLayout();
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
} 
5.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 */); // ---> 6
            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); //调用 mDawnCallback.onDrawn
            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); // ---> 7
            } 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);

            mContext.getMainExecutor().execute(() -> {
                if (finishedCallback == null) {
                    InteractionJankMonitor.getInstance().end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                    return;
                }

                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();
}
6.KeyguardMediator.setShowingLocked
void setShowingLocked(boolean showing) {
    setShowingLocked(showing, false /* forceCallbacks */);
}

private void setShowingLocked(boolean showing, boolean forceCallbacks) {
    final boolean aodShowing = mDozing && !mWakeAndUnlocking;
    final boolean notifyDefaultDisplayCallbacks = showing != mShowing
            || aodShowing != mAodShowing || forceCallbacks;
    mShowing = showing;
    mAodShowing = aodShowing;
    if (notifyDefaultDisplayCallbacks) {
        notifyDefaultDisplayCallbacks(showing); // 1.KeyguardStateCallback.onShowingStateChanged
        										// 2.updateInputRestrictedLocked
        										// 3.TrustManager.reportKeyguardShowingChanged
        updateActivityLockScreenState(showing, aodShowing); // ActivityTaskManager.getService().setLockScreenShown
        													// ---> ActivityTaskManagerService
    }
}
7.IRemoteAnimationRunner.onAnimationStart
// (in ActivityLaunchAnimator.kt)
override fun onAnimationStart(
    @WindowManager.TransitionOldType transit: Int,
    apps: Array<out RemoteAnimationTarget>?,
    wallpapers: Array<out RemoteAnimationTarget>?,
    nonApps: Array<out RemoteAnimationTarget>?,
    iCallback: IRemoteAnimationFinishedCallback?
) {
    removeTimeout()

    // The animation was started too late and we already notified the controller that it
    // timed out.
    if (timedOut) {
        iCallback?.invoke()
        return
    }

    // This should not happen, but let's make sure we don't start the animation if it was
    // cancelled before and we already notified the controller.
    if (cancelled) {
        return
    }

    context.mainExecutor.execute {
        startAnimation(apps, nonApps, iCallback)
    }
}
8.CarKeyguardViewController.hide
public void hide(long startTime, long fadeoutDuration) {
    if (!mShowing) return;

    mViewMediatorCallback.readyForKeyguardDone(); // if(mkeyguardDonePending) tryKeyguardGone()
    mShowing = false;
    mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
    mBouncer.hide(/* destroyView= */ true);
    mCarSystemBarController.showAllNavigationButtons(/* isSetUp= */ true);
    stop(); //  调用 mOverlayViewGlobalStateController.hideView
    mKeyguardStateController.notifyKeyguardDoneFading(); // 调用callback的onKeyguardFadingAwayChanged
    mMainExecutor.execute(mViewMediatorCallback::keyguardGone);
    notifyKeyguardUpdateMonitor(); // KeyguardLifeController(kt).updateListeningState
}

KeyguardMediator.tryKeyguardDone

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

KeyguardLifeController(kt).updateListeningState

private fun updateListeningState() {
	// ...
    if (shouldListen != isListening) {
        isListening = shouldListen

        if (shouldListen) {
            asyncSensorManager.requestTriggerSensor(listener, pickupSensor)
        } else {
            asyncSensorManager.cancelTriggerSensor(listener, pickupSensor)
        }
    }
}
9.KeyguardViewMediator.onKeyguardExitFinished
private void onKeyguardExitFinished() {
    // only play "unlock" noises if not on a call (since the incall UI
    // disables the keyguard)
    if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
        playSounds(false);
    }

    setShowingLocked(false); // ---> 6
    mWakeAndUnlocking = false;
    mDismissCallbackRegistry.notifyDismissSucceeded();
    resetKeyguardDonePendingLocked(); // mKeyguardDonePending = false;
									  // mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT);
    mHideAnimationRun = false;
    adjustStatusBarLocked(); // StatusBarManager.disable
    sendUserPresentBroadcast();
}

2.5 onFinishedGoingToSleep

在这里插入图片描述

1. KeyguardViewMediator.onFinishedGoingToSleep
public void onFinishedGoingToSleep(
        @WindowManagerPolicyConstants.OffReason int offReason, boolean cameraGestureTriggered) {
    if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + offReason + ")");
    synchronized (this) {
        mDeviceInteractive = false;
        mGoingToSleep = false;
        mWakeAndUnlocking = false;
        mAnimatingScreenOff = mDozeParameters.shouldControlUnlockedScreenOff();

        resetKeyguardDonePendingLocked();
        mHideAnimationRun = false;

        notifyFinishedGoingToSleep();

        if (cameraGestureTriggered) {

            // Just to make sure, make sure the device is awake.
            mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
                    PowerManager.WAKE_REASON_CAMERA_LAUNCH,
                    "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
            mPendingLock = false;
            mPendingReset = false;
        }

        if (mPendingReset) {
            resetStateLocked(); // ---> 2.3-7
            mPendingReset = false;
        }

        maybeHandlePendingLock(); //if (mPendingLock && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying())
        						  // doKeyguardLocked(null) ---> 2.3-3

        if (!mLockLater && !cameraGestureTriggered) {
            doKeyguardForChildProfilesLocked(); // 获取所有Enabled User Profile
            									// if (mLockPatternUtils.isSeparateProfileChallengeEnabled(profileId)) {
												// lockProfile(profileId);
            }
        }

    }
    mUpdateMonitor.dispatchFinishedGoingToSleep(offReason); 
    // mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why (offReason), 0));
    // ---> handleKeyguardReset (2.3-7)
}

private void notifyFinishedGoingToSleep() {
    if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
    mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
}
2.KeyguardViewMediator.handleNotifyFinishedGoingToSleep
private void handleNotifyFinishedGoingToSleep() {
    synchronized (KeyguardViewMediator.this) {
        if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
        mKeyguardViewControllerLazy.get().onFinishedGoingToSleep();
    }
}
3.CarKeyguardViewController.onFinishedGoingToSleep
public void onFinishedGoingToSleep() {
    if (mBouncer != null) {
        mBouncer.onScreenTurnedOff();
    }
}
4.KeyguardBouncer.onScreenTurnedOff
public void onScreenTurnedOff() {
    if (mKeyguardViewController != null
            && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
        mKeyguardViewController.onPause();
    }
}
5.KeyguardHostViewController.onPause
public void onPause() {
    if (DEBUG) {
        Log.d(TAG, String.format("screen off, instance %s at %s",
                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
    }
    mKeyguardSecurityContainerController.showPrimarySecurityScreen(true);
    mKeyguardSecurityContainerController.onPause();
    mView.clearFocus();
}
6.KeyguardUpdateMonitor.handleFinishedGoingToSleep
protected void handleFinishedGoingToSleep(int arg1) {
    Assert.isMainThread();
    mGoingToSleep = false;
    for (int i = 0; i < mCallbacks.size(); i++) {
        KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
        if (cb != null) {
            cb.onFinishedGoingToSleep(arg1);
        }
    }
    updateBiometricListeningState();
}
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值