keyguard学习--LockPatternKeyguardView

一、关于锁屏的模式

锁屏方式有两种,如下为定义方式

 /**
     * Either a lock screen (an informational keyguard screen), or an unlock
     * screen (a means for unlocking the device) is shown at any given time.
     */
    enum Mode {
        LockScreen,
        UnlockScreen
    }

其中,LockScreen是默认的解锁方式,一般称之为“解锁”界面;UnlockScreen一般称之为“开锁”界面。
它们之间是并列的关系,也就是在进入解锁后会判断是哪一种case,然后进入,而UnlockScreen并不是最终的一种case,它又细分为如下几种情况:

 /**
     * The different types screens available for {@link Mode#UnlockScreen}.
     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
     */
    enum UnlockMode {

        /**
         * Unlock by drawing a pattern.
         */
        Pattern,

        /**
         * Unlock by entering a sim pin.
         */
        SimPin,

        /**
         * Unlock by entering a sim2 pin.
         */
        Sim2Pin,
        
        /**
         * Unlock by entering an account's login and password.
         */
        Account,

        /**
         * Unlock by entering a password or PIN
         */
        Password,

        /**
         * Unknown (uninitialized) value
         */
        Unknown
    }

一共有五种UnlockScreen方式,很简单,不用多解释。


二、getInitialMode方法

此方法是为了获取初始的锁屏方式,返回的结果是Mode模式中的一种--LockScreen或者UnlockScreen。而对于UnlockScreen模式,并没有给出具体是哪种方式:pin,password,或者pattern等,没有给出。这会在另一个方法中进行判断。

private Mode getInitialMode() {
    if (stuckOnLockScreenBecauseSimMissing()) {
        return Mode.LockScreen;
    } else {
        if (!isSecure() || mShowLockBeforeUnlock) {
            return Mode.LockScreen;
        } else {
            return Mode.UnlockScreen;
        }
    }
}

当sim卡不存在时,当用户没有选择安全的方式(不安全意味着当前锁屏方式是滑动解锁,而非pin、password、pattern等),当显示UnlockScreen前需要首先显示LockScreen时,那么返回LockScreen;否则返回UnlockScreen。


三、getUnlockMode方法

此方法能够获取到当前应该处于UnlockScreen下的哪一种解锁方式,它会返回五种UnlockMode中的一种。

注意的是,获取解锁方式时是有优先级的。源码如下:

private UnlockMode getUnlockMode() {
    final IccCard.State simState = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_1);
    final IccCard.State sim2State = mUpdateMonitor.getSimState(Phone.GEMINI_SIM_2);
    UnlockMode currentMode = UnlockMode.Unknown;
    if (simState == IccCard.State.PIN_REQUIRED 
        && !mUpdateMonitor.getPINDismissFlag(Phone.GEMINI_SIM_1, true)
        || (simState == IccCard.State.PUK_REQUIRED 
        && !mUpdateMonitor.getPINDismissFlag(Phone.GEMINI_SIM_1, false))){
        currentMode = UnlockMode.SimPin;
    }  else if (sim2State == IccCard.State.PIN_REQUIRED 
        && !mUpdateMonitor.getPINDismissFlag(Phone.GEMINI_SIM_2, true)
        || (sim2State == IccCard.State.PUK_REQUIRED 
        && !mUpdateMonitor.getPINDismissFlag(Phone.GEMINI_SIM_2, false))){
        currentMode = UnlockMode.Sim2Pin;
    } else {
        final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
        switch (mode) {
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
                currentMode = UnlockMode.Password;
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
            case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
                // "forgot pattern" button is only available in the pattern mode...
                if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) {
                    currentMode = UnlockMode.Account;
                } else {
                    currentMode = UnlockMode.Pattern;
                }
                break;
            default:
               throw new IllegalStateException("Unknown unlock mode:" + mode);
        }
    }
    return currentMode;
}

默认是UnlockMode.Unknown
优先级最高的是UnlockMode.SimPin,然后是UnlockMode.Sim2Pin,再是其它的几种

private final KeyguardUpdateMonitor mUpdateMonitor;
这个KeyguardUpdateMonitor能够监测当前手机的状态,并提供了getSimState,它能够返回当前sim卡的状态,sim卡有多个状态,在IccCard.java中有定义

public enum State {
    UNKNOWN,
    ABSENT,
    PIN_REQUIRED,
    PUK_REQUIRED,
    NETWORK_LOCKED,
    READY,
    NOT_READY,
    PERM_DISABLED;
}

这里我们只对PIN_REQUIRED和PUK_REQUIRED这两个状态进行讨论。

inal int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
对于其它几种情况,应该是有个位置来记录这些mode的,但是我没有找到,猜测是在数据库中。


四、updateScreen方法

private void updateScreen(Mode mode, boolean force) {
    mMode = mode;

    /*
    **调用recreateLockScreen方法需要两步验证,任何一步不能通过都不会调用该方法
    **第一步:当前解锁方式为LockScreen,或者需要Show Lock Before Unlock,这一步就通过了
    **第二步:其它方法调用updateScreen时通过force指明强制调用,或者LockScreen仍为空,还未创建,这一步就通过了
    */
    // Re-create the lock screen if necessary
    if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {
        if (force || mLockScreen == null) {
            recreateLockScreen();
        }
    }

    // Re-create the unlock screen if necessary. This is primarily required to properly handle
    // SIM state changes. This typically happens when this method is called by reset()
    if (mode == Mode.UnlockScreen) {
        final UnlockMode unlockMode = getUnlockMode();
        if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
            boolean restartFaceLock = stopFaceLockIfRunning();
            recreateUnlockScreen(unlockMode);
            if (restartFaceLock) activateFaceLockIfAble();
        }
    }

    /*
    **mLockScreen和mUnlockScreen分别代表LockScreen和UnlockScreen
    **goneScreen和visibleScreen则分别代表消失的和可见的,应该各选其一,同一时刻只有一个是可见的,且另一个是消失的
    */
    // visibleScreen should never be null
    final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;
    final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;

    // do this before changing visibility so focus isn't requested before the input
    // flag is set
    mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());


    if (mScreenOn) {
        if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {
            ((KeyguardScreen) goneScreen).onPause();
        }
        if (visibleScreen.getVisibility() != View.VISIBLE) {
            ((KeyguardScreen) visibleScreen).onResume();
        }
    }

    if (goneScreen != null) {
        goneScreen.setVisibility(View.GONE);
    }
    visibleScreen.setVisibility(View.VISIBLE);
    requestLayout();

}

五、recreateLockScreen方法

private void recreateLockScreen() {
    /*
    **如果mLockScreen已经存在,那么这时就处于强制再创建mLockScreen的状态
    **分别调用onPause、cleanUp方法,然后再removeView掉,之后再重新创建,设置可见,并添加到ViewGroup中
    **recreateUnlockScreen方法与此方法类似
    */
    if (mLockScreen != null) {
        ((KeyguardScreen) mLockScreen).onPause();
        ((KeyguardScreen) mLockScreen).cleanUp();
        removeView(mLockScreen);
    }

    mLockScreen = createLockScreen();
    mLockScreen.setVisibility(View.INVISIBLE);
    addView(mLockScreen);
}







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值