一、关于锁屏的模式
锁屏方式有两种,如下为定义方式
/** * 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 }
/** * 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 }
二、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; } } }
三、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; }
四、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); }