分析源码为 android 12
一、InputMonitor层面分析
在 WMS 添加,更新和删除Window 的时候都会调用 InputMonitor 的 updateInputWindowsLw 更新 window 信息。如下是删除window 时候的调用函数:
WMS.java
void removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit,int displayId) {synchronized (mGlobalLock) {final DisplayContent dc = mRoot.getDisplayContent(displayId);if (dc == null) {ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"+ " for non-exiting displayId=%d", binder, displayId);return;}final WindowToken token = dc.removeWindowToken(binder, animateExit);if (token == null) {ProtoLog.w(WM_ERROR,"removeWindowToken: Attempted to remove non-existing token: %s",binder);return;}if (removeWindows) {token.removeAllWindowsIfPossible();}// 调用 updateInputWindowsLwdc.getInputMonitor().updateInputWindowsLw(true /* force */);}}
updateInputWindowsLw 属于经常被外部调用的方法,它会最后触发到UpdateInputWindows 的 run 方法执行。
private class UpdateInputWindows implements Runnable {@Overridepublic void run() {synchronized (mService.mGlobalLock) {mUpdateInputWindowsPending = false;mUpdateInputWindowsNeeded = false;if (mDisplayRemoved) {return;}// Populate the input window list with information about all of the windows that// could potentially receive input.// As an optimization, we could try to prune the list of windows but this turns// out to be difficult because only the native code knows for sure which window// currently has touch focus.// If there's a drag in flight, provide a pseudo-window to catch drag inputfinal boolean inDrag = mService.mDragDropController.dragDropActiveLocked();// Add all windows on the default display.mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);}}}
最后会调用到mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);这个关键方法:
private final class UpdateInputForAllWindowsConsumer implements Consumer<WindowState> {InputConsumerImpl mPipInputConsumer;InputConsumerImpl mWallpaperInputConsumer;InputConsumerImpl mRecentsAnimationInputConsumer;private boolean mAddPipInputConsumerHandle;private boolean mAddWallpaperInputConsumerHandle;private boolean mAddRecentsAnimationInputConsumerHandle;boolean mInDrag;private void updateInputWindows(boolean inDrag) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");......mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);updateInputFocusRequest(mRecentsAnimationInputConsumer);......}Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}......
}
这里有调用了 mDisplayContent.forAllWindows方法来遍历每一个windowstate 执行自己的 accept 方法:
public void accept(WindowState w) {......
// 这里会对每个WindowState转换成inputWindowHandle信息,
// 不过要求得有surface才可以,意味处于NO_SURFACE是不会进入if (w.mWinAnimator.hasSurface()) {populateInputWindowHandle(inputWindowHandle, w);setInputWindowInfoIfNeeded(mInputTransaction,w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);}}
把 WindowState 转换成 inputWindowHandle 后接下来会把这个inputWindowHandle 信息设置给 mSurfaceControl
static void setInputWindowInfoIfNeeded(SurfaceControl.Transaction t, SurfaceControl sc,InputWindowHandleWrapper inputWindowHandle) {if (DEBUG_INPUT) {Slog.d(TAG_WM, "Update InputWindowHandle: " + inputWindowHandle);}if (inputWindowHandle.isChanged()) {inputWindowHandle.applyChangesToSurface(t, sc);}}
接下来来到 SurfaceControl.java 的
public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) {checkPreconditions(sc);nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle);return this;}
这里一看就是调用是 nativeSetInputWindowInfo 方法
static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactionObj,jlong nativeObject, jobject inputWindow) {auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);sp<NativeInputWindowHandle> handle = android_view_InputWindowHandle_getHandle(env, inputWindow);handle->updateInfo();auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);transaction->setInputWindowInfo(ctrl, *handle->getInfo());
}sp<NativeInputWindowHandle> android_view_InputWindowHandle_getHandle(JNIEnv* env, jobject inputWindowHandleObj) {if (!inputWindowHandleObj) {return NULL;}AutoMutex _l(gHandleMutex);jlong ptr = env->GetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr);NativeInputWindowHandle* handle;if (ptr) {//这个java端的ptr变量,主要功能就是为了保存对应native层面指针地址handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);} else {jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj);handle = new NativeInputWindowHandle(objWeak);//java层面对象作为了参数,方便后面调用java对象相关属性handle->incStrong((void*)android_view_InputWindowHandle_getHandle);env->SetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr,reinterpret_cast<jlong>(handle));}return handle;
}
重点看看 handle->updateInfo(),这个只截取部分:
bool NativeInputWindowHandle::updateInfo() {JNIEnv* env = AndroidRuntime::getJNIEnv();jobject obj = env->NewLocalRef(mObjWeak);if (!obj) {releaseChannel();return false;}mInfo.touchableRegion.clear();jobject tokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.token);if (tokenObj) {mInfo.token = ibinderForJavaObject(env, tokenObj);env->DeleteLocalRef(tokenObj);} else {mInfo.token.clear();}mInfo.name = getStringField(env, obj, gInputWindowHandleClassInfo.name, "<null>");mInfo.dispatchingTimeout = std::chrono::milliseconds(env->GetLongField(obj, gInputWindowHandleClassInfo.dispatchingTimeoutMillis));//这里可以看出主要就是对java的数据拷贝到这个mInfomInfo.frameLeft = env->GetIntField(obj,gInputWindowHandleClassInfo.frameLeft);env->DeleteLocalRef(obj);return true;
}
接下来看看 transaction->setInputWindowInfo(ctrl, *handle->getInfo()); 这里较为简单,知识把对应的WindowInfo数据传递给对应的layer_state_t,其实对应就是Layer
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(const sp<SurfaceControl>& sc, const WindowInfo& info) {layer_state_t* s = getLayerState(sc);if (!s) {mStatus = BAD_INDEX;return *this;}s->windowInfoHandle = new WindowInfoHandle(info);s->what |= layer_state_t::eInputInfoChanged;return *this;
}
那么到此总结一下:
1、InputMonitior遍历每个WindowState相关数据,当然得有surface的,毕竟和surfaceflinger打交道
2、然后把数据java 的InputWindow数据转化native的InputWindow数据,通过一步步传递到transition中,即保存到了layer_state_t中
调用transition的apply方法:
status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {//省略遍历目前mComposerStates对象,这里面包好目前的所有inputwindowfor (auto const& kv : mComposerStates){composerStates.add(kv.second);}
//跨进程调用setTransactionState把composerStates作为参数sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,hasListenerCallbacks, listenerCallbacks, mId);//省略mStatus = NO_ERROR;return NO_ERROR;
}
二、到达SurfaceFlinger层面分析
跨进程调用到了SurfaceFlinger中了:
status_t SurfaceFlinger::setTransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {TransactionState state{frameTimelineInfo, states,displays, flags,applyToken, inputWindowCommands,desiredPresentTime, isAutoTimestamp,uncacheBuffer, postTime,permissions, hasListenerCallbacks,listenerCallbacks, originPid,originUid, transactionId};//把TransactionState放入队列,且会启动对应的scheduleCommitqueueTransaction(state);// Check the pending state to make sure the transaction is synchronous.if (state.transactionCommittedSignal) {waitForSynchronousTransaction(*state.transactionCommittedSignal);}return NO_ERROR;
}
然后执行SurfaceFlinger对应的commit会调用applyTransactionState再通过
setClientStateLocked把传递过来的layer_state_t进行获取更新到SurfaceFlinger的Layer
依次往下调用updateInputFlinger,会调用buildWindowInfos把当前所有的layer中获取数据转化到WindowInfo
uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,ComposerState& composerState,int64_t desiredPresentTime, bool isAutoTimestamp,int64_t postTime, uint32_t permissions) {
//省略if (what & layer_state_t::eInputInfoChanged) {layer->setInputInfo(*s.windowInfoHandle->getInfo());flags |= eTraversalNeeded;}
//省略
}
这样就更新到了Layer中 接下来再调用updateInputFlinger
void SurfaceFlinger::updateInputFlinger() {//省略if (mVisibleRegionsDirty || mInputInfoChanged) {mInputInfoChanged = false;updateWindowInfo = true;//把WindowInfos搞出buildWindowInfos(windowInfos, displayInfos);}BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,windowInfos = std::move(windowInfos),displayInfos = std::move(displayInfos),inputWindowCommands =std::move(mInputWindowCommands),inputFlinger = mInputFlinger, this]() {if (updateWindowInfo) {//这里会触发通知mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,inputWindowCommands.syncInputWindows);} else if (inputWindowCommands.syncInputWindows) {// If the caller requested to sync input windows, but there are no// changes to input windows, notify immediately.windowInfosReported();}for (const auto& focusRequest : inputWindowCommands.focusRequests) {inputFlinger->setFocusedWindow(focusRequest);}}});mInputWindowCommands.clear();
}
这里看看buildWindowInfos
void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,std::vector<DisplayInfo>& outDisplayInfos) {//省略mDrawingState.traverseInReverseZOrder([&](Layer* layer) {if (!layer->needsInputInfo()) return;// Do not create WindowInfos for windows on displays that cannot receive input.if (const auto opt = displayInputInfos.get(layer->getLayerStack())) {const auto& info = opt->get();outWindowInfos.push_back(layer->fillInputInfo(info.transform, info.isSecure));//根据layer填满outWindowInfos信息}});sNumWindowInfos = outWindowInfos.size();outDisplayInfos.reserve(displayInputInfos.size());for (const auto& [_, info] : displayInputInfos) {outDisplayInfos.push_back(info.info);}
}
再接下来看看WindowInfo怎么传递通知出去给InputDispatch
void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,const std::vector<DisplayInfo>& displayInfos,bool shouldSync) {ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;{std::scoped_lock lock(mListenersMutex);for (const auto& [_, listener] : mWindowInfosListeners) {windowInfosListeners.push_back(listener);}}mCallbacksPending = windowInfosListeners.size();for (const auto& listener : windowInfosListeners) {//这里listener其实就是InputDispatherlistener->onWindowInfosChanged(windowInfos, displayInfos,shouldSync ? mWindowInfosReportedListener : nullptr);}
}
而后调用到InputDispatcher中
void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos,const std::vector<DisplayInfo>& displayInfos) {mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
}
完毕。