美文网首页
android7.0锁屏(二)上锁流程

android7.0锁屏(二)上锁流程

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

    上锁的主要是两个步骤

    • 设备加密,这块主要是与android管理设备密码服务相关
    • 显示锁屏界面,即展开通知面板,同时加载密码界面的布局,但是会隐藏起来,等到向上划去锁屏界面才显示
    • 更新activity stack的状态,锁屏下的activity会被置为onstop
      执行上锁的流程是调用KeyguardViewMediator的doKeyguardLocked函数来完成的
    private void doKeyguardLocked(Bundle options) {
            if (!mExternallyEnabled) {
                return;
            }
            // if the keyguard is already showing, don't bother
            if (mStatusBarKeyguardViewManager.isShowing()) {
                resetStateLocked();
                return;
            }
            if (!mustNotUnlockCurrentUser()  || !mUpdateMonitor.isDeviceProvisioned()) {
                final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
                final boolean absent = SubscriptionManager.isValidSubscriptionId(
                        mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
                final boolean disabled = SubscriptionManager.isValidSubscriptionId(
                        mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
                final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                        || ((absent || disabled) && requireSim);
                if (!lockedOrMissing && shouldWaitForProvisioning()) {
                    return;
                }
                if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
                        && !lockedOrMissing) {
                    return;
                }
                if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
                    setShowingLocked(false);
                    hideLocked();
                    mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
                    return;
                }
            }
            showLocked(options);
        }
    

    重点看这个showLocked函数,经过handler的传递会调到handleShow

    private void handleShow(Bundle options) {
            final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
            if (mLockPatternUtils.isSecure(currentUser)) {
                mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);  //更新设备加密状态
            }
            synchronized (KeyguardViewMediator.this) {
                if (!mSystemReady) {
                    return;
                } else {
                }
                setShowingLocked(true);
                mStatusBarKeyguardViewManager.show(options); // 显示锁屏界面和加载bouncer
                mHiding = false;
                mWakeAndUnlocking = false;
                resetKeyguardDonePendingLocked();
                mHideAnimationRun = false;
                updateActivityLockScreenState(); // 更新activitystack的状态
                adjustStatusBarLocked();
                userActivity();
                mShowKeyguardWakeLock.release();
            }
            mKeyguardDisplayManager.show();
        }
    

    继续看显示锁屏的函数

    public void show(Bundle options) {
            mShowing = true;
            mStatusBarWindowManager.setKeyguardShowing(true); // 调整状态栏的窗口状态
            mScrimController.abortKeyguardFadingOut();
            reset();
        }
    
    public void reset() {
            if (mShowing) {
                if (mOccluded) {// 特殊情况,例如来电,音乐锁屏等显示在锁屏界面上的activity
                    mPhoneStatusBar.hideKeyguard();
                    mPhoneStatusBar.stopWaitingForKeyguardExit();
                    mBouncer.hide(false /* destroyView */);
                } else {
                    showBouncerOrKeyguard();
                }
                KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
                updateStates();
            }
        }
    

    正常情况下都会调用到showBouncerOrKeyguard()

    protected void showBouncerOrKeyguard() {
            if (mBouncer.needsFullscreenBouncer()) { // 存在锁定的sim卡会走到这里
                // 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 */); // 隐藏bouncer
                mBouncer.prepare(); // 加载bouncer的布局
            }
        }
    

    所以正常情况下就会调用上面三段函数,主要关注bouncer布局的加载
    经过一系列调用,会到达KeyguardSecurityContainer的showPrimarySecurityScreen

    void showPrimarySecurityScreen(boolean turningOff) {
            SecurityMode securityMode = mSecurityModel.getSecurityMode(); // 获取锁屏密码样式
            if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
            showSecurityScreen(securityMode); // 加载具体的布局
        }
    
    private void showSecurityScreen(SecurityMode securityMode) {
            if (securityMode == mCurrentSecuritySelection) return;
            KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
            KeyguardSecurityView newView = getSecurityView(securityMode);
    
            // Emulate Activity life cycle
            if (oldView != null) {
                oldView.onPause();
                oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
            }
            if (securityMode != SecurityMode.None) {
                newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
                newView.setKeyguardCallback(mCallback);
            }
            // Find and show this child.
            final int childCount = mSecurityViewFlipper.getChildCount();
            final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
            for (int i = 0; i < childCount; i++) {
                if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
                    mSecurityViewFlipper.setDisplayedChild(i);
                    break;
                }
            }
            mCurrentSecuritySelection = securityMode;
            mSecurityCallback.onSecurityModeChanged(securityMode,
                    securityMode != SecurityMode.None && newView.needsInput());
        }
    

    最后,通过锁定方式来找到对应的布局,就完成的bouncer的加载,划去锁屏界面后就可以看到了

    private int getSecurityViewIdForMode(SecurityMode securityMode) {
            switch (securityMode) {
                case Pattern: return R.id.keyguard_pattern_view;
                case PIN: return R.id.keyguard_pin_view;
                case Password: return R.id.keyguard_password_view;
                case SimPin: return R.id.keyguard_sim_pin_view;
                case SimPuk: return R.id.keyguard_sim_puk_view;
            }
            return 0;
        }
    

    放一张时序图


    image.png

    相关文章

      网友评论

          本文标题:android7.0锁屏(二)上锁流程

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