Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edd96400 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Support ANRs from windows that are not tracked by WM

Previously, ANRs for gesture monitors were reported using the pid of the
owner, and ANRs for all windows were reported using its input channel,
which was tracked by WM.

Now, there can be input windows that are not tracked by WM. We unify the
ANR reporting pipeline so that we first try to report an ANR using the
window's input channel. If the ANR reporting fails because the input
channel was not tracked by WM, we fall back on reporting ANR via the
pid of the window owner.

Bug: 210978621
Test: atest inputflinger_tests
Change-Id: I7f71186e042b0fc9df7d342a549ef609ff4862ae
Merged-In: I7f71186e042b0fc9df7d342a549ef609ff4862ae
parent e73b8065
Loading
Loading
Loading
Loading
+3 −8
Original line number Original line Diff line number Diff line
@@ -61,18 +61,13 @@ private:
        ALOGE("There is no focused window for %s", applicationHandle->getName().c_str());
        ALOGE("There is no focused window for %s", applicationHandle->getName().c_str());
    }
    }


    void notifyWindowUnresponsive(const sp<IBinder>& connectionToken,
    void notifyWindowUnresponsive(const sp<IBinder>& connectionToken, std::optional<int32_t> pid,
                                  const std::string& reason) override {
                                  const std::string& reason) override {
        ALOGE("Window is not responding: %s", reason.c_str());
        ALOGE("Window is not responding: %s", reason.c_str());
    }
    }


    void notifyWindowResponsive(const sp<IBinder>& connectionToken) override {}
    void notifyWindowResponsive(const sp<IBinder>& connectionToken,

                                std::optional<int32_t> pid) override {}
    void notifyMonitorUnresponsive(int32_t pid, const std::string& reason) override {
        ALOGE("Monitor is not responding: %s", reason.c_str());
    }

    void notifyMonitorResponsive(int32_t pid) override {}


    void notifyInputChannelBroken(const sp<IBinder>&) override {}
    void notifyInputChannelBroken(const sp<IBinder>&) override {}


+25 −41
Original line number Original line Diff line number Diff line
@@ -5816,35 +5816,21 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>&
    }
    }
}
}


void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
    auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
        scoped_unlock unlock(mLock);
        mPolicy->notifyMonitorUnresponsive(pid, reason);
    };
    postCommandLocked(std::move(command));
}

void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
                                                          std::optional<int32_t> pid,
                                                          std::string reason) {
                                                          std::string reason) {
    auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
    auto command = [this, token, pid, reason = std::move(reason)]() REQUIRES(mLock) {
        scoped_unlock unlock(mLock);
        mPolicy->notifyWindowUnresponsive(token, reason);
    };
    postCommandLocked(std::move(command));
}

void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
    auto command = [this, pid]() REQUIRES(mLock) {
        scoped_unlock unlock(mLock);
        scoped_unlock unlock(mLock);
        mPolicy->notifyMonitorResponsive(pid);
        mPolicy->notifyWindowUnresponsive(token, pid, reason);
    };
    };
    postCommandLocked(std::move(command));
    postCommandLocked(std::move(command));
}
}


void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
    auto command = [this, connectionToken]() REQUIRES(mLock) {
                                                        std::optional<int32_t> pid) {
    auto command = [this, token, pid]() REQUIRES(mLock) {
        scoped_unlock unlock(mLock);
        scoped_unlock unlock(mLock);
        mPolicy->notifyWindowResponsive(connectionToken);
        mPolicy->notifyWindowResponsive(token, pid);
    };
    };
    postCommandLocked(std::move(command));
    postCommandLocked(std::move(command));
}
}
@@ -5857,22 +5843,21 @@ void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& conne
void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
                                                          std::string reason) {
                                                          std::string reason) {
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    std::optional<int32_t> pid;
    if (connection.monitor) {
    if (connection.monitor) {
        ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
        ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
              reason.c_str());
              reason.c_str());
        std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
        pid = findMonitorPidByTokenLocked(connectionToken);
        if (!pid.has_value()) {
    } else {
            ALOGE("Could not find unresponsive monitor for connection %s",
        // The connection is a window
                  connection.inputChannel->getName().c_str());
            return;
        }
        sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
        return;
    }
    // If not a monitor, must be a window
        ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
        ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
              reason.c_str());
              reason.c_str());
    sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
        const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
        if (handle != nullptr) {
            pid = handle->getInfo()->ownerPid;
        }
    }
    sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
}
}


/**
/**
@@ -5880,18 +5865,17 @@ void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& conn
 */
 */
void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    std::optional<int32_t> pid;
    if (connection.monitor) {
    if (connection.monitor) {
        std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
        pid = findMonitorPidByTokenLocked(connectionToken);
        if (!pid.has_value()) {
    } else {
            ALOGE("Could not find responsive monitor for connection %s",
        // The connection is a window
                  connection.inputChannel->getName().c_str());
        const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
            return;
        if (handle != nullptr) {
            pid = handle->getInfo()->ownerPid;
        }
        }
        sendMonitorResponsiveCommandLocked(pid.value());
        return;
    }
    }
    // If not a monitor, must be a window
    sendWindowResponsiveCommandLocked(connectionToken, pid);
    sendWindowResponsiveCommandLocked(connectionToken);
}
}


bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
+4 −4
Original line number Original line Diff line number Diff line
@@ -503,11 +503,11 @@ private:
     */
     */
    void processConnectionResponsiveLocked(const Connection& connection) REQUIRES(mLock);
    void processConnectionResponsiveLocked(const Connection& connection) REQUIRES(mLock);


    void sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) REQUIRES(mLock);
    void sendWindowUnresponsiveCommandLocked(const sp<IBinder>& connectionToken,
    void sendWindowUnresponsiveCommandLocked(const sp<IBinder>& connectionToken, std::string reason)
                                             std::optional<int32_t> pid, std::string reason)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void sendMonitorResponsiveCommandLocked(int32_t pid) REQUIRES(mLock);
    void sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken,
    void sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock);
                                           std::optional<int32_t> pid) REQUIRES(mLock);


    // Optimization: AnrTracker is used to quickly find which connection is due for a timeout next.
    // Optimization: AnrTracker is used to quickly find which connection is due for a timeout next.
    // AnrTracker must be kept in-sync with all responsive connection.waitQueues.
    // AnrTracker must be kept in-sync with all responsive connection.waitQueues.
+6 −17
Original line number Original line Diff line number Diff line
@@ -51,30 +51,19 @@ public:
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;


    /* Notifies the system that a window just became unresponsive. This indicates that ANR
    /* Notifies the system that a window just became unresponsive. This indicates that ANR
     * should be raised for this window. The window is identified via token.
     * should be raised for this window. The window can be identified via its input token and the
     * The string reason contains information about the input event that we haven't received
     * pid of the owner. The string reason contains information about the input event that we
     * a response for.
     * haven't received a response for.
     */
     */
    virtual void notifyWindowUnresponsive(const sp<IBinder>& token, const std::string& reason) = 0;
    virtual void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<int32_t> pid,
    /* Notifies the system that a monitor just became unresponsive. This indicates that ANR
                                          const std::string& reason) = 0;
     * should be raised for this monitor. The monitor is identified via its pid.
     * The string reason contains information about the input event that we haven't received
     * a response for.
     */
    virtual void notifyMonitorUnresponsive(int32_t pid, const std::string& reason) = 0;


    /* Notifies the system that a window just became responsive. This is only called after the
    /* Notifies the system that a window just became responsive. This is only called after the
     * window was first marked "unresponsive". This indicates that ANR dialog (if any) should
     * window was first marked "unresponsive". This indicates that ANR dialog (if any) should
     * no longer should be shown to the user. The window is eligible to cause a new ANR in the
     * no longer should be shown to the user. The window is eligible to cause a new ANR in the
     * future.
     * future.
     */
     */
    virtual void notifyWindowResponsive(const sp<IBinder>& token) = 0;
    virtual void notifyWindowResponsive(const sp<IBinder>& token, std::optional<int32_t> pid) = 0;
    /* Notifies the system that a monitor just became responsive. This is only called after the
     * monitor was first marked "unresponsive". This indicates that ANR dialog (if any) should
     * no longer should be shown to the user. The monitor is eligible to cause a new ANR in the
     * future.
     */
    virtual void notifyMonitorResponsive(int32_t pid) = 0;


    /* Notifies the system that an input channel is unrecoverably broken. */
    /* Notifies the system that an input channel is unrecoverably broken. */
    virtual void notifyInputChannelBroken(const sp<IBinder>& token) = 0;
    virtual void notifyInputChannelBroken(const sp<IBinder>& token) = 0;
+132 −134

File changed.

Preview size limit exceeded, changes collapsed.