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); }
相关推荐
没有晚不了安10 分钟前
1.11作业
android
zhangphil13 分钟前
Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)
android·kotlin
貂蝉空大1 小时前
uni-app开发安卓和ios app 真机调试
android·ios·uni-app
少年芒2 小时前
Leetcode 490 迷宫
android·算法·leetcode
IT猿手2 小时前
2025最新智能优化算法:鲸鱼迁徙算法(Whale Migration Algorithm,WMA)求解23个经典函数测试集,MATLAB
android·数据库·人工智能·算法·机器学习·matlab·无人机
兰琛3 小时前
12.1 Android中协程的基本使用
android
liujingtech5 小时前
Kotlin实践下来 takeIf 并不是所有场景的银弹
android
xvch6 小时前
Kotlin 2.1.0 入门教程(二十三)泛型、泛型约束、协变、逆变、不变
android·kotlin
ianozo7 小时前
BUU40 [安洵杯 2019]easy_serialize_php
android·开发语言·php
abs6257 小时前
uniapp使用uts插件启动原生安卓Service
android·uni-app·uniapp uts插件·uniapp 安卓服务