keyguard學習--LockPatternKeyguardView

來源:互聯網
上載者:User

一、關於鎖屏的模式

鎖屏方式有兩種,如下為定義方式

 /**     * 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);}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.