接着看 PanelViewController#notifyBarPanelExpansionChanged()
这里注意:都是到 KeyguardSecurityContainer#KeyguardSecurityContainer(),滑动解锁与带有密码安全界面,即密码解锁,两个流程的代码执行顺序有差异。
// PanelViewController.java protected void notifyBarPanelExpansionChanged() { if (mBar != null) { mBar.panelExpansionChanged( mExpandedFraction, mExpandedFraction > 0f || mPeekAnimator != null || mInstantExpanding || isPanelVisibleBecauseOfHeadsUp() || mTracking || mHeightAnimator != null); } for (int i = 0; i < mExpansionListeners.size(); i++) { mExpansionListeners.get(i).onPanelExpansionChanged(mExpandedFraction, mTracking); } }
再 notifyBarPanelExpansionChanged() 方法中继而调用 PanelBar 中的panelExpansionChanged方法:页面的透明度。
PanelBar#panelExpansionChanged()
// PanelBar.java public void panelExpansionChanged(float frac, boolean expanded) { if (isNaN(frac)) { throw new IllegalArgumentException("frac cannot be NaN"); } boolean fullyClosed = true; boolean fullyOpened = false; if (SPEW) LOG("panelExpansionChanged: start state=%d", mState); PanelViewController pv = mPanel; mExpanded = expanded; mPanelFraction = frac; updateVisibility(); // 调整可能部分可见的任何其他面板 if (expanded) { if (mState == STATE_CLOSED) { go(STATE_OPENING); onPanelPeeked(); } fullyClosed = false; final float thisFrac = pv.getExpandedFraction(); if (SPEW) LOG("panelExpansionChanged: -> %s: f=%.1f", pv.getName(), thisFrac); fullyOpened = thisFrac >= 1f; } // fullyOpened 完全打开;就是:锁屏界面是否完全展开的;(手指不滑动时,fullyOpened = true,fullyClosed = false;) // fullyClosed 完全关闭,就是:锁屏界面是否完全折叠,即消失了;(锁屏界面上滑消失时,fullyOpened = false,fullyClosed = true) // 手指在滑动过程中时:fullyOpened = false,fullyClosed = false if (fullyOpened && !mTracking) { go(STATE_OPEN); onPanelFullyOpened(); } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) { go(STATE_CLOSED); // 面板折叠时 onPanelCollapsed(); } if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState, fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":""); }
当锁屏页面完全消失时,调用 onPanelCollapsed() 方法,执行 post() 方法。
PhoneStatusBarView#onPanelCollapsed()
@Override public void onPanelCollapsed() { super.onPanelCollapsed(); // Close the status bar in the next frame so we can show the end of the animation. post(mHideExpandedRunnable); mIsFullyOpenedPanel = false; } private Runnable mHideExpandedRunnable = new Runnable() { @Override public void run() { if (mPanelFraction == 0.0f) { mBar.makeExpandedInvisible(); } } };
接下来执行 StatusBar 中的 makeExpandedInvisible() 方法,更新通知栏和状态栏窗口的可见性。
StatusBar#makeExpandedInvisible()
// StatusBar.java void makeExpandedInvisible() { if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible + " mExpandedVisible=" + mExpandedVisible); if (!mExpandedVisible || mNotificationShadeWindowView == null) { return; } // 确保面板完全折叠 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/, 1.0f /* speedUpFactor */); mNotificationPanelViewController.closeQs(); mExpandedVisible = false; visibilityChanged(false); // 更新通知阴影和状态栏窗口的可见性 mNotificationShadeWindowController.setPanelVisible(false); mStatusBarWindowController.setForceStatusBarVisible(false); // Close any guts that might be visible mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */, true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */); mShadeController.runPostCollapseRunnables(); setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false); if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) { showBouncerIfKeyguard(); } else if (DEBUG) { Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen"); } mCommandQueue.recomputeDisableFlags( mDisplayId, mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */); // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in // the bouncer appear animation. if (!mStatusBarKeyguardViewManager.isShowing()) { WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); } }
StatusBar#showBouncerIfKeyguard()
// StatusBar.java private void showBouncerIfKeyguard() { if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) && !mKeyguardViewMediator.isHiding()) { // !mKeyguardViewMediator.isHiding() 不管是滑动解锁还是PIN码解锁等方式都是 true mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); } }
StatusBarKeyguardViewManager#showBouncer()
// StatusBarKeyguardViewManager.java public void showBouncer(boolean scrimmed) { // 如果是滑动解锁,这里 if 条件是 true,如果是密码解锁,这里是 false。 if (mShowing && !mBouncer.isShowing()) { mBouncer.show(false /* resetSecuritySelection */, scrimmed); } updateStates(); }
KeyguardBouncer#show() 如果有设置密码,则显示安全锁界面
// KeyguardBouncer.java 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; if (isScrimmed) { setExpansion(EXPANSION_VISIBLE); } if (resetSecuritySelection) { showPrimarySecurityScreen(); } 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; // 重点关注 dismiss() if (allowDismissKeyguard && mKeyguardView.dismiss(activeUserId)) { return; } 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 */); // 开始显示 mExpansionCallback.onStartingToShow(); }
这里重点关注 mKeyguardView.dismiss(activeUserId) ;
KeyguardHostView#dismiss()
// KeyguardHostView.java // 显示安全锁 public boolean dismiss(int targetUserId) { return dismiss(false, targetUserId, false); } @Override public boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen) { // 重点关注 return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId, bypassSecondaryLockScreen); }
KeyguardSecurityContainer#showNextSecurityScreenOrFinish()
// KeyguardSecurityContainer.java // 显示下一个安全屏幕(如果有) boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen) { if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")"); boolean finish = false; boolean strongAuth = false; int eventSubtype = -1; int unLockMode = 0;// add for KFCAANWIKFRA-833 BouncerUiEvent uiEvent = BouncerUiEvent.UNKNOWN; if (mUpdateMonitor.getUserHasTrust(targetUserId)) { // 省略部分代码...... } else if (mUpdateMonitor.getUserUnlockedWithBiometric(targetUserId)) { // 省略部分代码...... } else if (SecurityMode.None == mCurrentSecuritySelection) { // mCurrentSecuritySelection当前安全选择的模式 SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); if (SecurityMode.None == securityMode) { unLockMode = 0; finish = true; // 没有安全锁 eventSubtype = BOUNCER_DISMISS_NONE_SECURITY; uiEvent = BouncerUiEvent.BOUNCER_DISMISS_NONE_SECURITY; } else { showSecurityScreen(securityMode); // switch to the alternate security view } } else if (authenticated) { // mCurrentSecuritySelection 当前锁的模式 switch (mCurrentSecuritySelection) { case Pattern: case Password: case PIN: unLockMode = mCurrentSecuritySelection.ordinal() - 1; strongAuth = true; finish = true; eventSubtype = BOUNCER_DISMISS_PASSWORD; uiEvent = BouncerUiEvent.BOUNCER_DISMISS_PASSWORD; break; // 省略部分代码...... default: Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe"); showPrimarySecurityScreen(false); break; } } // 检查设备管理员指定的其他安全措施。 /* UNISOC: Modify for bug1394148 @{ */ Intent secondaryLockscreenIntent = mUpdateMonitor.getSecondaryLockscreenRequirement(targetUserId); if (finish && !bypassSecondaryLockScreen && secondaryLockscreenIntent != null) { mSecondaryLockScreenController.show(secondaryLockscreenIntent); return false; } /* @} */ if (eventSubtype != -1) { mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER) .setType(MetricsEvent.TYPE_DISMISS).setSubtype(eventSubtype)); } if (uiEvent != BouncerUiEvent.UNKNOWN) { sUiEventLogger.log(uiEvent); } // finish 是否还有一个安全屏幕,即是否解锁完成,有则返回 false,没有返回 true if (finish) { // 重点关注 mSecurityCallback.finish(strongAuth, targetUserId); // 省略部分代码...... } return finish; }
KeyguardHostView#finish()
// KeyguardHostView.java @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) { // deferKeyguardDone 上面设置成了 false mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId); } else { // 重点关注 mViewMediatorCallback.keyguardDone(strongAuth, targetUserId); } } }
KeyguardViewMediator#keyguardDone()
// KeyguardViewMediator.java @Override public void keyguardDone(boolean strongAuth, int targetUserId) { if (targetUserId != ActivityManager.getCurrentUser()) { return; } if (DEBUG) Log.d(TAG, "keyguardDone"); 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; mHideAnimationRunning = true; mKeyguardViewControllerLazy.get() .startPreHideAnimation(mHideAnimationFinishedRunnable); // 启动预隐藏动画 } }