在Input ANR中,有一类ANR打印的reason 为 “xx does not have a focused window” ,表明 输入事件 5s 内,只有FocusedApplication,而没找到focused window。本文分析下FocusedApplication的设置过程。
setFocusedApp
源码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
setFocusedApp被几处地方调用,最常见的就是打开应用时,在realStartActivityLocked方法里面调用。调用链如下:
07-01 13:27:36.475 456 2006 D test : java.lang.Exception
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.DisplayContent.setFocusedApp(DisplayContent.java:3356)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.DisplayContent.setFocusedApp(DisplayContent.java:5603)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.ActivityTaskManagerService.setResumedActivityUncheckLocked(ActivityTaskManagerService.java:5482)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.Task.onActivityStateChanged(Task.java:1897)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.ActivityRecord.setState(ActivityRecord.java:4425)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.ActivityStack.minimalResumeActivityLocked(ActivityStack.java:947)
07-01 13:27:36.475 456 2006 D test : at com.android.server.wm.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:919)
直接从setFocusedApp开始分析
//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
boolean setFocusedApp(ActivityRecord newFocus) {
//省略
mFocusedApp = newFocus; //可以在dumpsys window 中看到,在wms端,焦点app是哪个
getInputMonitor().setFocusedAppLw(newFocus);
updateTouchExcludeRegion();
return true;
}
setFocusedAppLw
//frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
public void setFocusedAppLw(ActivityRecord newApp) {
// Focused app has changed.
mService.mInputManager.setFocusedApplication(mDisplayId,
newApp != null ? newApp.getInputApplicationHandle(true /* update */) : null);
}
setFocusedApplication
//frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public void setFocusedApplication(int displayId, InputApplicationHandle application) {
nativeSetFocusedApplication(mPtr, displayId, application);
}
接下来就进入到Native层
nativeSetFocusedApplication
//frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
jlong ptr, jint displayId, jobject applicationHandleObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setFocusedApplication(env, displayId, applicationHandleObj);
}
void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
jobject applicationHandleObj) {
sp<InputApplicationHandle> applicationHandle =
android_view_InputApplicationHandle_getHandle(env, applicationHandleObj);
mInputManager->getDispatcher()->setFocusedApplication(displayId, applicationHandle);
}
setFocusedApplication
void InputDispatcher::setFocusedApplication(
int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) {
if (DEBUG_FOCUS) {
ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
}
{ // acquire lock
std::scoped_lock _l(mLock);
sp<InputApplicationHandle> oldFocusedApplicationHandle =
getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
if (oldFocusedApplicationHandle == mAwaitedFocusedApplication &&
inputApplicationHandle != oldFocusedApplicationHandle) {
resetNoFocusedWindowTimeoutLocked();
}
if (inputApplicationHandle != nullptr && inputApplicationHandle->updateInfo()) {
if (oldFocusedApplicationHandle != inputApplicationHandle) {
mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;//保存到mFocusedApplicationHandlesByDisplay容器中
}
} else if (oldFocusedApplicationHandle != nullptr) {
oldFocusedApplicationHandle.clear();
mFocusedApplicationHandlesByDisplay.erase(displayId);
}
} // release lock
// Wake up poll loop since it may need to make new input dispatching choices.
mLooper->wake();
}
可以看出,最终保存到 mFocusedApplicationHandlesByDisplay容器中。 key事件的传输过程中,去查找焦点app时,就是在该容器中查找
总结
FocusedApplication的设置是直接由WMS设置给了InputDispatcher,不需要经过Surfaceflinger
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Andorid 11 InputDispatcher FocusedApplication设置过程分析
发表评论 取消回复