(未完待续)
在Android中,对于App error有一个集中管理类:com.android.server.am.AppErrors
AppErrors.java
// 处理ANR void handleShowAnrUi(Message msg)
// 处理Crash void handleShowAppErrorUi(Message msg)
boolean handleAppCrashLocked(ProcessRecord app, String reason, String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data)
ANR调用顺序
InputManager.cpp
status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
// .......
}
InputDispatcher.cpp
bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();
return true;
}
InputDispatcher.cpp
void InputDispatcher::dispatchOnce() {
// .......
dispatchOnceInnerLocked(&nextWakeupTime);
// .......
}
InputDispatcher.cpp
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
// .......
done = dispatchMotionLocked(currentTime, typedEntry,
&dropReason, nextWakeupTime);
// .......
}
InputDispatcher.cpp
bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
// .......
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime, entry, inputTargets,
nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime, entry, inputTargets,
nextWakeupTime);
}
// .......
}
InputDispatcher.cpp
int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
// .......
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
mFocusedApplicationHandle, NULL, nextWakeupTime,
"Waiting because no window has focus but there is a "
"focused application that may eventually add a window "
"when it finishes starting up.");
// .......
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime, reason.string());
// ......
}
int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
const MotionEntry* entry, Vector<InputTarget>& inputTargets,
nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
// .......
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
NULL, touchedWindow.windowHandle, nextWakeupTime, reason.string());
// .......
}
InputDispatcher.cpp
int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
const sp<InputApplicationHandle>& applicationHandle,
const sp<InputWindowHandle>& windowHandle,
nsecs_t* nextWakeupTime, const char* reason) {
// ......
onANRLocked(currentTime, applicationHandle, windowHandle, entry->eventTime, mInputTargetWaitStartTime, reason);
// ......
}
InputDispatcher.cpp
void InputDispatcher::onANRLocked(nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
const sp<InputWindowHandle>& windowHandle, nsecs_t eventTime,
nsecs_t waitStartTime, const char* reason) {
// ......
CommandEntry* commandEntry = postCommandLocked(& InputDispatcher::doNotifyANRLockedInterruptible);
// ......
}
InputDispatcher.cpp
void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
// ......
nsecs_t newTimeout = mPolicy->notifyANR(commandEntry->inputApplicationHandle,
commandEntry->inputWindowHandle, commandEntry->reason);
// ......
}
com_android_server_input_InputManagerService.cpp
nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) {
// ......
jlong newTimeout = env->CallLongMethod(mServiceObj,
gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj,
reasonObj);
// ......
}
InputManagerService.java
private long notifyANR(InputApplicationHandle inputApplicationHandle,
InputWindowHandle inputWindowHandle, String reason) {
return mWindowManagerCallbacks.notifyANR(
inputApplicationHandle, inputWindowHandle, reason);
}
InputMonitor.java
@Override
public long notifyANR(InputApplicationHandle inputApplicationHandle,
InputWindowHandle inputWindowHandle, String reason) {
// ......
long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
windowState.mSession.mPid, aboveSystem, reason);
// ......
}
ActivityManagerService.java
@Override
public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
// ......
if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
return -1;
}
// ......
}
ActivityManagerService.java
public boolean inputDispatchingTimedOut(final ProcessRecord proc,
final ActivityRecord activity, final ActivityRecord parent,
final boolean aboveSystem, String reason) {
// ......
mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
// ......
}
AppErrors.java
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
ActivityRecord parent, boolean aboveSystem, final String annotation) {
// ......
msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
msg.obj = map;
msg.arg1 = aboveSystem ? 1 : 0;
// ......
mService.mUiHandler.sendMessage(msg);
}
ActivityManagerService$UiHandler.java
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// .......
case SHOW_NOT_RESPONDING_UI_MSG: {
mAppErrors.handleShowAnrUi(msg);
ensureBootCompleted();
} break;
// .......
}
}
AppErrors.java
void handleShowAnrUi(Message msg) {
// .......
}