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); }
相关推荐
逗脑IDE44 分钟前
零基础学ESP32:蓝牙控制舵机——手机一点,舵机就转!
android·智能手机
清霜之辰1 小时前
骁龙 8397 舱驾融合平台端侧大模型部署:7B 模型本地推理与 64GB 内存账本
android
烽火聊员1 小时前
Android屏幕卡顿traces.txt拉取查看
android·java·android studio
只睡四小时3 小时前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航
恋猫de小郭3 小时前
Android 原生的 Compose A2UI 也来了,你还抱着 XML 养老吗?
android·前端·flutter
程序媛_3 小时前
【JMeter】准备token文件
android·jmeter
维克兜率天3 小时前
【维克】弹性策略:用“乖离率“捕捉超跌反弹
android·开发语言·python·深度学习·kotlin·量化
古法安卓4 小时前
Android-Ext4文件系统问题排查
android·java·android studio
传奇开心果编程6 小时前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
生如夏花爱学习229668 小时前
贴心使用的语音生活小助手
android