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侧

@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焦点FocusWindow切换流程

    2024-07-13 21:50:06       20 阅读
  2. Android焦点Focused Window的更新(二)

    2024-07-13 21:50:06       20 阅读
  3. Android 音频焦点管理

    2024-07-13 21:50:06       55 阅读
  4. Android音频焦点

    2024-07-13 21:50:06       26 阅读
  5. Android Audio Focus 音频焦点

    2024-07-13 21:50:06       64 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 21:50:06       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 21:50:06       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 21:50:06       58 阅读
  4. Python语言-面向对象

    2024-07-13 21:50:06       69 阅读

热门阅读

  1. 基于深度学习的语言生成

    2024-07-13 21:50:06       22 阅读
  2. 华为OD机考题(HJ6 质数因子)

    2024-07-13 21:50:06       22 阅读
  3. (day11)1614. 括号的最大嵌套深度

    2024-07-13 21:50:06       19 阅读
  4. anaconda常用指令学习

    2024-07-13 21:50:06       18 阅读
  5. paddlenlp cpu windows 下测试gpt

    2024-07-13 21:50:06       21 阅读
  6. 维度评分:Kylin Cube设计中的自定义智能

    2024-07-13 21:50:06       21 阅读
  7. ArcGIS Pro SDK (九)几何 1 空间参考

    2024-07-13 21:50:06       17 阅读
  8. 树和二叉树_4

    2024-07-13 21:50:06       22 阅读
  9. centos7安装mongodb

    2024-07-13 21:50:06       16 阅读