学徒浅析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
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);
        }
    }

 

 

你可能感兴趣的:(Android开发,Lock,解锁,Android源码,Android10,Lock解锁)