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

Commit f5dc0777 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Split monitor and window ANR notification paths"

parents 4e5ad3e5 3c63fa47
Loading
Loading
Loading
Loading
+10 −4
Original line number Original line Diff line number Diff line
@@ -55,12 +55,18 @@ 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 notifyConnectionUnresponsive(const sp<IBinder>& connectionToken,
    void notifyWindowUnresponsive(const sp<IBinder>& connectionToken,
                                  const std::string& reason) override {
                                  const std::string& reason) override {
        ALOGE("Connection is not responding: %s", reason.c_str());
        ALOGE("Window is not responding: %s", reason.c_str());
    }
    }


    void notifyConnectionResponsive(const sp<IBinder>& connectionToken) override {}
    void notifyWindowResponsive(const sp<IBinder>& connectionToken) 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 {}


+1 −0
Original line number Original line Diff line number Diff line
@@ -271,6 +271,7 @@ struct CommandEntry {
    sp<IBinder> newToken;
    sp<IBinder> newToken;
    std::string obscuringPackage;
    std::string obscuringPackage;
    bool enabled;
    bool enabled;
    int32_t pid;
};
};


} // namespace android::inputdispatcher
} // namespace android::inputdispatcher
+133 −30
Original line number Original line Diff line number Diff line
@@ -453,6 +453,20 @@ static KeyEvent createKeyEvent(const KeyEntry& entry) {
    return event;
    return event;
}
}


static std::optional<int32_t> findMonitorPidByToken(
        const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
        const sp<IBinder>& token) {
    for (const auto& it : monitorsByDisplay) {
        const std::vector<Monitor>& monitors = it.second;
        for (const Monitor& monitor : monitors) {
            if (monitor.inputChannel->getConnectionToken() == token) {
                return monitor.pid;
            }
        }
    }
    return std::nullopt;
}

// --- InputDispatcher ---
// --- InputDispatcher ---


InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
@@ -615,7 +629,7 @@ nsecs_t InputDispatcher::processAnrsLocked() {
    connection->responsive = false;
    connection->responsive = false;
    // Stop waking up for this unresponsive connection
    // Stop waking up for this unresponsive connection
    mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
    mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
    onAnrLocked(*connection);
    onAnrLocked(connection);
    return LONG_LONG_MIN;
    return LONG_LONG_MIN;
}
}


@@ -5154,6 +5168,14 @@ std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
    return std::nullopt;
    return std::nullopt;
}
}


std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
    std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
    if (gesturePid.has_value()) {
        return gesturePid;
    }
    return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
}

sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
    if (inputConnectionToken == nullptr) {
    if (inputConnectionToken == nullptr) {
        return nullptr;
        return nullptr;
@@ -5214,12 +5236,15 @@ void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
    postCommandLocked(std::move(commandEntry));
    postCommandLocked(std::move(commandEntry));
}
}


void InputDispatcher::onAnrLocked(const Connection& connection) {
void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
    if (connection == nullptr) {
        LOG_ALWAYS_FATAL("Caller must check for nullness");
    }
    // Since we are allowing the policy to extend the timeout, maybe the waitQueue
    // Since we are allowing the policy to extend the timeout, maybe the waitQueue
    // is already healthy again. Don't raise ANR in this situation
    // is already healthy again. Don't raise ANR in this situation
    if (connection.waitQueue.empty()) {
    if (connection->waitQueue.empty()) {
        ALOGI("Not raising ANR because the connection %s has recovered",
        ALOGI("Not raising ANR because the connection %s has recovered",
              connection.inputChannel->getName().c_str());
              connection->inputChannel->getName().c_str());
        return;
        return;
    }
    }
    /**
    /**
@@ -5230,21 +5255,20 @@ void InputDispatcher::onAnrLocked(const Connection& connection) {
     * processes the events linearly. So providing information about the oldest entry seems to be
     * processes the events linearly. So providing information about the oldest entry seems to be
     * most useful.
     * most useful.
     */
     */
    DispatchEntry* oldestEntry = *connection.waitQueue.begin();
    DispatchEntry* oldestEntry = *connection->waitQueue.begin();
    const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
    const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
    std::string reason =
    std::string reason =
            android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
            android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
                                        connection.inputChannel->getName().c_str(),
                                        connection->inputChannel->getName().c_str(),
                                        ns2ms(currentWait),
                                        ns2ms(currentWait),
                                        oldestEntry->eventEntry->getDescription().c_str());
                                        oldestEntry->eventEntry->getDescription().c_str());
    sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
    sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
    updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
    updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);


    std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
    processConnectionUnresponsiveLocked(*connection, std::move(reason));
            &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);

    commandEntry->connectionToken = connectionToken;
    // Stop waking up for events on this connection, it is already unresponsive
    commandEntry->reason = std::move(reason);
    cancelEventsForAnrLocked(connection);
    postCommandLocked(std::move(commandEntry));
}
}


void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
@@ -5329,26 +5353,34 @@ void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry
    mLock.lock();
    mLock.lock();
}
}


void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
        CommandEntry* commandEntry) {
    mLock.unlock();
    mLock.unlock();


    mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
    mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);


    mLock.lock();
    mLock.lock();
}


    // stop waking up for events in this connection, it is already not responding
void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
    sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
    mLock.unlock();
    if (connection == nullptr) {

        return;
    mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);

    mLock.lock();
}
}
    cancelEventsForAnrLocked(connection);

void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
    mLock.unlock();

    mPolicy->notifyWindowResponsive(commandEntry->connectionToken);

    mLock.lock();
}
}


void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
    mLock.unlock();
    mLock.unlock();


    mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
    mPolicy->notifyMonitorResponsive(commandEntry->pid);


    mLock.lock();
    mLock.lock();
}
}
@@ -5453,13 +5485,8 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c
        if (!connection->responsive) {
        if (!connection->responsive) {
            connection->responsive = isConnectionResponsive(*connection);
            connection->responsive = isConnectionResponsive(*connection);
            if (connection->responsive) {
            if (connection->responsive) {
                // The connection was unresponsive, and now it's responsive. Tell the policy
                // The connection was unresponsive, and now it's responsive.
                // about it so that it can stop ANR.
                processConnectionResponsiveLocked(*connection);
                std::unique_ptr<CommandEntry> connectionResponsiveCommand =
                        std::make_unique<CommandEntry>(
                                &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
                connectionResponsiveCommand->connectionToken = connectionToken;
                postCommandLocked(std::move(connectionResponsiveCommand));
            }
            }
        }
        }
        traceWaitQueueLength(connection);
        traceWaitQueueLength(connection);
@@ -5475,6 +5502,82 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c
    startDispatchCycleLocked(now(), connection);
    startDispatchCycleLocked(now(), connection);
}
}


void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
    std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
    monitorUnresponsiveCommand->pid = pid;
    monitorUnresponsiveCommand->reason = std::move(reason);
    postCommandLocked(std::move(monitorUnresponsiveCommand));
}

void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
                                                          std::string reason) {
    std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
    windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
    windowUnresponsiveCommand->reason = std::move(reason);
    postCommandLocked(std::move(windowUnresponsiveCommand));
}

void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
    std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
    monitorResponsiveCommand->pid = pid;
    postCommandLocked(std::move(monitorResponsiveCommand));
}

void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
    std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
    windowResponsiveCommand->connectionToken = std::move(connectionToken);
    postCommandLocked(std::move(windowResponsiveCommand));
}

/**
 * Tell the policy that a connection has become unresponsive so that it can start ANR.
 * Check whether the connection of interest is a monitor or a window, and add the corresponding
 * command entry to the command queue.
 */
void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
                                                          std::string reason) {
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    if (connection.monitor) {
        ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
              reason.c_str());
        std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
        if (!pid.has_value()) {
            ALOGE("Could not find unresponsive monitor for connection %s",
                  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(),
          reason.c_str());
    sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
}

/**
 * Tell the policy that a connection has become responsive so that it can stop ANR.
 */
void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
    const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
    if (connection.monitor) {
        std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
        if (!pid.has_value()) {
            ALOGE("Could not find responsive monitor for connection %s",
                  connection.inputChannel->getName().c_str());
            return;
        }
        sendMonitorResponsiveCommandLocked(pid.value());
        return;
    }
    // If not a monitor, must be a window
    sendWindowResponsiveCommandLocked(connectionToken);
}

bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
                                                       DispatchEntry* dispatchEntry,
                                                       DispatchEntry* dispatchEntry,
                                                       KeyEntry& keyEntry, bool handled) {
                                                       KeyEntry& keyEntry, bool handled) {
+37 −5
Original line number Original line Diff line number Diff line
@@ -233,6 +233,8 @@ private:
    // Finds the display ID of the gesture monitor identified by the provided token.
    // Finds the display ID of the gesture monitor identified by the provided token.
    std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token)
    std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token)
            REQUIRES(mLock);
            REQUIRES(mLock);
    // Find a monitor pid by the provided token.
    std::optional<int32_t> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock);


    // Input channels that will receive a copy of all input events sent to the provided display.
    // Input channels that will receive a copy of all input events sent to the provided display.
    std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay GUARDED_BY(mLock);
    std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay GUARDED_BY(mLock);
@@ -432,6 +434,34 @@ private:
    int32_t mAwaitedApplicationDisplayId GUARDED_BY(mLock);
    int32_t mAwaitedApplicationDisplayId GUARDED_BY(mLock);
    void processNoFocusedWindowAnrLocked() REQUIRES(mLock);
    void processNoFocusedWindowAnrLocked() REQUIRES(mLock);


    /**
     * Tell policy about a window or a monitor that just became unresponsive. Starts ANR.
     */
    void processConnectionUnresponsiveLocked(const Connection& connection, std::string reason)
            REQUIRES(mLock);
    /**
     * Tell policy about a window or a monitor that just became responsive.
     */
    void processConnectionResponsiveLocked(const Connection& connection) REQUIRES(mLock);

    /**
     * Post `doNotifyMonitorUnresponsiveLockedInterruptible` command.
     */
    void sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) REQUIRES(mLock);
    /**
     * Post `doNotifyWindowUnresponsiveLockedInterruptible` command.
     */
    void sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken, std::string reason)
            REQUIRES(mLock);
    /**
     * Post `doNotifyMonitorResponsiveLockedInterruptible` command.
     */
    void sendMonitorResponsiveCommandLocked(int32_t pid) REQUIRES(mLock);
    /**
     * Post `doNotifyWindowResponsiveLockedInterruptible` command.
     */
    void sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) REQUIRES(mLock);

    /**
    /**
     * This map will store the pending focus requests that cannot be currently processed. This can
     * This map will store the pending focus requests that cannot be currently processed. This can
     * happen if the window requested to be focused is not currently visible. Such a window might
     * happen if the window requested to be focused is not currently visible. Such a window might
@@ -577,7 +607,7 @@ private:
                              int32_t displayId, std::string_view reason) REQUIRES(mLock);
                              int32_t displayId, std::string_view reason) REQUIRES(mLock);
    void notifyFocusChangedLocked(const sp<IBinder>& oldFocus, const sp<IBinder>& newFocus)
    void notifyFocusChangedLocked(const sp<IBinder>& oldFocus, const sp<IBinder>& newFocus)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void onAnrLocked(const Connection& connection) REQUIRES(mLock);
    void onAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
    void onAnrLocked(std::shared_ptr<InputApplicationHandle> application) REQUIRES(mLock);
    void onAnrLocked(std::shared_ptr<InputApplicationHandle> application) REQUIRES(mLock);
    void onUntrustedTouchLocked(const std::string& obscuringPackage) REQUIRES(mLock);
    void onUntrustedTouchLocked(const std::string& obscuringPackage) REQUIRES(mLock);
    void updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)
    void updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)
@@ -592,11 +622,13 @@ private:
            REQUIRES(mLock);
            REQUIRES(mLock);
    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    // ANR-related callbacks - start
    void doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyConnectionUnresponsiveLockedInterruptible(CommandEntry* commandEntry)
    void doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
            REQUIRES(mLock);
    void doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry)
    void doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
            REQUIRES(mLock);
    void doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    // ANR-related callbacks - end
    void doNotifySensorLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifySensorLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry)
    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry)
+19 −8
Original line number Original line Diff line number Diff line
@@ -50,20 +50,31 @@ public:
    virtual void notifyNoFocusedWindowAnr(
    virtual void notifyNoFocusedWindowAnr(
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;


    /* Notifies the system that a connection 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 connection. The connection is identified via token.
     * should be raised for this window. The window is identified via token.
     * The string reason contains information about the input event that we haven't received
     * The string reason contains information about the input event that we haven't received
     * a response for.
     * a response for.
     */
     */
    virtual void notifyConnectionUnresponsive(const sp<IBinder>& token,
    virtual void notifyWindowUnresponsive(const sp<IBinder>& token, const std::string& reason) = 0;
                                              const std::string& reason) = 0;
    /* Notifies the system that a monitor just became unresponsive. This indicates that ANR
     * 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 connection just became responsive. This is only called after the
    /* Notifies the system that a window just became responsive. This is only called after the
     * connection 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 connection 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.
     */
    virtual void notifyWindowResponsive(const sp<IBinder>& token) = 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.
     * future.
     */
     */
    virtual void notifyConnectionResponsive(const sp<IBinder>& token) = 0;
    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;
Loading