接下来就到了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); }