最近在分析一个客户问题:设备在使用一段时间后,输入法框diag无法正常显示。
public class InputMethodManagerService extends IInputMethodManager.Stubimplements ServiceConnection, Handler.Callback {static final boolean DEBUG = false;static final String TAG = "InputMethodManagerService";@Retention(SOURCE)@IntDef({ShellCommandResult.SUCCESS, ShellCommandResult.FAILURE})private @interface ShellCommandResult {int SUCCESS = 0;int FAILURE = -1;}public class InputManagerService extends IInputManager.Stubimplements Watchdog.Monitor {static final String TAG = "InputManager";static final boolean DEBUG = false;
将上述两个地方的DEBUG设置为true后,发现输入法show hide流程log都是正常的。
同时输入法异常时,home和recent键失效。
通过分析客户的代码发现,可以app 在接受网络消息后,通过disableKeyguard hide 锁屏界面,此时设备最上层app显示。
但是由于锁屏并没有真正disable,而是在上层app之下。
继续分析InputMethod发现,在InputMethodManagerService.java 中存在是否锁屏的判断
private boolean isScreenLocked() {return mKeyguardManager != null&& mKeyguardManager.isKeyguardLocked() && mKeyguardManager.isKeyguardSecure();}
InputMethodSubtypeSwitchingController.java public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean includeAuxiliarySubtypes, boolean isScreenLocked) {final ArrayList<ImeSubtypeListItem> imList = new ArrayList<>();final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(mContext);if (immis == null || immis.size() == 0) {return Collections.emptyList();}if (isScreenLocked && includeAuxiliarySubtypes) {if (DEBUG) {Slog.w(TAG, "Auxiliary subtypes are not allowed to be shown in lock screen.");}includeAuxiliarySubtypes = false;}mSortedImmis.clear();mSortedImmis.putAll(immis);for (InputMethodInfo imi : mSortedImmis.keySet()) {if (imi == null) {continue;}
Slog.w(TAG, “Auxiliary subtypes are not allowed to be shown in lock screen.”); 上述log,说明google设计思路,在没有解锁时,输入法diag是不允许显示。
解决方案:
在systemui中处理解锁流程。具体略
同时可以通过 adb shell dumpsys window p 来判断输入法可以弹框。