分析源码为 android 12
在 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();
}
// 调用 updateInputWindowsLw
dc.getInputMonitor().updateInputWindowsLw(true /* force */);
}
}
updateInputWindowsLw 属于经常被外部调用的方法,它会最后触发到UpdateInputWindows 的 run 方法执行。
private class UpdateInputWindows implements Runnable {
@Override
public 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 input
final 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, "" );
mInfo.dispatchingTimeout = std::chrono::milliseconds(
env->GetLongField(obj, gInputWindowHandleClassInfo.dispatchingTimeoutMillis));
//这里可以看出主要就是对java的数据拷贝到这个mInfo
mInfo.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对象,这里面包好目前的所有inputwindow
for (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中了:
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放入队列,且会启动对应的scheduleCommit
queueTransaction(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其实就是InputDispather
listener->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);
}
完毕。