您的位置:首页 > 娱乐 > 八卦 > Android焦点之InputWindows的更新(一)

Android焦点之InputWindows的更新(一)

2024/12/22 17:16:03 来源:https://blog.csdn.net/wenwang88/article/details/140343358  浏览:    关键词:Android焦点之InputWindows的更新(一)

找到焦点窗口后,回到DisplayContent的updateFocusedWindowLocked方法中继续往下走 执行到此处会进行InputWindows的更新

InputMonitor#setInputFocusLw:以上过程伴随日志:WindowManager: Input focus has changed to Window{a44139a u0 NotificationShade} display=0

InputMonitor#updateInputWindowsLw:在该方法中,只有当强制更新或者mUpdateInputWindowsNeeded值为true时(在setUpdateInputWindowsNeededLw设置为true),才会进行InputWindows的更新

之后将执行scheduleUpdateInputWindows()方法,在这个方法中,会post一个Runnable对象mUpdateInputWindows,在mHandler所在的android.anim线程中执行更新流程:

接下来执行mUpdateInputForAllWindowsConsumer.updateInputWindows()方法。

mUpdateInputForAllWindowsConsumer.updateInputWindows: 在该方法中,首先会确认是否存在几类特殊的InputConsumer。InputConsumer用于读取事件,每个窗口对应的客户端都会通过InputConsumer来读取和消费事件,一般情况下,ViewRootImpl在添加窗口过程中,会在注册InputEventReceiver时自动创建InputConsumer对象。此处的特殊InputConsumer则是对一些系统UI显式地进行了创建:

然后,接mDisplayContent.forAllWindows 将发起所有WindowState的遍历,mUpdateInputForAllWindowsConsumer本身是一个Consumer接口对象,因此会回调accept()方法对每个WindowState进行处理:

以上方法中:

1.首先会对几类特殊InputConsumer进行单独处理;

2. 然后填充InputWindowHandle对象(populateInputWindowHandle);

3. 最后将InputWindowHandle对象设置给Transaction对象(setInputWindowInfoIfNeeded),并在事物提交后,由SurfaceFlinger设置给InputDispatcher中。

InputMonitor#populateInputWindowHandle:在该方法中,会将WindowState的部分属性填充给inputWindowHandle:

填充完毕InputWindowHandle后,调用setInputWindowInfoIfNeeded()方法,下面简单看一下InputWindowHandleWrapper这个类

 //InputWindowHandle的包装类
class InputWindowHandleWrapper {//所有的信息都设置到 mHandle 变量中private final @NonNull InputWindowHandle mHandle;boolean isChanged() {return mChanged;}//......void setTouchableRegion(Region region) {if (mHandle.touchableRegion.equals(region)) {return;}mHandle.touchableRegion.set(region);mChanged = true;}void applyChangesToSurface(@NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl sc) {t.setInputWindowInfo(sc, mHandle);mChanged = false;}//......
}@frameworks/base/core/java/android/view/InputWindowHandle.java
public final class InputWindowHandle {@Retention(RetentionPolicy.SOURCE)@IntDef(flag = true, value = {InputConfig.DEFAULT,InputConfig.NO_INPUT_CHANNEL,InputConfig.NOT_FOCUSABLE,InputConfig.NOT_TOUCHABLE,InputConfig.PREVENT_SPLITTING,InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,InputConfig.IS_WALLPAPER,InputConfig.PAUSE_DISPATCHING,InputConfig.TRUSTED_OVERLAY,InputConfig.WATCH_OUTSIDE_TOUCH,InputConfig.SLIPPERY,InputConfig.DISABLE_USER_ACTIVITY,InputConfig.SPY,InputConfig.INTERCEPTS_STYLUS,})        public InputApplicationHandle inputApplicationHandle;    // The window name.public String name;    public long dispatchingTimeoutMillis;public int frameLeft;public int frameTop;        // Window touchable region.public final Region touchableRegion = new Region();public int touchOcclusionMode = TouchOcclusionMode.BLOCK_UNTRUSTED;
}

 

InputMonitor#setInputWindowInfoIfNeeded:回到updateInputWindows()方法的,调用setInputWindowInfoIfNeeded将填充好的InputWindowHandle最终通过通过SurfaceFlinger设置给了InputDispatcher,

native层也有对应的surfacecontrol,刚刚封装的WindowInfo也被传递进来,后续统一apply(); BpBn调setClientStateLocked()时eInputInfoChanged更新inputInfo;

InputMonitor#updateInputFocusRequest:再回到InputMonitor#updateInputWindows中,接下先来看一下updateInputFocusRequest是如何打印“Focus request ”这条log的

接着看mInputTransaction.setFocusedWindow 这个方法,后续统一apply();BpBn调addInputWindowCommands()添加命令;

再次回到InputMonitor#updateInputWindows(),调用SurfaceControl.Transaction#merge,之后,当WindowAnimator.java的animate()时发起apply();可以是线程"android.anim"或"binder"线程;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com