美文网首页
android7.0锁屏(三)解锁流程

android7.0锁屏(三)解锁流程

作者: Lonelyyy | 来源:发表于2017-12-06 00:00 被阅读0次

    前面的文章分析了上锁的流程,解锁的流程可以看作是上锁的逆过程,同样有以下三点

    • 设备认证
    • 移除锁屏,或者说是statusbar由锁屏模式切换为状态栏模式,改变窗口大小,移除bouncer
    • 更新activity stack状态,这个在前面讲apptransition有提到过

    1.密码界面解锁

    输入密码后,会调用到下面这段函数,通过回调的方式来获取到密码校验的结果,其中LockPatternUtils扮演了类似于xxManager的作用,把检验密码的命令发送到LockSettingsService,最终直达GateKeeper,再一层层传回结果,密码校验的过程也是十分复杂,这里不做分析

    mPendingLockCheck = LockPatternChecker.checkPassword(mLockPatternUtils,  entry, userId,
                    new LockPatternChecker.OnCheckCallback() {
                        @Override
                        public void onEarlyMatched() {
                            onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */, true /* isValidPassword */);
                        }
    
                        @Override
                        public void onChecked(boolean matched, int timeoutMs) {
                            setPasswordEntryInputEnabled(true);
                            mPendingLockCheck = null;
                            if (!matched) {
                                onPasswordChecked(userId, false /* matched */, timeoutMs, true /* isValidPassword */);
                            }
                        }
                    });
    

    完成密码校验后最终来到KeyguardViewMediator的handleKeyguardDone函数,类似于doKeyguardLocked,都是上锁或解锁的起始函数

    private void handleKeyguardDone(boolean authenticated) {
            final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
            if (mLockPatternUtils.isSecure(currentUser)) {
                mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser); // 通知devicepolicymanagerservice
            }
            synchronized (this) {
                resetKeyguardDonePendingLocked();
            }
            if (authenticated) {
                mUpdateMonitor.clearFailedUnlockAttempts();
            }
            mUpdateMonitor.clearFingerprintRecognized();
            if (mGoingToSleep) {
                return;
            }
            if (mExitSecureCallback != null) {
                try {
                    mExitSecureCallback.onKeyguardExitResult(authenticated);
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
                }
                mExitSecureCallback = null;
                if (authenticated) {
                    mExternallyEnabled = true;
                    mNeedToReshowWhenReenabled = false;
                    updateInputRestricted();
                }
            }
            handleHide(); // 处理移除锁屏
        }
    

    handleHide首先会执行一个apptransition,这里面就会完成activity stack的更新,前面也说过,执行完apptransition又会调到handleStartKeyguardExitAnimation

    private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    mStatusBarKeyguardViewManager.keyguardGoingAway();
           int flags = 0;
                    if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
                            || mWakeAndUnlocking) {
                        flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
                    }
                    if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()) {
                        flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
                    }
                    if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
                        flags |= WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
                    }
                    ActivityManagerNative.getDefault().keyguardGoingAway(flags);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error while calling WindowManager", e);
                }
            }
        };
    
    private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
            synchronized (KeyguardViewMediator.this) {
                if (!mHiding) {
                    return;
                }
                mHiding = false;
                if (mWakeAndUnlocking && mDrawnCallback != null) {
                    mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
                    notifyDrawn(mDrawnCallback);
                    mDrawnCallback = null;
                }
                if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
                    playSounds(false);
                }
                mWakeAndUnlocking = false;
                setShowingLocked(false);
                mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration); // 收起锁屏并隐藏bouncer
                resetKeyguardDonePendingLocked();
                mHideAnimationRun = false;
                updateActivityLockScreenState();
                adjustStatusBarLocked();
                sendUserPresentBroadcast();
            }
        }
    

    StatusBarKeyguardViewManager中的hide和show函数也是相互对应的关系,这里也会涉及到很多场景的处理,一般情况下的解锁过程已经标注出来,经过解锁流程,锁屏界面消失,锁屏下的界面显示出来

    public void hide(long startTime, long fadeoutDuration) {
            mShowing = false;
            if (KeyguardUpdateMonitor.getInstance(mContext).needsSlowUnlockTransition()) {
                fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
            }
            long uptimeMillis = SystemClock.uptimeMillis();
            long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);
            if (mPhoneStatusBar.isInLaunchTransition() ) {
                mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
                    @Override
                    public void run() {
                        mStatusBarWindowManager.setKeyguardShowing(false);
                        mStatusBarWindowManager.setKeyguardFadingAway(true);
                        mBouncer.hide(true /* destroyView */);
                        updateStates();
                        mScrimController.animateKeyguardFadingOut(
                                PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
                                PhoneStatusBar.FADE_KEYGUARD_DURATION, null,
                                false /* skipFirstFrame */);
                    }
                }, new Runnable() {
                    @Override
                    public void run() {
                        mPhoneStatusBar.hideKeyguard();
                        mStatusBarWindowManager.setKeyguardFadingAway(false);
                        mViewMediatorCallback.keyguardGone();
                        executeAfterKeyguardGoneAction();
                    }
                });
            } else {
                if (mFingerprintUnlockController.getMode() == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
                    mFingerprintUnlockController.startKeyguardFadingAway();
                    mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 240);
                    mStatusBarWindowManager.setKeyguardFadingAway(true);
                    mPhoneStatusBar.fadeKeyguardWhilePulsing();
                    animateScrimControllerKeyguardFadingOut(0, 240, new Runnable() {
                        @Override
                        public void run() {
                            mPhoneStatusBar.hideKeyguard();
                        }
                    }, false /* skipFirstFrame */);
                } else {
                    // 一般情况
    
                    mFingerprintUnlockController.startKeyguardFadingAway();
                    mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
                    boolean staying = mPhoneStatusBar.hideKeyguard();
                    if (!staying) {
                        mStatusBarWindowManager.setKeyguardFadingAway(true);
                        if (mFingerprintUnlockController.getMode()
                                == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
                            if (!mScreenTurnedOn) {
                                mDeferScrimFadeOut = true;
                            } else {
                                animateScrimControllerKeyguardFadingOut(0,WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS, true /* skipFirstFrame */);
                            }
                        } else {
                            animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration, false /* skipFirstFrame */);
                        }
                    } else {
                        mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
                        mPhoneStatusBar.finishKeyguardFadingAway();
                    }
                }
                mStatusBarWindowManager.setKeyguardShowing(false);
                mBouncer.hide(true /* destroyView */);
                mViewMediatorCallback.keyguardGone();
                executeAfterKeyguardGoneAction();
                updateStates();
            }
        }
    

    2.指纹解锁

    Android6.0加入了指纹解锁的功能,指纹解锁和密码解锁的主要区别是指纹的认证是由FingerprintService传递过来的,并非LockSettingsService,当然指纹和密码也有很多其他的联系,这里不详述
    锁屏处理指纹监听与结果回调的类是KeyguardUpdateMonitor,进一步地,它会把结果传递到FingprintUnlockController

    public void onFingerprintAuthenticated(int userId) {
            if (mUpdateMonitor.isGoingToSleep()) {
                mPendingAuthenticatedUserId = userId;
                return;
            }
            boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
            mMode = calculateMode();
            if (!wasDeviceInteractive) {
                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.policy:FINGERPRINT");
            }
            releaseFingerprintWakeLock();
            switch (mMode) {
                case MODE_DISMISS_BOUNCER:
                    mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
                            false /* strongAuth */);
                    break;
                case MODE_UNLOCK:
                case MODE_SHOW_BOUNCER:
                    if (!wasDeviceInteractive) {
                        mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
                    }
                    mStatusBarKeyguardViewManager.animateCollapsePanels(
                            FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
                    break;
                case MODE_WAKE_AND_UNLOCK_PULSING:
                    mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */, 
                            true /* allowEnterAnimation */);
                case MODE_WAKE_AND_UNLOCK:
                    mStatusBarWindowManager.setStatusBarFocusable(false);
                    mDozeScrimController.abortPulsing();
                    mKeyguardViewMediator.onWakeAndUnlocking();
                    mScrimController.setWakeAndUnlocking();
                    if (mPhoneStatusBar.getNavigationBarView() != null) {
                        mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
                    }
                    break;
                case MODE_ONLY_WAKE:
                case MODE_NONE:
                    break;
            }
            if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
                mStatusBarWindowManager.setForceDozeBrightness(false);
            }
            mPhoneStatusBar.notifyFpAuthModeChanged();
        }
    

    如果当前屏幕熄灭,那么指纹认证成功后还会点亮屏幕,同时也会根据当前的场景去执行相应的解锁流程,但是不管是mStatusBarKeyguardViewManager.animateCollapsePanels(FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR)还是mKeyguardViewMediator.onWakeAndUnlocking(),最终结果都会是KeyguardViewMediator的handleKeyguardDone函数,殊途同归

    3.时序图

    image.png

    相关文章

      网友评论

          本文标题:android7.0锁屏(三)解锁流程

          本文链接:https://www.haomeiwen.com/subject/cqbhixtx.html