Loading include/input/Input.h +4 −0 Original line number Diff line number Diff line Loading @@ -462,6 +462,8 @@ public: nsecs_t eventTime); void initialize(const KeyEvent& from); static const char* actionToString(int32_t action); protected: int32_t mAction; int32_t mFlags; Loading Loading @@ -725,6 +727,8 @@ public: static const char* getLabel(int32_t axis); static int32_t getAxisFromLabel(const char* label); static const char* actionToString(int32_t action); protected: int32_t mAction; int32_t mActionButton; Loading libs/input/Input.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,18 @@ void KeyEvent::initialize(const KeyEvent& from) { 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 --- Loading Loading @@ -678,6 +690,25 @@ int32_t MotionEvent::getAxisFromLabel(const char* 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 --- void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) { Loading services/inputflinger/dispatcher/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ cc_library_headers { filegroup { name: "libinputdispatcher_sources", srcs: [ "AnrTracker.cpp", "Connection.cpp", "Entry.cpp", "InjectionState.cpp", Loading services/inputflinger/dispatcher/AnrTracker.cpp 0 → 100644 +73 −0 Original line number 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 services/inputflinger/dispatcher/AnrTracker.h 0 → 100644 +60 −0 Original line number 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
include/input/Input.h +4 −0 Original line number Diff line number Diff line Loading @@ -462,6 +462,8 @@ public: nsecs_t eventTime); void initialize(const KeyEvent& from); static const char* actionToString(int32_t action); protected: int32_t mAction; int32_t mFlags; Loading Loading @@ -725,6 +727,8 @@ public: static const char* getLabel(int32_t axis); static int32_t getAxisFromLabel(const char* label); static const char* actionToString(int32_t action); protected: int32_t mAction; int32_t mActionButton; Loading
libs/input/Input.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,18 @@ void KeyEvent::initialize(const KeyEvent& from) { 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 --- Loading Loading @@ -678,6 +690,25 @@ int32_t MotionEvent::getAxisFromLabel(const char* 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 --- void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) { Loading
services/inputflinger/dispatcher/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ cc_library_headers { filegroup { name: "libinputdispatcher_sources", srcs: [ "AnrTracker.cpp", "Connection.cpp", "Entry.cpp", "InjectionState.cpp", Loading
services/inputflinger/dispatcher/AnrTracker.cpp 0 → 100644 +73 −0 Original line number 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
services/inputflinger/dispatcher/AnrTracker.h 0 → 100644 +60 −0 Original line number 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