Loading cmds/statsd/src/packages/UidMap.cpp +31 −11 Original line number Diff line number Diff line Loading @@ -31,10 +31,9 @@ namespace android { namespace os { namespace statsd { UidMap::UidMap() : mBytesUsed(0) { } UidMap::~UidMap() { } UidMap::UidMap() : mBytesUsed(0) {} UidMap::~UidMap() {} bool UidMap::hasApp(int uid, const string& packageName) const { lock_guard<mutex> lock(mMutex); Loading @@ -48,6 +47,27 @@ bool UidMap::hasApp(int uid, const string& packageName) const { return false; } string UidMap::normalizeAppName(const string& appName) const { string normalizedName = appName; std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower); return normalizedName; } std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const { lock_guard<mutex> lock(mMutex); return getAppNamesFromUidLocked(uid,returnNormalized); } std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const { std::set<string> names; auto range = mMap.equal_range(uid); for (auto it = range.first; it != range.second; ++it) { names.insert(returnNormalized ? normalizeAppName(it->second.packageName) : it->second.packageName); } return names; } int64_t UidMap::getAppVersion(int uid, const string& packageName) const { lock_guard<mutex> lock(mMutex); Loading Loading @@ -97,17 +117,17 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i const int64_t& versionCode) { lock_guard<mutex> lock(mMutex); string app = string(String8(app_16).string()); string appName = string(String8(app_16).string()); // Notify any interested producers that this app has updated for (auto it : mSubscribers) { it->notifyAppUpgrade(app, uid, versionCode); it->notifyAppUpgrade(appName, uid, versionCode); } auto log = mOutput.add_changes(); log->set_deletion(false); log->set_timestamp_nanos(timestamp); log->set_app(app); log->set_app(appName); log->set_uid(uid); log->set_version(versionCode); mBytesUsed += log->ByteSize(); Loading @@ -117,16 +137,15 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i auto range = mMap.equal_range(int(uid)); for (auto it = range.first; it != range.second; ++it) { if (it->second.packageName == app) { // If we find the exact same app name and uid, update the app version directly. if (it->second.packageName == appName) { it->second.versionCode = versionCode; return; } VLOG("updateApp failed to find the app %s with uid %i to update", app.c_str(), uid); return; } // Otherwise, we need to add an app at this uid. mMap.insert(make_pair(uid, AppData(app, versionCode))); mMap.insert(make_pair(uid, AppData(appName, versionCode))); } void UidMap::ensureBytesUsedBelowLimit() { Loading Loading @@ -154,6 +173,7 @@ void UidMap::ensureBytesUsedBelowLimit() { void UidMap::removeApp(const String16& app_16, const int32_t& uid) { removeApp(time(nullptr) * NS_PER_SEC, app_16, uid); } void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) { lock_guard<mutex> lock(mMutex); Loading cmds/statsd/src/packages/UidMap.h +7 −3 Original line number Diff line number Diff line Loading @@ -14,8 +14,7 @@ * limitations under the License. */ #ifndef STATSD_UIDMAP_H #define STATSD_UIDMAP_H #pragma once #include "config/ConfigKey.h" #include "config/ConfigListener.h" Loading Loading @@ -66,6 +65,9 @@ public: // Returns true if the given uid contains the specified app (eg. com.google.android.gms). bool hasApp(int uid, const string& packageName) const; // Returns the app names from uid. std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const; int64_t getAppVersion(int uid, const string& packageName) const; // Helper for debugging contents of this uid map. Can be triggered with: Loading Loading @@ -103,6 +105,9 @@ public: size_t getBytesUsed(); private: std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const; string normalizeAppName(const string& appName) const; void updateMap(const int64_t& timestamp, const vector<int32_t>& uid, const vector<int64_t>& versionCode, const vector<String16>& packageName); Loading Loading @@ -160,4 +165,3 @@ private: } // namespace os } // namespace android #endif // STATSD_UIDMAP_H cmds/statsd/tests/UidMap_test.cpp +55 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ TEST(UidMapTest, TestMatching) { EXPECT_TRUE(m.hasApp(1000, kApp1)); EXPECT_TRUE(m.hasApp(1000, kApp2)); EXPECT_FALSE(m.hasApp(1000, "not.app")); std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */); EXPECT_TRUE(name_set.empty()); } TEST(UidMapTest, TestAddAndRemove) { Loading @@ -90,12 +98,59 @@ TEST(UidMapTest, TestAddAndRemove) { versions.push_back(5); m.updateMap(uids, versions, apps); std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Update the app1 version. m.updateApp(String16(kApp1.c_str()), 1000, 40); EXPECT_EQ(40, m.getAppVersion(1000, kApp1)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); m.removeApp(String16(kApp1.c_str()), 1000); EXPECT_FALSE(m.hasApp(1000, kApp1)); EXPECT_TRUE(m.hasApp(1000, kApp2)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 1u); EXPECT_TRUE(name_set.find(kApp1) == name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Remove app2. m.removeApp(String16(kApp2.c_str()), 1000); EXPECT_FALSE(m.hasApp(1000, kApp1)); EXPECT_FALSE(m.hasApp(1000, kApp2)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_TRUE(name_set.empty()); } TEST(UidMapTest, TestUpdateApp) { UidMap m; m.updateMap({1000, 1000}, {4, 5}, {String16(kApp1.c_str()), String16(kApp2.c_str())}); std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Adds a new name for uid 1000. m.updateApp(String16("NeW_aPP1_NAmE"), 1000, 40); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 3u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end()); EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end()); // This name is also reused by another uid 2000. m.updateApp(String16("NeW_aPP1_NAmE"), 2000, 1); name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 1u); EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end()); EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end()); } TEST(UidMapTest, TestClearingOutput) { Loading Loading
cmds/statsd/src/packages/UidMap.cpp +31 −11 Original line number Diff line number Diff line Loading @@ -31,10 +31,9 @@ namespace android { namespace os { namespace statsd { UidMap::UidMap() : mBytesUsed(0) { } UidMap::~UidMap() { } UidMap::UidMap() : mBytesUsed(0) {} UidMap::~UidMap() {} bool UidMap::hasApp(int uid, const string& packageName) const { lock_guard<mutex> lock(mMutex); Loading @@ -48,6 +47,27 @@ bool UidMap::hasApp(int uid, const string& packageName) const { return false; } string UidMap::normalizeAppName(const string& appName) const { string normalizedName = appName; std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower); return normalizedName; } std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const { lock_guard<mutex> lock(mMutex); return getAppNamesFromUidLocked(uid,returnNormalized); } std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const { std::set<string> names; auto range = mMap.equal_range(uid); for (auto it = range.first; it != range.second; ++it) { names.insert(returnNormalized ? normalizeAppName(it->second.packageName) : it->second.packageName); } return names; } int64_t UidMap::getAppVersion(int uid, const string& packageName) const { lock_guard<mutex> lock(mMutex); Loading Loading @@ -97,17 +117,17 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i const int64_t& versionCode) { lock_guard<mutex> lock(mMutex); string app = string(String8(app_16).string()); string appName = string(String8(app_16).string()); // Notify any interested producers that this app has updated for (auto it : mSubscribers) { it->notifyAppUpgrade(app, uid, versionCode); it->notifyAppUpgrade(appName, uid, versionCode); } auto log = mOutput.add_changes(); log->set_deletion(false); log->set_timestamp_nanos(timestamp); log->set_app(app); log->set_app(appName); log->set_uid(uid); log->set_version(versionCode); mBytesUsed += log->ByteSize(); Loading @@ -117,16 +137,15 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i auto range = mMap.equal_range(int(uid)); for (auto it = range.first; it != range.second; ++it) { if (it->second.packageName == app) { // If we find the exact same app name and uid, update the app version directly. if (it->second.packageName == appName) { it->second.versionCode = versionCode; return; } VLOG("updateApp failed to find the app %s with uid %i to update", app.c_str(), uid); return; } // Otherwise, we need to add an app at this uid. mMap.insert(make_pair(uid, AppData(app, versionCode))); mMap.insert(make_pair(uid, AppData(appName, versionCode))); } void UidMap::ensureBytesUsedBelowLimit() { Loading Loading @@ -154,6 +173,7 @@ void UidMap::ensureBytesUsedBelowLimit() { void UidMap::removeApp(const String16& app_16, const int32_t& uid) { removeApp(time(nullptr) * NS_PER_SEC, app_16, uid); } void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) { lock_guard<mutex> lock(mMutex); Loading
cmds/statsd/src/packages/UidMap.h +7 −3 Original line number Diff line number Diff line Loading @@ -14,8 +14,7 @@ * limitations under the License. */ #ifndef STATSD_UIDMAP_H #define STATSD_UIDMAP_H #pragma once #include "config/ConfigKey.h" #include "config/ConfigListener.h" Loading Loading @@ -66,6 +65,9 @@ public: // Returns true if the given uid contains the specified app (eg. com.google.android.gms). bool hasApp(int uid, const string& packageName) const; // Returns the app names from uid. std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const; int64_t getAppVersion(int uid, const string& packageName) const; // Helper for debugging contents of this uid map. Can be triggered with: Loading Loading @@ -103,6 +105,9 @@ public: size_t getBytesUsed(); private: std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const; string normalizeAppName(const string& appName) const; void updateMap(const int64_t& timestamp, const vector<int32_t>& uid, const vector<int64_t>& versionCode, const vector<String16>& packageName); Loading Loading @@ -160,4 +165,3 @@ private: } // namespace os } // namespace android #endif // STATSD_UIDMAP_H
cmds/statsd/tests/UidMap_test.cpp +55 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ TEST(UidMapTest, TestMatching) { EXPECT_TRUE(m.hasApp(1000, kApp1)); EXPECT_TRUE(m.hasApp(1000, kApp2)); EXPECT_FALSE(m.hasApp(1000, "not.app")); std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */); EXPECT_TRUE(name_set.empty()); } TEST(UidMapTest, TestAddAndRemove) { Loading @@ -90,12 +98,59 @@ TEST(UidMapTest, TestAddAndRemove) { versions.push_back(5); m.updateMap(uids, versions, apps); std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Update the app1 version. m.updateApp(String16(kApp1.c_str()), 1000, 40); EXPECT_EQ(40, m.getAppVersion(1000, kApp1)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); m.removeApp(String16(kApp1.c_str()), 1000); EXPECT_FALSE(m.hasApp(1000, kApp1)); EXPECT_TRUE(m.hasApp(1000, kApp2)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 1u); EXPECT_TRUE(name_set.find(kApp1) == name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Remove app2. m.removeApp(String16(kApp2.c_str()), 1000); EXPECT_FALSE(m.hasApp(1000, kApp1)); EXPECT_FALSE(m.hasApp(1000, kApp2)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_TRUE(name_set.empty()); } TEST(UidMapTest, TestUpdateApp) { UidMap m; m.updateMap({1000, 1000}, {4, 5}, {String16(kApp1.c_str()), String16(kApp2.c_str())}); std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Adds a new name for uid 1000. m.updateApp(String16("NeW_aPP1_NAmE"), 1000, 40); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 3u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end()); EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end()); // This name is also reused by another uid 2000. m.updateApp(String16("NeW_aPP1_NAmE"), 2000, 1); name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 1u); EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end()); EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end()); } TEST(UidMapTest, TestClearingOutput) { Loading