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

Commit 206d40a7 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou Committed by Automerger Merge Worker
Browse files

Report ANR when waited for longer than the timeout am: e4623041

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/11883661

Change-Id: Ic138255cc8c820faa9bb82d76171f736a2e57e27
parents 2bdc9617 e4623041
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -462,6 +462,8 @@ public:
                    nsecs_t eventTime);
                    nsecs_t eventTime);
    void initialize(const KeyEvent& from);
    void initialize(const KeyEvent& from);


    static const char* actionToString(int32_t action);

protected:
protected:
    int32_t mAction;
    int32_t mAction;
    int32_t mFlags;
    int32_t mFlags;
@@ -725,6 +727,8 @@ public:
    static const char* getLabel(int32_t axis);
    static const char* getLabel(int32_t axis);
    static int32_t getAxisFromLabel(const char* label);
    static int32_t getAxisFromLabel(const char* label);


    static const char* actionToString(int32_t action);

protected:
protected:
    int32_t mAction;
    int32_t mAction;
    int32_t mActionButton;
    int32_t mActionButton;
+31 −0
Original line number Original line Diff line number Diff line
@@ -169,6 +169,18 @@ void KeyEvent::initialize(const KeyEvent& from) {
    mEventTime = from.mEventTime;
    mEventTime = from.mEventTime;
}
}


const char* KeyEvent::actionToString(int32_t action) {
    // Convert KeyEvent action to string
    switch (action) {
        case AKEY_EVENT_ACTION_DOWN:
            return "DOWN";
        case AKEY_EVENT_ACTION_UP:
            return "UP";
        case AKEY_EVENT_ACTION_MULTIPLE:
            return "MULTIPLE";
    }
    return "UNKNOWN";
}


// --- PointerCoords ---
// --- PointerCoords ---


@@ -678,6 +690,25 @@ int32_t MotionEvent::getAxisFromLabel(const char* label) {
    return getAxisByLabel(label);
    return getAxisByLabel(label);
}
}


const char* MotionEvent::actionToString(int32_t action) {
    // Convert MotionEvent action to string
    switch (action & AMOTION_EVENT_ACTION_MASK) {
        case AMOTION_EVENT_ACTION_DOWN:
            return "DOWN";
        case AMOTION_EVENT_ACTION_MOVE:
            return "MOVE";
        case AMOTION_EVENT_ACTION_UP:
            return "UP";
        case AMOTION_EVENT_ACTION_CANCEL:
            return "CANCEL";
        case AMOTION_EVENT_ACTION_POINTER_DOWN:
            return "POINTER_DOWN";
        case AMOTION_EVENT_ACTION_POINTER_UP:
            return "POINTER_UP";
    }
    return "UNKNOWN";
}

// --- FocusEvent ---
// --- FocusEvent ---


void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ cc_library_headers {
filegroup {
filegroup {
    name: "libinputdispatcher_sources",
    name: "libinputdispatcher_sources",
    srcs: [
    srcs: [
        "AnrTracker.cpp",
        "Connection.cpp",
        "Connection.cpp",
        "Entry.cpp",
        "Entry.cpp",
        "InjectionState.cpp",
        "InjectionState.cpp",
+73 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "AnrTracker.h"

namespace android::inputdispatcher {

template <typename T>
static T max(const T& a, const T& b) {
    return a < b ? b : a;
}

void AnrTracker::insert(nsecs_t timeoutTime, sp<IBinder> token) {
    mAnrTimeouts.insert(std::make_pair(timeoutTime, std::move(token)));
}

/**
 * Erase a single entry only. If there are multiple duplicate entries
 * (same time, same connection), then only remove one of them.
 */
void AnrTracker::erase(nsecs_t timeoutTime, const sp<IBinder>& token) {
    auto pair = std::make_pair(timeoutTime, token);
    auto it = mAnrTimeouts.find(pair);
    if (it != mAnrTimeouts.end()) {
        mAnrTimeouts.erase(it);
    }
}

void AnrTracker::eraseToken(const sp<IBinder>& token) {
    for (auto it = mAnrTimeouts.begin(); it != mAnrTimeouts.end();) {
        if (it->second == token) {
            it = mAnrTimeouts.erase(it);
        } else {
            ++it;
        }
    }
}

bool AnrTracker::empty() const {
    return mAnrTimeouts.empty();
}

// If empty() is false, return the time at which the next connection should cause an ANR
// If empty() is true, return LONG_LONG_MAX
nsecs_t AnrTracker::firstTimeout() const {
    if (mAnrTimeouts.empty()) {
        return std::numeric_limits<nsecs_t>::max();
    }
    return mAnrTimeouts.begin()->first;
}

const sp<IBinder>& AnrTracker::firstToken() const {
    return mAnrTimeouts.begin()->second;
}

void AnrTracker::clear() {
    mAnrTimeouts.clear();
}

} // namespace android::inputdispatcher
+60 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _UI_INPUT_INPUTDISPATCHER_ANRTRACKER_H
#define _UI_INPUT_INPUTDISPATCHER_ANRTRACKER_H

#include <binder/IBinder.h>
#include <utils/Timers.h>
#include <set>

namespace android::inputdispatcher {

/**
 * Keeps track of the times when each connection is going to ANR.
 * Provides the ability to quickly find the connection that is going to cause ANR next.
 */
class AnrTracker {
public:
    void insert(nsecs_t timeoutTime, sp<IBinder> token);
    void erase(nsecs_t timeoutTime, const sp<IBinder>& token);
    void eraseToken(const sp<IBinder>& token);
    void clear();

    bool empty() const;
    // If empty() is false, return the time at which the next connection should cause an ANR
    // If empty() is true, return LONG_LONG_MAX
    nsecs_t firstTimeout() const;
    // Return the token of the next connection that should cause an ANR.
    // Do not call this unless empty() is false, you will encounter undefined behaviour.
    const sp<IBinder>& firstToken() const;

private:
    // Optimization: use a multiset to keep track of the event timeouts. When an event is sent
    // to the InputConsumer, we add an entry to this structure. We look at the smallest value to
    // determine if any of the connections is unresponsive, and to determine when we should wake
    // next for the future ANR check.
    // Using a multiset helps quickly look up the next timeout due.
    //
    // We must use a multi-set, because it is plausible (although highly unlikely) to have entries
    // from the same connection and same timestamp, but different sequence numbers.
    // We are not tracking sequence numbers, and just allow duplicates to exist.
    std::multiset<std::pair<nsecs_t /*timeoutTime*/, sp<IBinder> /*connectionToken*/>> mAnrTimeouts;
};

} // namespace android::inputdispatcher

#endif // _UI_INPUT_INPUTDISPATCHER_ANRTRACKER_H
Loading