學徒淺析Android——Android Q隱藏在Lock中的小bug(一)

      距離上一篇文章過去半年了,要不是最近的一次偶然搜索,都快忘了這個賬號的密碼。谷歌還在一如既往的更新,我還在迷眼亂花中摸索。這不,最近在適配Android Q時,發現了一個源碼造成的bug,並且這個bug是AndroidQ變更造成的。具體的問題描述如下:  

 

 

解鎖模式爲password,在解鎖頁面輸入5次錯誤密碼,然後熄滅屏幕,等待30秒後,再進入解鎖頁面,此時輸入框無法獲取焦點,且無法通過點擊彈出軟鍵盤。

針對這種現象,我首先認爲一定是setEnable被製成了false。順着這個思路,我很幸運地在KeyguardPasswordView中發現了異常。因爲在AndroidP上並沒有聽說過這中問題,我比對了P和Q地代碼,有這樣一處變動:

p- KeyguardPasswordView
 

     @Override
     protected void resetState() {
         mSecurityMessageDisplay.setMessage("");
         final boolean wasDisabled = mPasswordEntry.isEnabled();
         setPasswordEntryEnabled(true);
         setPasswordEntryInputEnabled(true);
         if (wasDisabled) {
             mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
         }
     }

Q-KeyguardPasswordView
 

    @Override
    protected void resetState() {
        mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
        if (mSecurityMessageDisplay != null) {
            mSecurityMessageDisplay.setMessage("");
        }
        final boolean wasDisabled = mPasswordEntry.isEnabled();
        // Don't set enabled password entry & showSoftInput when PasswordEntry is invisible or in
        // pausing stage.
        if (!mResumed || !mPasswordEntry.isVisibleToUser()) {
            return;
        }
        setPasswordEntryEnabled(true);
        setPasswordEntryInputEnabled(true);
        if (wasDisabled) {
            mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
        }
    }

        // Don't set enabled password entry & showSoftInput when PasswordEntry is invisible or in
        // pausing stage.
        if (!mResumed || !mPasswordEntry.isVisibleToUser()) {
            return;
        }

和P相比,在setEnabled=true之前,Q多了上述處理。而這段代碼添加地原因在投入記錄

d62bfd20d0df5540f10d40bd950ba6172c5f6f34中是這樣描述的:
Author: lumark <[email protected]>
Date:   Thu Jan 10 15:29:11 2019 +0800

    Fix IME window pops up when unlock keyguard with fingerprint
    
    When in KeyguardPasswordView, hide IME window manually with pressing
    back key to back Keyguard view, and then unlock screen with fingerprint
    will find IME window pop up suddently.
    
    The reason is when KeyguardBouncer#hide will have a call path to pause
    KeyguardPasswordView & reset the state, but in resetState() will call
    IMM#showSoftInput even the password entry is invisible.
    
    Make sure to not call IMM#showSoftInput when KeyguardPasswordView is
    in pausing stage or password entry is invisible case to prevent
    IME pops up in unexpected way.
    
    Bug: 112811602
    Test: manual as the issue description
    Change-Id: I3c43d09d4206c48f1afcd8dad79e7978337f1b7d

也就是說這段代碼是爲了規避軟鍵盤在解鎖頁面不展示時突然彈出的問題,但很明顯,setEnable的處理也被阻礙了,lumark 改的有些愜意,也許那天天氣不錯,他想到了下班後的貓膩。

所以,真正的修改方案應該是這樣的,將setEnale和判斷調換一下位置:

    @Override
    protected void resetState() {
        mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
        if (mSecurityMessageDisplay != null) {
            mSecurityMessageDisplay.setMessage("");
        }
        final boolean wasDisabled = mPasswordEntry.isEnabled();

        setPasswordEntryEnabled(true);
        setPasswordEntryInputEnabled(true);
        // Don't set enabled password entry & showSoftInput when PasswordEntry is invisible or in
        // pausing stage.
        if (!mResumed || !mPasswordEntry.isVisibleToUser()) {
            return;
        }
        if (wasDisabled) {
            mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
        }
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章