美文网首页
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