Android焦点之SurfaceFlinger传递给InputFinger

接下来就到了SurfaceFlinger端,内调ISurfaceComposer的setTransactionState()

SurfaceFlinger::setTransactionState:这里是一个BpBn操作,进程surfaceflinger的binder线程,主要是调用到SurfaceFlinger.cpp的setTransactionState()。

在每次SurfaceFlinger主线程进行commit操作的时候,都会调用一次updateInputFlinger方法去更新一遍需要派发给InputDispatcher的窗口信息,代码如下:

SurfaceFlinger::updateInputFlinger:

需要出现在InputDispatcher的窗口列表中,在SurfaceFlinger这里需要满足两个条件:

对应Layer存在于SurfaceFlinger所维护的Layer列表中,

对应Layer需要满足needsInputInfo条件。

对于第一个条件,当Layer对应Surface没有被上层destroy时,才会存在于SurfaceFlinger的Layer列表中。(上层移除Surface的时机一般为对应窗口退出动画执行完毕时,由relayoutWindow流程发起)

对于第二个条件,需要对应窗口的inputChannelToken建立且没有被移除。

Layer::fillInputInfo 设置可见性, 对于具有InputInfo的Layer,走的是canReceiveInput的逻辑判断当前是否可见:

这里通过三个条件作可见性判断:

isHiddenByPolicy:这里会检查目标Layer的flag是否带有不可见标识

mBufferInfo.mBuffer:buffer为空即满足可见条件

getAlpha:Alpha值大于0,非透明即可见

详细的有关layer可见性的本篇不再继续跟踪

WindowInfosListenerInvoker::windowInfosChanged: windowInfosChanged方法能够将WindowInfo的变化通知到InputDispatcher。

内调InputDispatcher.cpp内部类DispatcherWindowListener的onWindowInfosChanged();

遍历,handlesPerDisplay,调setInputWindowsLocked() 由sf侧传递给input侧

java 复制代码
@frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::setTransactionState
    queueTransaction(state);  // 将TransactionState入队,该方法会触发相应的Commit操作
        mTransactionQueue.emplace(state);
        
SurfaceFlinger::onMessageInvalidate   //最新版本改成SurfaceFlinger::commit
    updateInputFlinger();
        if (mVisibleRegionsDirty || mInputInfoChanged) {
            mInputInfoChanged = false;
            notifyWindowInfos(); 
                mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
                    sp<DisplayDevice> display = enablePerWindowInputRotation() ? ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)) : nullptr;     
@frameworks/native/services/surfaceflinger/Layer.cpp                    
                    windowInfos.push_back(layer->fillInputInfo(display));
                        WindowInfo info = mDrawingState.inputInfo;
                        info.visible = hasInputInfo() ? canReceiveInput() : isVisible();  // 设置WindowInfo可见性, 对于具不具备InputInfo的layer,有两种可见性的判断逻辑,对于输入窗口,走canReceiveInput
                            return !isHiddenByPolicy();  //isHiddenByPolicy:这里会检查目标Layer的flag是否带有不可见标识
                                return s.flags & layer_state_t::eLayerHidden;
@frameworks/native/services/surfaceflinger/WindowInfosListenerInvoker.cpp
                //通知InputDispatcher更新窗口列表信息                  
                mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, mInputWindowCommands.syncInputWindows);  
                // listener其实就是InputDispather
                for (const auto& listener : windowInfosListeners) { listener->onWindowInfosChanged(windowInfos, shouldSync ? mWindowInfosReportedListener : nullptr);   }
@frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
                    //确保我们为所有现有显示器创建了一个条目,以便如果 displayId 没有窗口,我们可以知道窗口已从显示器中删除。
                    for (const auto& info : windowInfos) {
                        handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
                        handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));}
                    setInputWindows(handlesPerDisplay);                        
                        for (const auto& [displayId, handles] : handlesPerDisplay) { setInputWindowsLocked(handles, displayId); } //遍历,handlesPerDisplay,调setInputWindowsLocked()
        }
        // focusRequests也是从InputMonitor传过来的,InputMonitor的updateInputFocusRequest方法最后会调用requestFocus方法,requestFocus方法里面会往InputTransaction里设置focus window。
        for (const auto& focusRequest : inputWindowCommands.focusRequests) { mInputFlinger->setFocusedWindow(focusRequest); }
相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui