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

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

Merge "Tell policy about responsive connections"

parents e1208a47 234129c0
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -50,12 +50,18 @@ protected:
private:
    void notifyConfigurationChanged(nsecs_t) override {}

    std::chrono::nanoseconds notifyAnr(const std::shared_ptr<InputApplicationHandle>&,
                                       const sp<IBinder>&, const std::string& name) override {
        ALOGE("The window is not responding : %s", name.c_str());
        return 0s;
    void notifyNoFocusedWindowAnr(
            const std::shared_ptr<InputApplicationHandle>& applicationHandle) override {
        ALOGE("There is no focused window for %s", applicationHandle->getName().c_str());
    }

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

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

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

    void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
+47 −58
Original line number Diff line number Diff line
@@ -2336,7 +2336,7 @@ bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& window
}

std::string InputDispatcher::getApplicationWindowLabel(
        const std::shared_ptr<InputApplicationHandle>& applicationHandle,
        const InputApplicationHandle* applicationHandle,
        const sp<InputWindowHandle>& windowHandle) {
    if (applicationHandle != nullptr) {
        if (windowHandle != nullptr) {
@@ -4922,24 +4922,21 @@ void InputDispatcher::onAnrLocked(const Connection& connection) {
    sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
    updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);

    std::unique_ptr<CommandEntry> commandEntry =
            std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
    commandEntry->inputApplicationHandle = nullptr;
    std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
    commandEntry->connectionToken = connectionToken;
    commandEntry->reason = std::move(reason);
    postCommandLocked(std::move(commandEntry));
}

void InputDispatcher::onAnrLocked(const std::shared_ptr<InputApplicationHandle>& application) {
    std::string reason = android::base::StringPrintf("%s does not have a focused window",
                                                     application->getName().c_str());

    updateLastAnrStateLocked(application, reason);
void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
    std::string reason =
            StringPrintf("%s does not have a focused window", application->getName().c_str());
    updateLastAnrStateLocked(*application, reason);

    std::unique_ptr<CommandEntry> commandEntry =
            std::make_unique<CommandEntry>(&InputDispatcher::doNotifyAnrLockedInterruptible);
    commandEntry->inputApplicationHandle = application;
    commandEntry->reason = std::move(reason);
    std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
            &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
    commandEntry->inputApplicationHandle = std::move(application);
    postCommandLocked(std::move(commandEntry));
}

@@ -4956,9 +4953,9 @@ void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& wind
    updateLastAnrStateLocked(windowLabel, reason);
}

void InputDispatcher::updateLastAnrStateLocked(
        const std::shared_ptr<InputApplicationHandle>& application, const std::string& reason) {
    const std::string windowLabel = getApplicationWindowLabel(application, nullptr);
void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
                                               const std::string& reason) {
    const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
    updateLastAnrStateLocked(windowLabel, reason);
}

@@ -5006,61 +5003,44 @@ void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* comm
    mLock.lock();
}

void InputDispatcher::doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) {
void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
    mLock.unlock();
    const sp<IBinder>& token = commandEntry->connectionToken;
    const std::chrono::nanoseconds timeoutExtension =
            mPolicy->notifyAnr(commandEntry->inputApplicationHandle, token, commandEntry->reason);

    mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);

    mLock.lock();
}

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

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

    mLock.lock();

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

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

    mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
    mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);

    mLock.lock();
}

void InputDispatcher::extendAnrTimeoutsLocked(
        const std::shared_ptr<InputApplicationHandle>& application,
        const sp<IBinder>& connectionToken, std::chrono::nanoseconds timeoutExtension) {
    if (connectionToken == nullptr && application != nullptr) {
        // The ANR happened because there's no focused window
        mNoFocusedWindowTimeoutTime = now() + timeoutExtension.count();
        mAwaitedFocusedApplication = application;
    }

    sp<Connection> connection = getConnectionLocked(connectionToken);
    if (connection == nullptr) {
        // It's possible that the connection already disappeared. No action necessary.
        return;
    }
void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
    mLock.unlock();

    ALOGI("Raised ANR, but the policy wants to keep waiting on %s for %" PRId64 "ms longer",
          connection->inputChannel->getName().c_str(), millis(timeoutExtension));
    mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);

    connection->responsive = true;
    const nsecs_t newTimeout = now() + timeoutExtension.count();
    for (DispatchEntry* entry : connection->waitQueue) {
        if (newTimeout >= entry->timeoutTime) {
            // Already removed old entries when connection was marked unresponsive
            entry->timeoutTime = newTimeout;
            mAnrTracker.insert(entry->timeoutTime, connectionToken);
        }
    }
    mLock.lock();
}

void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
@@ -5150,10 +5130,19 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c
    if (dispatchEntryIt != connection->waitQueue.end()) {
        dispatchEntry = *dispatchEntryIt;
        connection->waitQueue.erase(dispatchEntryIt);
        mAnrTracker.erase(dispatchEntry->timeoutTime,
                          connection->inputChannel->getConnectionToken());
        const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
        mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
        if (!connection->responsive) {
            connection->responsive = isConnectionResponsive(*connection);
            if (connection->responsive) {
                // The connection was unresponsive, and now it's responsive. Tell the policy
                // about it so that it can stop ANR.
                std::unique_ptr<CommandEntry> connectionResponsiveCommand =
                        std::make_unique<CommandEntry>(
                                &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
                connectionResponsiveCommand->connectionToken = connectionToken;
                postCommandLocked(std::move(connectionResponsiveCommand));
            }
        }
        traceWaitQueueLength(connection);
        if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
+9 −9
Original line number Diff line number Diff line
@@ -419,9 +419,6 @@ private:
    // Once a connection becomes unresponsive, its entries are removed from AnrTracker to
    // prevent unneeded wakeups.
    AnrTracker mAnrTracker GUARDED_BY(mLock);
    void extendAnrTimeoutsLocked(const std::shared_ptr<InputApplicationHandle>& application,
                                 const sp<IBinder>& connectionToken,
                                 std::chrono::nanoseconds timeoutExtension) REQUIRES(mLock);

    // Contains the last window which received a hover event.
    sp<InputWindowHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
@@ -475,8 +472,7 @@ private:
                                       int32_t y) const REQUIRES(mLock);
    bool isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const REQUIRES(mLock);
    std::string dumpWindowForTouchOcclusion(const InputWindowInfo* info, bool isTouchWindow) const;
    std::string getApplicationWindowLabel(
            const std::shared_ptr<InputApplicationHandle>& applicationHandle,
    std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
                                          const sp<InputWindowHandle>& windowHandle);

    // Manage the dispatch cycle for a single connection.
@@ -554,11 +550,11 @@ private:
    void notifyFocusChangedLocked(const sp<IBinder>& oldFocus, const sp<IBinder>& newFocus)
            REQUIRES(mLock);
    void onAnrLocked(const Connection& connection) REQUIRES(mLock);
    void onAnrLocked(const 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 updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)
            REQUIRES(mLock);
    void updateLastAnrStateLocked(const std::shared_ptr<InputApplicationHandle>& application,
    void updateLastAnrStateLocked(const InputApplicationHandle& application,
                                  const std::string& reason) REQUIRES(mLock);
    void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason)
            REQUIRES(mLock);
@@ -568,7 +564,11 @@ private:
            REQUIRES(mLock);
    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyAnrLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doNotifyConnectionUnresponsiveLockedInterruptible(CommandEntry* commandEntry)
            REQUIRES(mLock);
    void doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry)
            REQUIRES(mLock);
    void doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry)
            REQUIRES(mLock);
+19 −5
Original line number Diff line number Diff line
@@ -45,11 +45,25 @@ public:
    /* Notifies the system that a configuration change has occurred. */
    virtual void notifyConfigurationChanged(nsecs_t when) = 0;

    /* Notifies the system that an application is not responding.
     * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
    virtual std::chrono::nanoseconds notifyAnr(
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
            const sp<IBinder>& token, const std::string& reason) = 0;
    /* Notifies the system that an application does not have a focused window.
     */
    virtual void notifyNoFocusedWindowAnr(
            const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;

    /* Notifies the system that a connection just became unresponsive. This indicates that ANR
     * should be raised for this connection. The connection is identified via token.
     * The string reason contains information about the input event that we haven't received
     * a response for.
     */
    virtual void notifyConnectionUnresponsive(const sp<IBinder>& token,
                                              const std::string& reason) = 0;

    /* Notifies the system that a connection just became responsive. This is only called after the
     * connection 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
     * future.
     */
    virtual void notifyConnectionResponsive(const sp<IBinder>& token) = 0;

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

File changed.

Preview size limit exceeded, changes collapsed.