Loading include/input/Input.h +62 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,19 @@ enum { AMOTION_EVENT_FLAG_TAINTED = 0x80000000, }; /** * Allowed VerifiedKeyEvent flags. All other flags from KeyEvent do not get verified. * These values must be kept in sync with VerifiedKeyEvent.java */ constexpr int32_t VERIFIED_KEY_EVENT_FLAGS = AKEY_EVENT_FLAG_CANCELED; /** * Allowed VerifiedMotionEventFlags. All other flags from MotionEvent do not get verified. * These values must be kept in sync with VerifiedMotionEvent.java */ constexpr int32_t VERIFIED_MOTION_EVENT_FLAGS = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; enum { /* Used when a motion event is not associated with any display. * Typically used for non-pointer events. */ Loading Loading @@ -718,6 +731,55 @@ protected: bool mInTouchMode; }; /** * Base class for verified events. * Do not create a VerifiedInputEvent explicitly. * Use helper functions to create them from InputEvents. */ struct __attribute__((__packed__)) VerifiedInputEvent { enum class Type : int32_t { KEY = AINPUT_EVENT_TYPE_KEY, MOTION = AINPUT_EVENT_TYPE_MOTION, }; Type type; int32_t deviceId; nsecs_t eventTimeNanos; uint32_t source; int32_t displayId; }; /** * Same as KeyEvent, but only contains the data that can be verified. * If you update this class, you must also update VerifiedKeyEvent.java */ struct __attribute__((__packed__)) VerifiedKeyEvent : public VerifiedInputEvent { int32_t action; nsecs_t downTimeNanos; int32_t flags; int32_t keyCode; int32_t scanCode; int32_t metaState; int32_t repeatCount; }; /** * Same as MotionEvent, but only contains the data that can be verified. * If you update this class, you must also update VerifiedMotionEvent.java */ struct __attribute__((__packed__)) VerifiedMotionEvent : public VerifiedInputEvent { float rawX; float rawY; int32_t actionMasked; nsecs_t downTimeNanos; int32_t flags; int32_t metaState; int32_t buttonState; }; VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event); VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event); /* * Input event factory. */ Loading libs/binder/tests/Android.bp +3 −3 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ cc_test { }, srcs: ["binderDriverInterfaceTest.cpp"], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], } cc_test { Loading Loading @@ -69,7 +69,7 @@ cc_test { "libbinder", "libutils", ], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], require_root: true, } Loading Loading @@ -131,7 +131,7 @@ cc_test { "liblog", "libutils", ], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], require_root: true, } Loading libs/binderthreadstate/Android.bp +0 −12 Original line number Diff line number Diff line Loading @@ -63,15 +63,3 @@ cc_test { ], require_root: true, } // TODO(b/148692216): remove empty lib cc_library { name: "libbinderthreadstate", recovery_available: true, vendor_available: false, vndk: { enabled: true, support_system_process: true, }, host_supported: true, } libs/cputimeinstate/cputimeinstate.cpp +52 −3 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ static std::vector<std::vector<uint32_t>> gPolicyCpus; static std::set<uint32_t> gAllFreqs; static unique_fd gTisMapFd; static unique_fd gConcurrentMapFd; static unique_fd gUidLastUpdateMapFd; static std::optional<std::vector<uint32_t>> readNumbersFromFile(const std::string &path) { std::string data; Loading Loading @@ -144,6 +145,10 @@ static bool initGlobals() { unique_fd{bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_concurrent_times_map")}; if (gConcurrentMapFd < 0) return false; gUidLastUpdateMapFd = unique_fd{bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_last_update_map")}; if (gUidLastUpdateMapFd < 0) return false; gInitialized = true; return true; } Loading Loading @@ -263,6 +268,18 @@ std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t ui return out; } static std::optional<bool> uidUpdatedSince(uint32_t uid, uint64_t lastUpdate, uint64_t *newLastUpdate) { uint64_t uidLastUpdate; if (findMapEntry(gUidLastUpdateMapFd, &uid, &uidLastUpdate)) return {}; // Updates that occurred during the previous read may have been missed. To mitigate // this, don't ignore entries updated up to 1s before *lastUpdate constexpr uint64_t NSEC_PER_SEC = 1000000000; if (uidLastUpdate + NSEC_PER_SEC < lastUpdate) return false; if (uidLastUpdate > *newLastUpdate) *newLastUpdate = uidLastUpdate; return true; } // Retrieve the times in ns that each uid spent running at each CPU freq. // Return contains no value on error, otherwise it contains a map from uids to vectors of vectors // using the format: Loading @@ -271,6 +288,14 @@ std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t ui // where ti_j_k is the ns uid i spent running on the jth cluster at the cluster's kth lowest freq. std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsCpuFreqTimes() { return getUidsUpdatedCpuFreqTimes(nullptr); } // Retrieve the times in ns that each uid spent running at each CPU freq, excluding UIDs that have // not run since before lastUpdate. // Return format is the same as getUidsCpuFreqTimes() std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsUpdatedCpuFreqTimes(uint64_t *lastUpdate) { if (!gInitialized && !initGlobals()) return {}; time_key_t key, prevKey; std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>> map; Loading @@ -282,8 +307,14 @@ getUidsCpuFreqTimes() { std::vector<std::vector<uint64_t>> mapFormat; for (const auto &freqList : gPolicyFreqs) mapFormat.emplace_back(freqList.size(), 0); uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0; std::vector<tis_val_t> vals(gNCpus); do { if (lastUpdate) { auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate); if (!uidUpdated.has_value()) return {}; if (!*uidUpdated) continue; } if (findMapEntry(gTisMapFd, &key, vals.data())) return {}; if (map.find(key.uid) == map.end()) map.emplace(key.uid, mapFormat); Loading @@ -299,8 +330,9 @@ getUidsCpuFreqTimes() { } } prevKey = key; } while (!getNextMapKey(gTisMapFd, &prevKey, &key)); } while (prevKey = key, !getNextMapKey(gTisMapFd, &prevKey, &key)); if (errno != ENOENT) return {}; if (lastUpdate && newLastUpdate > *lastUpdate) *lastUpdate = newLastUpdate; return map; } Loading Loading @@ -365,6 +397,15 @@ std::optional<concurrent_time_t> getUidConcurrentTimes(uint32_t uid, bool retry) // where ai is the ns spent running concurrently with tasks on i other cpus and pi_j is the ns spent // running on the ith cluster, concurrently with tasks on j other cpus in the same cluster. std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrentTimes() { return getUidsUpdatedConcurrentTimes(nullptr); } // Retrieve the times in ns that each uid spent running concurrently with each possible number of // other tasks on each cluster (policy times) and overall (active times), excluding UIDs that have // not run since before lastUpdate. // Return format is the same as getUidsConcurrentTimes() std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsUpdatedConcurrentTimes( uint64_t *lastUpdate) { if (!gInitialized && !initGlobals()) return {}; time_key_t key, prevKey; std::unordered_map<uint32_t, concurrent_time_t> ret; Loading @@ -379,7 +420,13 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent std::vector<concurrent_val_t> vals(gNCpus); std::vector<uint64_t>::iterator activeBegin, activeEnd, policyBegin, policyEnd; uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0; do { if (lastUpdate) { auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate); if (!uidUpdated.has_value()) return {}; if (!*uidUpdated) continue; } if (findMapEntry(gConcurrentMapFd, &key, vals.data())) return {}; if (ret.find(key.uid) == ret.end()) ret.emplace(key.uid, retFormat); Loading @@ -405,8 +452,7 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent std::plus<uint64_t>()); } } prevKey = key; } while (!getNextMapKey(gConcurrentMapFd, &prevKey, &key)); } while (prevKey = key, !getNextMapKey(gConcurrentMapFd, &prevKey, &key)); if (errno != ENOENT) return {}; for (const auto &[key, value] : ret) { if (!verifyConcurrentTimes(value)) { Loading @@ -414,6 +460,7 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent if (val.has_value()) ret[key] = val.value(); } } if (lastUpdate && newLastUpdate > *lastUpdate) *lastUpdate = newLastUpdate; return ret; } Loading Loading @@ -446,6 +493,8 @@ bool clearUidTimes(uint32_t uid) { return false; if (deleteMapEntry(gConcurrentMapFd, &key) && errno != ENOENT) return false; } if (deleteMapEntry(gUidLastUpdateMapFd, &uid) && errno != ENOENT) return false; return true; } Loading libs/cputimeinstate/cputimeinstate.h +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ bool startTrackingUidTimes(); std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t uid); std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsCpuFreqTimes(); std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsUpdatedCpuFreqTimes(uint64_t *lastUpdate); std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs(); struct concurrent_time_t { Loading @@ -35,6 +37,8 @@ struct concurrent_time_t { std::optional<concurrent_time_t> getUidConcurrentTimes(uint32_t uid, bool retry = true); std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrentTimes(); std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsUpdatedConcurrentTimes(uint64_t *lastUpdate); bool clearUidTimes(unsigned int uid); } // namespace bpf Loading Loading
include/input/Input.h +62 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,19 @@ enum { AMOTION_EVENT_FLAG_TAINTED = 0x80000000, }; /** * Allowed VerifiedKeyEvent flags. All other flags from KeyEvent do not get verified. * These values must be kept in sync with VerifiedKeyEvent.java */ constexpr int32_t VERIFIED_KEY_EVENT_FLAGS = AKEY_EVENT_FLAG_CANCELED; /** * Allowed VerifiedMotionEventFlags. All other flags from MotionEvent do not get verified. * These values must be kept in sync with VerifiedMotionEvent.java */ constexpr int32_t VERIFIED_MOTION_EVENT_FLAGS = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; enum { /* Used when a motion event is not associated with any display. * Typically used for non-pointer events. */ Loading Loading @@ -718,6 +731,55 @@ protected: bool mInTouchMode; }; /** * Base class for verified events. * Do not create a VerifiedInputEvent explicitly. * Use helper functions to create them from InputEvents. */ struct __attribute__((__packed__)) VerifiedInputEvent { enum class Type : int32_t { KEY = AINPUT_EVENT_TYPE_KEY, MOTION = AINPUT_EVENT_TYPE_MOTION, }; Type type; int32_t deviceId; nsecs_t eventTimeNanos; uint32_t source; int32_t displayId; }; /** * Same as KeyEvent, but only contains the data that can be verified. * If you update this class, you must also update VerifiedKeyEvent.java */ struct __attribute__((__packed__)) VerifiedKeyEvent : public VerifiedInputEvent { int32_t action; nsecs_t downTimeNanos; int32_t flags; int32_t keyCode; int32_t scanCode; int32_t metaState; int32_t repeatCount; }; /** * Same as MotionEvent, but only contains the data that can be verified. * If you update this class, you must also update VerifiedMotionEvent.java */ struct __attribute__((__packed__)) VerifiedMotionEvent : public VerifiedInputEvent { float rawX; float rawY; int32_t actionMasked; nsecs_t downTimeNanos; int32_t flags; int32_t metaState; int32_t buttonState; }; VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event); VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event); /* * Input event factory. */ Loading
libs/binder/tests/Android.bp +3 −3 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ cc_test { }, srcs: ["binderDriverInterfaceTest.cpp"], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], } cc_test { Loading Loading @@ -69,7 +69,7 @@ cc_test { "libbinder", "libutils", ], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], require_root: true, } Loading Loading @@ -131,7 +131,7 @@ cc_test { "liblog", "libutils", ], test_suites: ["device-tests"], test_suites: ["device-tests", "vts-core"], require_root: true, } Loading
libs/binderthreadstate/Android.bp +0 −12 Original line number Diff line number Diff line Loading @@ -63,15 +63,3 @@ cc_test { ], require_root: true, } // TODO(b/148692216): remove empty lib cc_library { name: "libbinderthreadstate", recovery_available: true, vendor_available: false, vndk: { enabled: true, support_system_process: true, }, host_supported: true, }
libs/cputimeinstate/cputimeinstate.cpp +52 −3 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ static std::vector<std::vector<uint32_t>> gPolicyCpus; static std::set<uint32_t> gAllFreqs; static unique_fd gTisMapFd; static unique_fd gConcurrentMapFd; static unique_fd gUidLastUpdateMapFd; static std::optional<std::vector<uint32_t>> readNumbersFromFile(const std::string &path) { std::string data; Loading Loading @@ -144,6 +145,10 @@ static bool initGlobals() { unique_fd{bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_concurrent_times_map")}; if (gConcurrentMapFd < 0) return false; gUidLastUpdateMapFd = unique_fd{bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_last_update_map")}; if (gUidLastUpdateMapFd < 0) return false; gInitialized = true; return true; } Loading Loading @@ -263,6 +268,18 @@ std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t ui return out; } static std::optional<bool> uidUpdatedSince(uint32_t uid, uint64_t lastUpdate, uint64_t *newLastUpdate) { uint64_t uidLastUpdate; if (findMapEntry(gUidLastUpdateMapFd, &uid, &uidLastUpdate)) return {}; // Updates that occurred during the previous read may have been missed. To mitigate // this, don't ignore entries updated up to 1s before *lastUpdate constexpr uint64_t NSEC_PER_SEC = 1000000000; if (uidLastUpdate + NSEC_PER_SEC < lastUpdate) return false; if (uidLastUpdate > *newLastUpdate) *newLastUpdate = uidLastUpdate; return true; } // Retrieve the times in ns that each uid spent running at each CPU freq. // Return contains no value on error, otherwise it contains a map from uids to vectors of vectors // using the format: Loading @@ -271,6 +288,14 @@ std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t ui // where ti_j_k is the ns uid i spent running on the jth cluster at the cluster's kth lowest freq. std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsCpuFreqTimes() { return getUidsUpdatedCpuFreqTimes(nullptr); } // Retrieve the times in ns that each uid spent running at each CPU freq, excluding UIDs that have // not run since before lastUpdate. // Return format is the same as getUidsCpuFreqTimes() std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsUpdatedCpuFreqTimes(uint64_t *lastUpdate) { if (!gInitialized && !initGlobals()) return {}; time_key_t key, prevKey; std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>> map; Loading @@ -282,8 +307,14 @@ getUidsCpuFreqTimes() { std::vector<std::vector<uint64_t>> mapFormat; for (const auto &freqList : gPolicyFreqs) mapFormat.emplace_back(freqList.size(), 0); uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0; std::vector<tis_val_t> vals(gNCpus); do { if (lastUpdate) { auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate); if (!uidUpdated.has_value()) return {}; if (!*uidUpdated) continue; } if (findMapEntry(gTisMapFd, &key, vals.data())) return {}; if (map.find(key.uid) == map.end()) map.emplace(key.uid, mapFormat); Loading @@ -299,8 +330,9 @@ getUidsCpuFreqTimes() { } } prevKey = key; } while (!getNextMapKey(gTisMapFd, &prevKey, &key)); } while (prevKey = key, !getNextMapKey(gTisMapFd, &prevKey, &key)); if (errno != ENOENT) return {}; if (lastUpdate && newLastUpdate > *lastUpdate) *lastUpdate = newLastUpdate; return map; } Loading Loading @@ -365,6 +397,15 @@ std::optional<concurrent_time_t> getUidConcurrentTimes(uint32_t uid, bool retry) // where ai is the ns spent running concurrently with tasks on i other cpus and pi_j is the ns spent // running on the ith cluster, concurrently with tasks on j other cpus in the same cluster. std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrentTimes() { return getUidsUpdatedConcurrentTimes(nullptr); } // Retrieve the times in ns that each uid spent running concurrently with each possible number of // other tasks on each cluster (policy times) and overall (active times), excluding UIDs that have // not run since before lastUpdate. // Return format is the same as getUidsConcurrentTimes() std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsUpdatedConcurrentTimes( uint64_t *lastUpdate) { if (!gInitialized && !initGlobals()) return {}; time_key_t key, prevKey; std::unordered_map<uint32_t, concurrent_time_t> ret; Loading @@ -379,7 +420,13 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent std::vector<concurrent_val_t> vals(gNCpus); std::vector<uint64_t>::iterator activeBegin, activeEnd, policyBegin, policyEnd; uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0; do { if (lastUpdate) { auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate); if (!uidUpdated.has_value()) return {}; if (!*uidUpdated) continue; } if (findMapEntry(gConcurrentMapFd, &key, vals.data())) return {}; if (ret.find(key.uid) == ret.end()) ret.emplace(key.uid, retFormat); Loading @@ -405,8 +452,7 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent std::plus<uint64_t>()); } } prevKey = key; } while (!getNextMapKey(gConcurrentMapFd, &prevKey, &key)); } while (prevKey = key, !getNextMapKey(gConcurrentMapFd, &prevKey, &key)); if (errno != ENOENT) return {}; for (const auto &[key, value] : ret) { if (!verifyConcurrentTimes(value)) { Loading @@ -414,6 +460,7 @@ std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrent if (val.has_value()) ret[key] = val.value(); } } if (lastUpdate && newLastUpdate > *lastUpdate) *lastUpdate = newLastUpdate; return ret; } Loading Loading @@ -446,6 +493,8 @@ bool clearUidTimes(uint32_t uid) { return false; if (deleteMapEntry(gConcurrentMapFd, &key) && errno != ENOENT) return false; } if (deleteMapEntry(gUidLastUpdateMapFd, &uid) && errno != ENOENT) return false; return true; } Loading
libs/cputimeinstate/cputimeinstate.h +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ bool startTrackingUidTimes(); std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t uid); std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsCpuFreqTimes(); std::optional<std::unordered_map<uint32_t, std::vector<std::vector<uint64_t>>>> getUidsUpdatedCpuFreqTimes(uint64_t *lastUpdate); std::optional<std::vector<std::vector<uint32_t>>> getCpuFreqs(); struct concurrent_time_t { Loading @@ -35,6 +37,8 @@ struct concurrent_time_t { std::optional<concurrent_time_t> getUidConcurrentTimes(uint32_t uid, bool retry = true); std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsConcurrentTimes(); std::optional<std::unordered_map<uint32_t, concurrent_time_t>> getUidsUpdatedConcurrentTimes(uint64_t *lastUpdate); bool clearUidTimes(unsigned int uid); } // namespace bpf Loading