Android 11 ANR

platform

     R K 3568 + A n d r o i d 11 RK3568 + Android 11 R K 3568+Android11

overview

The official note is
    that an "Application Not Responding" (ANR) error will be triggered if the UI thread of an Android application is blocked for too long. If the app is in the foreground, the system presents a dialog to the user, and the ANR dialog gives the user the option to force quit the app.

    ANR processing flow

  • First of all, the time definitions of the three ANRs:
        through debugging: view the dispatchingTimeout of the window information in the adb shell dumpsys input, different windows may be different, it depends on the actual time setting, the following three values ​​are all set to 5 seconds , the displayed value is 5 seconds.

App如Launhcer:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

	//当前的超时设置为5's
    public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;

Navigation bar and status bar of SystemUI:
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

///
//  这个时间关联到的是:                         //
///
    // Default input dispatching timeout in nanoseconds.
    static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
       h.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;

frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

// Default input dispatching timeout if there is no focused application or paused window
// from which to determine an appropriate dispatching timeout.
constexpr std::chrono::nanoseconds DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5s;
  • Second, the string definition (under the frameworks/base/core/res directory):
    <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g>没有响应"</string>
    <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g>没有响应"</string>
    <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g>没有响应"</string>
    <string name="anr_process" msgid="1664277165911816067">"进程“<xliff:g id="PROCESS">%1$s</xliff:g>”没有响应"</string>
    <string name="force_close" msgid="9035203496368973803">"确定"</string>
    <string name="report" msgid="2149194372340349521">"报告"</string>
    <string name="wait" msgid="7765985809494033348">"等待"</string>

timing

InputDispatcher com_android_server_input_InputManagerService InputManagerService InputManagerCallback ActivityRecord ActivityManagerService$LocalService ActivityManagerService AnrHelper AnrHelper.AnrConsumerThread AnrHelper.AnrRecord appNotResponding ProcessRecord AppErrors dispatchOnce(处理输入事件) processAnrsLocked(检测到ANR后) onAnrLocked notifyAnr notifyAnr notifyANR notifyANRInner keyDispatchingTimedOut inputDispatchingTimedOut inputDispatchingTimedOut appNotResponding run appNotResponding appNotResponding mUiHandler.sendMessage(SHOW_NOT_RESPONDING_UI_MSG) handleShowAnrUi InputDispatcher com_android_server_input_InputManagerService InputManagerService InputManagerCallback ActivityRecord ActivityManagerService$LocalService ActivityManagerService AnrHelper AnrHelper.AnrConsumerThread AnrHelper.AnrRecord appNotResponding ProcessRecord AppErrors

key code

frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

void InputDispatcher::doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) {
    
    
    sp<IBinder> token =
            commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
    mLock.unlock();

    const nsecs_t timeoutExtension =
            mPolicy->notifyAnr(commandEntry->inputApplicationHandle, token, commandEntry->reason);

    mLock.lock();

    if (timeoutExtension > 0) {
    
    
        extendAnrTimeoutsLocked(commandEntry->inputApplicationHandle, token, timeoutExtension);
    } else {
    
    
        // stop waking up for events in this connection, it is already not responding
        sp<Connection> connection = getConnectionLocked(token);
        if (connection == nullptr) {
    
    
            return;
        }
        cancelEventsForAnrLocked(connection);
    }
}

void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
    
    
    // Since we are allowing the policy to extend the timeout, maybe the waitQueue
    // is already healthy again. Don't raise ANR in this situation
    if (connection->waitQueue.empty()) {
    
    
        ALOGI("Not raising ANR because the connection %s has recovered",
              connection->inputChannel->getName().c_str());
        return;
    }
    /**
     * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
     * may not be the one that caused the timeout to occur. One possibility is that window timeout
     * has changed. This could cause newer entries to time out before the already dispatched
     * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
     * processes the events linearly. So providing information about the oldest entry seems to be
     * most useful.
     */
    DispatchEntry* oldestEntry = *connection->waitQueue.begin();
    const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
    std::string reason =
            android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
                                        connection->inputChannel->getName().c_str(),
                                        ns2ms(currentWait),
                                        oldestEntry->eventEntry->getDescription().c_str());

    updateLastAnrStateLocked(getWindowHandleLocked(connection->inputChannel->getConnectionToken()),
                             reason);
    std::unique_ptr<CommandEntry> commandEntry =
            std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
    commandEntry->inputApplicationHandle = nullptr;
    commandEntry->inputChannel = connection->inputChannel;
    commandEntry->reason = std::move(reason);
    postCommandLocked(std::move(commandEntry));
}

/**
 * Check if any of the connections' wait queues have events that are too old.
 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
 * Return the time at which we should wake up next.
 */
nsecs_t InputDispatcher::processAnrsLocked() {
    
    
    const nsecs_t currentTime = now();
    nsecs_t nextAnrCheck = LONG_LONG_MAX;
    // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
    if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
    
    
        if (currentTime >= *mNoFocusedWindowTimeoutTime) {
    
    
            onAnrLocked(mAwaitedFocusedApplication);
            mAwaitedFocusedApplication.clear();
            return LONG_LONG_MIN;
        } else {
    
    
            // Keep waiting
            const nsecs_t millisRemaining = ns2ms(*mNoFocusedWindowTimeoutTime - currentTime);
            ALOGW("Still no focused window. Will drop the event in %" PRId64 "ms", millisRemaining);
            nextAnrCheck = *mNoFocusedWindowTimeoutTime;
        }
    }

    // Check if any connection ANRs are due
    nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
    if (currentTime < nextAnrCheck) {
    
     // most likely scenario
        return nextAnrCheck;          // everything is normal. Let's check again at nextAnrCheck
    }

    // If we reached here, we have an unresponsive connection.
    sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
    if (connection == nullptr) {
    
    
        ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
        return nextAnrCheck;
    }
    connection->responsive = false;
    // Stop waking up for this unresponsive connection
    mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
	//ANR触发位置
    onAnrLocked(connection);
    return LONG_LONG_MIN;
}

void InputDispatcher::dispatchOnce() {
    
    
    nsecs_t nextWakeupTime = LONG_LONG_MAX;
    {
    
     // acquire lock
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();

        // Run a dispatch loop if there are no pending commands.
        // The dispatch loop might enqueue commands to run afterwards.
        if (!haveCommandsLocked()) {
    
    
            dispatchOnceInnerLocked(&nextWakeupTime);
        }

        // Run all pending commands if there are any.
        // If any commands were run then force the next poll to wake up immediately.
        if (runCommandsLockedInterruptible()) {
    
    
            nextWakeupTime = LONG_LONG_MIN;
        }

        // If we are still waiting for ack on some events,
        // we might have to wake up earlier to check if an app is anr'ing.
        const nsecs_t nextAnrCheck = processAnrsLocked();
        nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);

        // We are about to enter an infinitely long sleep, because we have no commands or
        // pending or queued events
        if (nextWakeupTime == LONG_LONG_MAX) {
    
    
            mDispatcherEnteredIdle.notify_all();
        }
    } // release lock

    // Wait for callback or timeout or wake.  (make sure we round up, not down)
    nsecs_t currentTime = now();
    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
    mLooper->pollOnce(timeoutMillis);
}

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

nsecs_t NativeInputManager::notifyAnr(const sp<InputApplicationHandle>& inputApplicationHandle,
                                      const sp<IBinder>& token, const std::string& reason) {
    
    
#if DEBUG_INPUT_DISPATCHER_POLICY
    ALOGD("notifyANR");
#endif
    ATRACE_CALL();

    JNIEnv* env = jniEnv();
    ScopedLocalFrame localFrame(env);

    jobject inputApplicationHandleObj =
            getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);

    jobject tokenObj = javaObjectForIBinder(env, token);
    jstring reasonObj = env->NewStringUTF(reason.c_str());

    jlong newTimeout = env->CallLongMethod(mServiceObj,
            gServiceClassInfo.notifyANR, inputApplicationHandleObj, tokenObj,
                 reasonObj);
    if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
    
    
        newTimeout = 0; // abort dispatch
    } else {
    
    
        assert(newTimeout >= 0);
    }
    return newTimeout;
}


    GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
            "notifyANR",
            "(Landroid/view/InputApplicationHandle;Landroid/os/IBinder;Ljava/lang/String;)J");

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java


    // Native callback.
    private long notifyANR(InputApplicationHandle inputApplicationHandle, IBinder token,
            String reason) {
    
    
        return mWindowManagerCallbacks.notifyANR(inputApplicationHandle,
                token, reason);
    }

frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java

    /**
     * Notifies the window manager about an application that is not responding.
     * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
     *
     * Called by the InputManager.
     */
    @Override
    public long notifyANR(InputApplicationHandle inputApplicationHandle, IBinder token,
            String reason) {
    
    
        final long startTime = SystemClock.uptimeMillis();
        try {
    
    
            return notifyANRInner(inputApplicationHandle, token, reason);
        } finally {
    
    
            // Log the time because the method is called from InputDispatcher thread. It shouldn't
            // take too long that may affect input response time.
            Slog.d(TAG_WM, "notifyANR took " + (SystemClock.uptimeMillis() - startTime) + "ms");
        }
    }

    private long notifyANRInner(InputApplicationHandle inputApplicationHandle, IBinder token,
            String reason) {
    
    
        ActivityRecord activity = null;
        WindowState windowState = null;
        boolean aboveSystem = false;
        int windowPid = INVALID_PID;

        preDumpIfLockTooSlow();

        //TODO(b/141764879) Limit scope of wm lock when input calls notifyANR
        synchronized (mService.mGlobalLock) {
    
    

            // Check if we can blame a window
            if (token != null) {
    
    
                windowState = mService.mInputToWindowMap.get(token);
                if (windowState != null) {
    
    
                    activity = windowState.mActivityRecord;
                    windowPid = windowState.mSession.mPid;
                    // Figure out whether this window is layered above system windows.
                    // We need to do this here to help the activity manager know how to
                    // layer its ANR dialog.
                    aboveSystem = isWindowAboveSystem(windowState);
                }
            }

            // Check if we can blame an embedded window
            if (token != null && windowState == null) {
    
    
                EmbeddedWindow embeddedWindow = mService.mEmbeddedWindowController.get(token);
                if (embeddedWindow != null) {
    
    
                    windowPid = embeddedWindow.mOwnerPid;
                    WindowState hostWindowState = embeddedWindow.mHostWindowState;
                    if (hostWindowState == null) {
    
    
                        // The embedded window has no host window and we cannot easily determine
                        // its z order. Try to place the anr dialog as high as possible.
                        aboveSystem = true;
                    } else {
    
    
                        aboveSystem = isWindowAboveSystem(hostWindowState);
                    }
                }
            }

            // Check if we can blame an activity. If we don't have an activity to blame, pull out
            // the token passed in via input application handle. This can happen if there are no
            // focused windows but input dispatcher knows the focused app.
            if (activity == null && inputApplicationHandle != null) {
    
    
                activity = ActivityRecord.forTokenLocked(inputApplicationHandle.token);
            }

            if (windowState != null) {
    
    
                Slog.i(TAG_WM, "Input event dispatching timed out "
                        + "sending to " + windowState.mAttrs.getTitle()
                        + ".  Reason: " + reason);
            } else if (activity != null) {
    
    
                Slog.i(TAG_WM, "Input event dispatching timed out "
                        + "sending to application " + activity.stringName
                        + ".  Reason: " + reason);
            } else {
    
    
                Slog.i(TAG_WM, "Input event dispatching timed out "
                        + ".  Reason: " + reason);
            }

            mService.saveANRStateLocked(activity, windowState, reason);
        }

        // All the calls below need to happen without the WM lock held since they call into AM.
        mService.mAtmInternal.saveANRState(reason);

        if (activity != null && activity.appToken != null) {
    
    
            // Notify the activity manager about the timeout and let it decide whether
            // to abort dispatching or keep waiting.
            final boolean abort = activity.keyDispatchingTimedOut(reason, windowPid);
            if (!abort) {
    
    
                // The activity manager declined to abort dispatching.
                // Wait a bit longer and timeout again later.
                return activity.mInputDispatchingTimeoutNanos;
            }
        } else if (windowState != null || windowPid != INVALID_PID) {
    
    
            // Notify the activity manager about the timeout and let it decide whether
            // to abort dispatching or keep waiting.
            long timeout = mService.mAmInternal.inputDispatchingTimedOut(windowPid, aboveSystem,
                    reason);
            if (timeout >= 0) {
    
    
                // The activity manager declined to abort dispatching.
                // Wait a bit longer and timeout again later.
                return timeout * 1000000L; // nanoseconds
            }
        }
        return 0; // abort dispatching
    }


frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
    
    
        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
    
    
            throw new SecurityException("Requires permission " + FILTER_EVENTS);
        }
        ProcessRecord proc;
        long timeout;
        synchronized (this) {
    
    
            synchronized (mPidsSelfLocked) {
    
    
                proc = mPidsSelfLocked.get(pid);
            }
            timeout = proc != null ? proc.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
        }

        if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, reason)) {
    
    
            return -1;
        }

        return timeout;
    }

    final class UiHandler extends Handler {
    
    
        //Ignored....
        @Override
        public void handleMessage(Message msg) {
    
    
            switch (msg.what) {
    
    
                case SHOW_ERROR_UI_MSG: {
    
    
                    mAppErrors.handleShowAppErrorUi(msg);
                    ensureBootCompleted();
                } break;
                case SHOW_NOT_RESPONDING_UI_MSG: {
    
    
                    mAppErrors.handleShowAnrUi(msg);
                    ensureBootCompleted();
                } break;
        //Ignored .....
     }

frameworks/base/services/core/java/com/android/server/am/AnrHelper.java

    void appNotResponding(ProcessRecord anrProcess, String annotation) {
    
    
        appNotResponding(anrProcess, null /* activityShortComponentName */, null /* aInfo */,
                null /* parentShortComponentName */, null /* parentProcess */,
                false /* aboveSystem */, annotation);
    }

    void appNotResponding(ProcessRecord anrProcess, String activityShortComponentName,
            ApplicationInfo aInfo, String parentShortComponentName,
            WindowProcessController parentProcess, boolean aboveSystem, String annotation) {
    
    
        synchronized (mAnrRecords) {
    
    
            mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName, aInfo,
                    parentShortComponentName, parentProcess, aboveSystem, annotation));
        }
        startAnrConsumerIfNeeded();
    }

    private void startAnrConsumerIfNeeded() {
    
    
        if (mRunning.compareAndSet(false, true)) {
    
    
            new AnrConsumerThread().start();
        }
    }

frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java

    void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
            String parentShortComponentName, WindowProcessController parentProcess,
            boolean aboveSystem, String annotation, boolean onlyDumpSelf) {
    
    
        //Ignored...

            // mUiHandler can be null if the AMS is constructed with injector only. This will only
            // happen in tests.
            if (mService.mUiHandler != null) {
    
    
                // Bring up the infamous App Not Responding dialog
                Message msg = Message.obtain();
                msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
                msg.obj = new AppNotRespondingDialog.Data(this, aInfo, aboveSystem);

                mService.mUiHandler.sendMessage(msg);
            }
        }
    }
    
class ErrorDialogControlle
        //AppErrors 调用
        void showAnrDialogs(AppNotRespondingDialog.Data data) {
    
    
            List<Context> contexts = getDisplayContexts(isSilentAnr() /* lastUsedOnly */);
            mAnrDialogs = new ArrayList<>();
            for (int i = contexts.size() - 1; i >= 0; i--) {
    
    
                final Context c = contexts.get(i);
                mAnrDialogs.add(new AppNotRespondingDialog(mService, c, data));
            }
            mService.mUiHandler.post(() -> {
    
    
                List<AppNotRespondingDialog> dialogs;
                synchronized (mService) {
    
    
                    dialogs = mAnrDialogs;
                }
                if (dialogs != null) {
    
    
                    forAllDialogs(dialogs, Dialog::show);
                }
            });
        }

frameworks/base/services/core/java/com/android/server/am/AppErrors.java

    void handleShowAnrUi(Message msg) {
    
    
        List<VersionedPackage> packageList = null;
        synchronized (mService) {
    
    
            AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
            final ProcessRecord proc = data.proc;
            if (proc == null) {
    
    
                Slog.e(TAG, "handleShowAnrUi: proc is null");
                return;
            }
            if (!proc.isPersistent()) {
    
    
                packageList = proc.getPackageListWithVersionCode();
            }
            if (proc.getDialogController().hasAnrDialogs()) {
    
    
                Slog.e(TAG, "App already has anr dialog: " + proc);
                MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
                        AppNotRespondingDialog.ALREADY_SHOWING);
                return;
            }

            boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
            if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) {
    
    
                proc.getDialogController().showAnrDialogs(data);
                //Ignored .....
   }

frameworks/base/services/core/java/com/android/server/am/AppNotRespondingDialog.java
对话框的代码就省略吧.

至此, 显示ANR对话框的流程走完
 


InputDispatcher中窗口句柄

SurfaceFlinger InputManager InputDispatcher updateInputFlinger updateInputWindowInfo setInputWindows setInputWindowsLocked SurfaceFlinger InputManager InputDispatcher

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::updateInputFlinger() {
    
    
    ATRACE_CALL();
    if (!mInputFlinger) {
    
    
        return;
    }

    if (mVisibleRegionsDirty || mInputInfoChanged) {
    
    
        mInputInfoChanged = false;
        updateInputWindowInfo();
    } else if (mInputWindowCommands.syncInputWindows) {
    
    
        // If the caller requested to sync input windows, but there are no
        // changes to input windows, notify immediately.
        setInputWindowsFinished();
    }

    mInputWindowCommands.clear();
}

void SurfaceFlinger::updateInputWindowInfo() {
    
    
    std::vector<InputWindowInfo> inputHandles;

    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
    
    
        if (layer->needsInputInfo()) {
    
    
            // When calculating the screen bounds we ignore the transparent region since it may
            // result in an unwanted offset.
            inputHandles.push_back(layer->fillInputInfo());
        }
    });

    mInputFlinger->setInputWindows(inputHandles,
                                   mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
                                                                         : nullptr);
}

frameworks/native/services/inputflinger/InputManager.cpp

void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos,
        const sp<ISetInputWindowsListener>& setInputWindowsListener) {
    
    
    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay;

    std::vector<sp<InputWindowHandle>> handles;
    for (const auto& info : infos) {
    
    
        handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
        handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
    }
    mDispatcher->setInputWindows(handlesPerDisplay);

    if (setInputWindowsListener) {
    
    
        setInputWindowsListener->onSetInputWindowsFinished();
    }
}

frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

///
//  通过InputManagerService 添加窗口句柄        //
///
/** 
 * Called from InputManagerService, update window handle list by displayId that can receive input.
 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
 * If set an empty list, remove all handles from the specific display.
 * For focused handle, check if need to change and send a cancel event to previous one.
 * For removed handle, check if need to send a cancel event if already in touch.
 */
void InputDispatcher::setInputWindowsLocked(){
    
    
	updateWindowHandlesForDisplayLocked...
}
///
//   更新mWindowHandlesByDisplay中            //
///
void InputDispatcher::updateWindowHandlesForDisplayLocked(
        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
    
    
    //Ignored.....
    // Insert or replace
    mWindowHandlesByDisplay[displayId] = newHandles;
}

///
//  从mWindowHandlesByDisplay中查询当前窗口     //
///
sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
        const sp<IBinder>& windowHandleToken) const {
    
    
    if (windowHandleToken == nullptr) {
    
    
        return nullptr;
    }

    for (auto& it : mWindowHandlesByDisplay) {
    
    
        const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
        for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
    
    
            if (windowHandle->getToken() == windowHandleToken) {
    
    
                return windowHandle;
            }
        }
    }
    return nullptr;
}

nsecs_t InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
    
    
    sp<InputWindowHandle> window = getWindowHandleLocked(token);
    if (window != nullptr) {
    
    
        return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT).count();
    }
    return DEFAULT_INPUT_DISPATCHING_TIMEOUT.count();
}

frameworks/base/services/core/java/com/android/server/wm/WindowProcessController.java

    public long getInputDispatchingTimeout() {
    
    
        synchronized (mAtm.mGlobalLock) {
    
    
            return isInstrumenting() || isUsingWrapper()
                    ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
        }
    }

frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java

    public long getInputDispatchingTimeout() {
    
    
        return mWindowProcessController.getInputDispatchingTimeout();
    }

扩展

编译及替换

#编译
mmm frameworks/native/services/inputflinger/ -j2

#替换
adb push out/target/product/rk3566_r/system/bin/inputflinger /system/bin/
adb push out/target/product/rk3566_r/system/lib/libinputflinger.so /system/lib/
adb push out/target/product/rk3566_r/system/lib64/libinputflinger.so /system/lib64/

调试: adb shell dumpsys input

      0: name='Window{57ce99a u0 NavigationBar0}', displayId=0, portalToDisplayId=-1, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x21840068, type=0x000007e3, frame=[0,752][1280,800], globalScale=1.000000, windowScale=(1.000000,1.000000), touchableRegion=[0,752][1280,800], inputFeatures=0x00000000, ownerPid=614, ownerUid=10119, dispatchingTimeout=7000ms
      1: name='Window{61c1033 u0 StatusBar}', displayId=0, portalToDisplayId=-1, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x81800408, type=0x000007d0, frame=[0,0][1280,24], globalScale=1.000000, windowScale=(1.000000,1.000000), touchableRegion=[0,0][1280,24], inputFeatures=0x00000000, ownerPid=614, ownerUid=10119, dispatchingTimeout=7000ms
      2: name='Window{e0e47c4 u0 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher}', displayId=0, portalToDisplayId=-1, paused=false, hasFocus=true, hasWallpaper=true, visible=true, canReceiveKeys=true, flags=0x81910120, type=0x00000001, frame=[0,0][1280,800], globalScale=1.000000, windowScale=(1.000000,1.000000), touchableRegion=[0,0][1280,800], inputFeatures=0x00000000, ownerPid=1039, ownerUid=10121, dispatchingTimeout=15000ms
      3: name='Window{bbadc9c u0 com.android.systemui.ImageWallpaper}', displayId=0, portalToDisplayId=-1, paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x00014318, type=0x000007dd, frame=[-64,-304][1344,1104], globalScale=1.000000, windowScale=(0.909091,0.909091), touchableRegion=[-64,-304][1344,1104], inputFeatures=0x00000000, ownerPid=614, ownerUid=10119, dispatchingTimeout=7000ms

参考

ANR
Android ANR:原理分析及解决办法

Guess you like

Origin blog.csdn.net/ansondroider/article/details/126957979