diff options
| author | 2018-10-29 11:41:56 -0700 | |
|---|---|---|
| committer | 2018-10-30 16:24:25 -0700 | |
| commit | 730403e7572eb9997adb1727867d9a1dd2b490aa (patch) | |
| tree | 0b059c8be53311bee130150b8ba1a6fadf5cb493 | |
| parent | 68585439aaa41be3275a35de29e84e8ccb2fc062 (diff) | |
Statsd uidmap includes vers string and installer
Each config can choose to include version strings and installer with
each metrics report. This data may be useful in the cloud to filter
the app-specific data.
BUG: 115626330
Change-Id: I3972ff2a94e7f0347ac0cc8a443cf328c1731e13
Test: Modified unit-tests, verified on marlin-eng
| -rw-r--r-- | cmds/statsd/src/StatsLogProcessor.cpp | 8 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsService.cpp | 11 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsService.h | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricsManager.h | 10 | ||||
| -rw-r--r-- | cmds/statsd/src/packages/UidMap.cpp | 75 | ||||
| -rw-r--r-- | cmds/statsd/src/packages/UidMap.h | 26 | ||||
| -rw-r--r-- | cmds/statsd/src/stats_log.proto | 12 | ||||
| -rw-r--r-- | cmds/statsd/src/statsd_config.proto | 4 | ||||
| -rw-r--r-- | cmds/statsd/tests/LogEntryMatcher_test.cpp | 18 | ||||
| -rw-r--r-- | cmds/statsd/tests/StatsLogProcessor_test.cpp | 6 | ||||
| -rw-r--r-- | cmds/statsd/tests/UidMap_test.cpp | 102 | ||||
| -rw-r--r-- | cmds/statsd/tests/e2e/Attribution_e2e_test.cpp | 8 | ||||
| -rw-r--r-- | cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp | 32 | ||||
| -rw-r--r-- | core/java/android/os/IStatsManager.aidl | 9 | ||||
| -rw-r--r-- | services/core/java/com/android/server/stats/StatsCompanionService.java | 25 |
16 files changed, 271 insertions, 83 deletions
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index f4c70bee2806..1cd60fe2b709 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -354,11 +354,9 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, // This skips the uid map if it's an empty config. if (it->second->getNumMetrics() > 0) { uint64_t uidMapToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP); - if (it->second->hashStringInReport()) { - mUidMap->appendUidMap(dumpTimeStampNs, key, &str_set, proto); - } else { - mUidMap->appendUidMap(dumpTimeStampNs, key, nullptr, proto); - } + mUidMap->appendUidMap( + dumpTimeStampNs, key, it->second->hashStringInReport() ? &str_set : nullptr, + it->second->versionStringsInReport(), it->second->installerInReport(), proto); proto->end(uidMapToken); } diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index ce2877731882..148e1472a960 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -750,21 +750,24 @@ status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) { } Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version, - const vector<String16>& app) { + const vector<String16>& version_string, + const vector<String16>& app, + const vector<String16>& installer) { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informAllUidData was called"); - mUidMap->updateMap(getElapsedRealtimeNs(), uid, version, app); + mUidMap->updateMap(getElapsedRealtimeNs(), uid, version, version_string, app, installer); VLOG("StatsService::informAllUidData succeeded"); return Status::ok(); } -Status StatsService::informOnePackage(const String16& app, int32_t uid, int64_t version) { +Status StatsService::informOnePackage(const String16& app, int32_t uid, int64_t version, + const String16& version_string, const String16& installer) { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informOnePackage was called"); - mUidMap->updateApp(getElapsedRealtimeNs(), app, uid, version); + mUidMap->updateApp(getElapsedRealtimeNs(), app, uid, version, version_string, installer); return Status::ok(); } diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index cbf34292c1d4..895bd652e655 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -73,8 +73,10 @@ public: virtual Status informAlarmForSubscriberTriggeringFired(); virtual Status informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version, - const vector<String16>& app); - virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version); + const vector<String16>& version_string, + const vector<String16>& app, const vector<String16>& installer); + virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version, + const String16& version_string, const String16& installer); virtual Status informOnePackageRemoved(const String16& app, int32_t uid); virtual Status informDeviceShutdown(); diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index f85ba1f93e8c..c2e0f4d84d80 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -77,6 +77,8 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config, mActivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, mNoReportMetricIds); mHashStringsInReport = config.hash_strings_in_metric_report(); + mVersionStringsInReport = config.version_strings_in_metric_report(); + mInstallerInReport = config.installer_in_metric_report(); if (config.allowed_log_source_size() == 0) { mConfigValid = false; diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 649222ffef9d..0aa18ade436f 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -83,6 +83,14 @@ public: return mHashStringsInReport; }; + inline bool versionStringsInReport() const { + return mVersionStringsInReport; + }; + + inline bool installerInReport() const { + return mInstallerInReport; + }; + void refreshTtl(const int64_t currentTimestampNs) { if (mTtlNs > 0) { mTtlEndNs = currentTimestampNs + mTtlNs; @@ -125,6 +133,8 @@ private: bool mConfigValid = false; bool mHashStringsInReport = false; + bool mVersionStringsInReport = false; + bool mInstallerInReport = false; const int64_t mTtlNs; int64_t mTtlEndNs; diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp index 37a00673959c..59f3f0448e0e 100644 --- a/cmds/statsd/src/packages/UidMap.cpp +++ b/cmds/statsd/src/packages/UidMap.cpp @@ -49,6 +49,10 @@ const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2; const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3; const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4; const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5; +const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING = 6; +const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH = 7; +const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER = 8; +const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH = 9; const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1; const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2; const int FIELD_ID_SNAPSHOTS = 1; @@ -60,6 +64,10 @@ const int FIELD_ID_CHANGE_UID = 4; const int FIELD_ID_CHANGE_NEW_VERSION = 5; const int FIELD_ID_CHANGE_PREV_VERSION = 6; const int FIELD_ID_CHANGE_PACKAGE_HASH = 7; +const int FIELD_ID_CHANGE_NEW_VERSION_STRING = 8; +const int FIELD_ID_CHANGE_PREV_VERSION_STRING = 9; +const int FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH = 10; +const int FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH = 11; UidMap::UidMap() : mBytesUsed(0) {} @@ -104,7 +112,8 @@ int64_t UidMap::getAppVersion(int uid, const string& packageName) const { } void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid, - const vector<int64_t>& versionCode, const vector<String16>& packageName) { + const vector<int64_t>& versionCode, const vector<String16>& versionString, + const vector<String16>& packageName, const vector<String16>& installer) { vector<wp<PackageInfoListener>> broadcastList; { lock_guard<mutex> lock(mMutex); // Exclusively lock for updates. @@ -121,7 +130,9 @@ void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid, mMap.clear(); for (size_t j = 0; j < uid.size(); j++) { string package = string(String8(packageName[j]).string()); - mMap[std::make_pair(uid[j], package)] = AppData(versionCode[j]); + mMap[std::make_pair(uid[j], package)] = + AppData(versionCode[j], string(String8(versionString[j]).string()), + string(String8(installer[j]).string())); } for (const auto& kv : deletedApps) { @@ -150,23 +161,30 @@ void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid, } void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid, - const int64_t& versionCode) { + const int64_t& versionCode, const String16& versionString, + const String16& installer) { vector<wp<PackageInfoListener>> broadcastList; string appName = string(String8(app_16).string()); { lock_guard<mutex> lock(mMutex); int32_t prevVersion = 0; + string prevVersionString = ""; + string newVersionString = string(String8(versionString).string()); bool found = false; auto it = mMap.find(std::make_pair(uid, appName)); if (it != mMap.end()) { found = true; prevVersion = it->second.versionCode; + prevVersionString = it->second.versionString; it->second.versionCode = versionCode; + it->second.versionString = newVersionString; + it->second.installer = string(String8(installer).string()); it->second.deleted = false; } if (!found) { // Otherwise, we need to add an app at this uid. - mMap[std::make_pair(uid, appName)] = AppData(versionCode); + mMap[std::make_pair(uid, appName)] = + AppData(versionCode, newVersionString, string(String8(installer).string())); } else { // Only notify the listeners if this is an app upgrade. If this app is being installed // for the first time, then we don't notify the listeners. @@ -174,7 +192,8 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i // app after deletion. getListenerListCopyLocked(&broadcastList); } - mChanges.emplace_back(false, timestamp, appName, uid, versionCode, prevVersion); + mChanges.emplace_back(false, timestamp, appName, uid, versionCode, newVersionString, + prevVersion, prevVersionString); mBytesUsed += kBytesChangeRecord; ensureBytesUsedBelowLimit(); StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed); @@ -226,10 +245,12 @@ void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const i lock_guard<mutex> lock(mMutex); int64_t prevVersion = 0; + string prevVersionString = ""; auto key = std::make_pair(uid, app); auto it = mMap.find(key); if (it != mMap.end() && !it->second.deleted) { prevVersion = it->second.versionCode; + prevVersionString = it->second.versionString; it->second.deleted = true; mDeletedApps.push_back(key); } @@ -240,7 +261,7 @@ void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const i mMap.erase(oldest); StatsdStats::getInstance().noteUidMapAppDeletionDropped(); } - mChanges.emplace_back(true, timestamp, app, uid, 0, prevVersion); + mChanges.emplace_back(true, timestamp, app, uid, 0, "", prevVersion, prevVersionString); mBytesUsed += kBytesChangeRecord; ensureBytesUsedBelowLimit(); StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed); @@ -315,8 +336,9 @@ size_t UidMap::getBytesUsed() const { return mBytesUsed; } -void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, - std::set<string> *str_set, ProtoOutputStream* proto) { +void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set, + bool includeVersionStrings, bool includeInstaller, + ProtoOutputStream* proto) { lock_guard<mutex> lock(mMutex); // Lock for updates for (const ChangeRecord& record : mChanges) { @@ -330,8 +352,22 @@ void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, str_set->insert(record.package); proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH, (long long)Hash64(record.package)); + if (includeVersionStrings) { + str_set->insert(record.versionString); + proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH, + (long long)Hash64(record.versionString)); + str_set->insert(record.prevVersionString); + proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH, + (long long)Hash64(record.prevVersionString)); + } } else { proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package); + if (includeVersionStrings) { + proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_NEW_VERSION_STRING, + record.versionString); + proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PREV_VERSION_STRING, + record.prevVersionString); + } } proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid); @@ -354,8 +390,26 @@ void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, str_set->insert(kv.first.second); proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH, (long long)Hash64(kv.first.second)); + if (includeVersionStrings) { + str_set->insert(kv.second.versionString); + proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH, + (long long)Hash64(kv.second.versionString)); + } + if (includeInstaller) { + str_set->insert(kv.second.installer); + proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH, + (long long)Hash64(kv.second.installer)); + } } else { proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, kv.first.second); + if (includeVersionStrings) { + proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING, + kv.second.versionString); + } + if (includeInstaller) { + proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER, + kv.second.installer); + } } proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION, @@ -391,8 +445,9 @@ void UidMap::printUidMap(int out) const { for (const auto& kv : mMap) { if (!kv.second.deleted) { - dprintf(out, "%s, v%" PRId64 " (%i)\n", kv.first.second.c_str(), kv.second.versionCode, - kv.first.first); + dprintf(out, "%s, v%" PRId64 ", %s, %s (%i)\n", kv.first.second.c_str(), + kv.second.versionCode, kv.second.versionString.c_str(), + kv.second.installer.c_str(), kv.first.first); } } } diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h index 4598369f1222..75ff507ef09a 100644 --- a/cmds/statsd/src/packages/UidMap.h +++ b/cmds/statsd/src/packages/UidMap.h @@ -44,12 +44,16 @@ namespace statsd { struct AppData { int64_t versionCode; + string versionString; + string installer; bool deleted; // Empty constructor needed for unordered map. AppData() { } - AppData(const int64_t v) : versionCode(v), deleted(false){}; + + AppData(const int64_t v, const string& versionString, const string& installer) + : versionCode(v), versionString(versionString), installer(installer), deleted(false){}; }; // When calling appendUidMap, we retrieve all the ChangeRecords since the last @@ -61,15 +65,20 @@ struct ChangeRecord { const int32_t uid; const int64_t version; const int64_t prevVersion; + const string versionString; + const string prevVersionString; ChangeRecord(const bool isDeletion, const int64_t timestampNs, const string& package, - const int32_t uid, const int64_t version, const int64_t prevVersion) + const int32_t uid, const int64_t version, const string versionString, + const int64_t prevVersion, const string prevVersionString) : deletion(isDeletion), timestampNs(timestampNs), package(package), uid(uid), version(version), - prevVersion(prevVersion) { + prevVersion(prevVersion), + versionString(versionString), + prevVersionString(prevVersionString) { } }; @@ -87,10 +96,12 @@ public: * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j]. */ void updateMap(const int64_t& timestamp, const vector<int32_t>& uid, - const vector<int64_t>& versionCode, const vector<String16>& packageName); + const vector<int64_t>& versionCode, const vector<String16>& versionString, + const vector<String16>& packageName, const vector<String16>& installer); void updateApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid, - const int64_t& versionCode); + const int64_t& versionCode, const String16& versionString, + const String16& installer); void removeApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid); // Returns true if the given uid contains the specified app (eg. com.google.android.gms). @@ -127,8 +138,9 @@ public: // Gets all snapshots and changes that have occurred since the last output. // If every config key has received a change or snapshot record, then this // record is deleted. - void appendUidMap(const int64_t& timestamp, const ConfigKey& key, - std::set<string> *str_set, util::ProtoOutputStream* proto); + void appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set, + bool includeVersionStrings, bool includeInstaller, + util::ProtoOutputStream* proto); // Forces the output to be cleared. We still generate a snapshot based on the current state. // This results in extra data uploaded but helps us reconstruct the uid mapping on the server diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 10ed7f3ebaa1..b19cb8cb3996 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -223,6 +223,14 @@ message UidMapping { optional bool deleted = 4; optional uint64 name_hash = 5; + + optional string version_string = 6; + + optional uint64 version_string_hash = 7; + + optional string installer = 8; + + optional uint64 installer_hash = 9; } optional int64 elapsed_timestamp_nanos = 1; @@ -240,6 +248,10 @@ message UidMapping { optional int64 new_version = 5; optional int64 prev_version = 6; optional uint64 app_hash = 7; + optional string new_version_string = 8; + optional string prev_version_string = 9; + optional uint64 new_version_string_hash = 10; + optional uint64 prev_version_string_hash = 11; } repeated Change changes = 2; } diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index d5f81a593082..e1f5a7c79765 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -397,6 +397,10 @@ message StatsdConfig { repeated MetricActivation metric_activation = 17; + optional bool version_strings_in_metric_report = 18; + + optional bool installer_in_metric_report = 19; + // Field number 1000 is reserved for later use. reserved 1000; } diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 4c6671dcd663..2b9528f7d1de 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -148,8 +148,12 @@ TEST(AtomMatcherTest, TestAttributionMatcher) { uidMap.updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), - android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) @@ -297,8 +301,12 @@ TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), - android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1111); @@ -372,8 +380,12 @@ TEST(AtomMatcherTest, TestEqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), - android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1067); diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index b6f635c6a0cb..d92782768e40 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -153,7 +153,8 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); + m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")}, + {String16("p1"), String16("p2")}, {String16(""), String16("")}); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; @@ -182,7 +183,8 @@ TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); + m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")}, + {String16("p1"), String16("p2")}, {String16(""), String16("")}); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp index 99082cc647f6..f0d9cf188661 100644 --- a/cmds/statsd/tests/UidMap_test.cpp +++ b/cmds/statsd/tests/UidMap_test.cpp @@ -71,14 +71,20 @@ TEST(UidMapTest, TestMatching) { vector<int32_t> uids; vector<int64_t> versions; vector<String16> apps; + vector<String16> versionStrings; + vector<String16> installers; uids.push_back(1000); uids.push_back(1000); + versionStrings.push_back(String16("v1")); + versionStrings.push_back(String16("v1")); + installers.push_back(String16("")); + installers.push_back(String16("")); apps.push_back(String16(kApp1.c_str())); apps.push_back(String16(kApp2.c_str())); versions.push_back(4); versions.push_back(5); - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); EXPECT_TRUE(m.hasApp(1000, kApp1)); EXPECT_TRUE(m.hasApp(1000, kApp2)); EXPECT_FALSE(m.hasApp(1000, "not.app")); @@ -97,14 +103,20 @@ TEST(UidMapTest, TestAddAndRemove) { vector<int32_t> uids; vector<int64_t> versions; vector<String16> apps; + vector<String16> versionStrings; + vector<String16> installers; uids.push_back(1000); uids.push_back(1000); + versionStrings.push_back(String16("v1")); + versionStrings.push_back(String16("v1")); + installers.push_back(String16("")); + installers.push_back(String16("")); apps.push_back(String16(kApp1.c_str())); apps.push_back(String16(kApp2.c_str())); versions.push_back(4); versions.push_back(5); - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 2u); @@ -112,7 +124,7 @@ TEST(UidMapTest, TestAddAndRemove) { EXPECT_TRUE(name_set.find(kApp2) != name_set.end()); // Update the app1 version. - m.updateApp(2, String16(kApp1.c_str()), 1000, 40); + m.updateApp(2, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16("")); EXPECT_EQ(40, m.getAppVersion(1000, kApp1)); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); @@ -138,14 +150,15 @@ TEST(UidMapTest, TestAddAndRemove) { TEST(UidMapTest, TestUpdateApp) { UidMap m; - m.updateMap(1, {1000, 1000}, {4, 5}, {String16(kApp1.c_str()), String16(kApp2.c_str())}); + m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")}, + {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")}); 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(2, String16("NeW_aPP1_NAmE"), 1000, 40); + m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16("")); name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 3u); EXPECT_TRUE(name_set.find(kApp1) != name_set.end()); @@ -154,7 +167,7 @@ TEST(UidMapTest, TestUpdateApp) { EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end()); // This name is also reused by another uid 2000. - m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1); + m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16("")); name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */); EXPECT_EQ(name_set.size(), 1u); EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end()); @@ -185,21 +198,26 @@ TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot) { vector<int32_t> uids; vector<int64_t> versions; vector<String16> apps; + vector<String16> versionStrings; + vector<String16> installers; uids.push_back(1000); apps.push_back(String16(kApp2.c_str())); + versionStrings.push_back(String16("v1")); + installers.push_back(String16("")); versions.push_back(5); - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); // Set the last timestamp for this config key to be newer. m.mLastUpdatePerConfigKey[config1] = 2; ProtoOutputStream proto; - m.appendUidMap(3, config1, nullptr, &proto); + m.appendUidMap(3, config1, nullptr, true, true, &proto); // Check there's still a uidmap attached this one. UidMapping results; protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); + EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string()); } TEST(UidMapTest, TestRemovedAppRetained) { @@ -209,15 +227,19 @@ TEST(UidMapTest, TestRemovedAppRetained) { m.OnConfigUpdated(config1); vector<int32_t> uids; vector<int64_t> versions; + vector<String16> versionStrings; + vector<String16> installers; vector<String16> apps; uids.push_back(1000); apps.push_back(String16(kApp2.c_str())); versions.push_back(5); - m.updateMap(1, uids, versions, apps); + versionStrings.push_back(String16("v5")); + installers.push_back(String16("")); + m.updateMap(1, uids, versions, versionStrings, apps, installers); m.removeApp(2, String16(kApp2.c_str()), 1000); ProtoOutputStream proto; - m.appendUidMap(3, config1, nullptr, &proto); + m.appendUidMap(3, config1, nullptr, true, true, &proto); // Snapshot should still contain this item as deleted. UidMapping results; @@ -233,30 +255,34 @@ TEST(UidMapTest, TestRemovedAppOverGuardrail) { m.OnConfigUpdated(config1); vector<int32_t> uids; vector<int64_t> versions; + vector<String16> versionStrings; + vector<String16> installers; vector<String16> apps; const int maxDeletedApps = StatsdStats::kMaxDeletedAppsInUidMap; for (int j = 0; j < maxDeletedApps + 10; j++) { uids.push_back(j); apps.push_back(String16(kApp1.c_str())); versions.push_back(j); + versionStrings.push_back(String16("v")); + installers.push_back(String16("")); } - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); // First, verify that we have the expected number of items. UidMapping results; ProtoOutputStream proto; - m.appendUidMap(3, config1, nullptr, &proto); + m.appendUidMap(3, config1, nullptr, true, true, &proto); protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size()); // Now remove all the apps. - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); for (int j = 0; j < maxDeletedApps + 10; j++) { m.removeApp(4, String16(kApp1.c_str()), j); } proto.clear(); - m.appendUidMap(5, config1, nullptr, &proto); + m.appendUidMap(5, config1, nullptr, true, true, &proto); // Snapshot drops the first nine items. protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(maxDeletedApps, results.snapshots(0).package_info_size()); @@ -272,6 +298,8 @@ TEST(UidMapTest, TestClearingOutput) { vector<int32_t> uids; vector<int64_t> versions; + vector<String16> versionStrings; + vector<String16> installers; vector<String16> apps; uids.push_back(1000); uids.push_back(1000); @@ -279,45 +307,49 @@ TEST(UidMapTest, TestClearingOutput) { apps.push_back(String16(kApp2.c_str())); versions.push_back(4); versions.push_back(5); - m.updateMap(1, uids, versions, apps); + versionStrings.push_back(String16("v4")); + versionStrings.push_back(String16("v5")); + installers.push_back(String16("")); + installers.push_back(String16("")); + m.updateMap(1, uids, versions, versionStrings, apps, installers); ProtoOutputStream proto; - m.appendUidMap(2, config1, nullptr, &proto); + m.appendUidMap(2, config1, nullptr, true, true, &proto); UidMapping results; protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); // We have to keep at least one snapshot in memory at all times. proto.clear(); - m.appendUidMap(2, config1, nullptr, &proto); + m.appendUidMap(2, config1, nullptr, true, true, &proto); protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); // Now add another configuration. m.OnConfigUpdated(config2); - m.updateApp(5, String16(kApp1.c_str()), 1000, 40); + m.updateApp(5, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16("")); EXPECT_EQ(1U, m.mChanges.size()); proto.clear(); - m.appendUidMap(6, config1, nullptr, &proto); + m.appendUidMap(6, config1, nullptr, true, true, &proto); protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); EXPECT_EQ(1, results.changes_size()); EXPECT_EQ(1U, m.mChanges.size()); // Add another delta update. - m.updateApp(7, String16(kApp2.c_str()), 1001, 41); + m.updateApp(7, String16(kApp2.c_str()), 1001, 41, String16("v41"), String16("")); EXPECT_EQ(2U, m.mChanges.size()); // We still can't remove anything. proto.clear(); - m.appendUidMap(8, config1, nullptr, &proto); + m.appendUidMap(8, config1, nullptr, true, true, &proto); protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); EXPECT_EQ(1, results.changes_size()); EXPECT_EQ(2U, m.mChanges.size()); proto.clear(); - m.appendUidMap(9, config2, nullptr, &proto); + m.appendUidMap(9, config2, nullptr, true, true, &proto); protoOutputStreamToUidMapping(&proto, &results); EXPECT_EQ(1, results.snapshots_size()); EXPECT_EQ(2, results.changes_size()); @@ -335,19 +367,23 @@ TEST(UidMapTest, TestMemoryComputed) { vector<int32_t> uids; vector<int64_t> versions; vector<String16> apps; + vector<String16> versionStrings; + vector<String16> installers; uids.push_back(1000); apps.push_back(String16(kApp1.c_str())); versions.push_back(1); - m.updateMap(1, uids, versions, apps); + versionStrings.push_back(String16("v1")); + installers.push_back(String16("")); + m.updateMap(1, uids, versions, versionStrings, apps, installers); - m.updateApp(3, String16(kApp1.c_str()), 1000, 40); + m.updateApp(3, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16("")); ProtoOutputStream proto; vector<uint8_t> bytes; - m.appendUidMap(2, config1, nullptr, &proto); + m.appendUidMap(2, config1, nullptr, true, true, &proto); size_t prevBytes = m.mBytesUsed; - m.appendUidMap(4, config1, nullptr, &proto); + m.appendUidMap(4, config1, nullptr, true, true, &proto); EXPECT_TRUE(m.mBytesUsed < prevBytes); } @@ -361,21 +397,27 @@ TEST(UidMapTest, TestMemoryGuardrail) { size_t startBytes = m.mBytesUsed; vector<int32_t> uids; vector<int64_t> versions; + vector<String16> versionStrings; + vector<String16> installers; vector<String16> apps; for (int i = 0; i < 100; i++) { uids.push_back(1); buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i); apps.push_back(String16(buf.c_str())); versions.push_back(1); + versionStrings.push_back(String16("v1")); + installers.push_back(String16("")); } - m.updateMap(1, uids, versions, apps); + m.updateMap(1, uids, versions, versionStrings, apps, installers); - m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2); + m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2, + String16("v2"), String16("")); EXPECT_EQ(1U, m.mChanges.size()); // Now force deletion by limiting the memory to hold one delta change. - m.maxBytesOverride = 80; // Since the app string alone requires >45 characters. - m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4); + m.maxBytesOverride = 120; // Since the app string alone requires >45 characters. + m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4, + String16("v4"), String16("")); EXPECT_EQ(1U, m.mChanges.size()); } diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp index a8fcc8163656..16737e1ff625 100644 --- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp @@ -69,8 +69,10 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) { // Here it assumes that GMS core has two uids. processor->getUidMap()->updateMap( 1, {222, 444, 111, 333}, {1, 1, 2, 2}, + {String16("v1"), String16("v1"), String16("v2"), String16("v2")}, {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"), - String16("APP3")}); + String16("APP3")}, + {String16(""), String16(""), String16(""), String16("")}); // GMS core node is in the middle. std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"), @@ -215,8 +217,10 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) { // Here it assumes that GMS core has two uids. processor->getUidMap()->updateMap( 1, {222, 444, 111, 333}, {1, 1, 2, 2}, + {String16("v1"), String16("v1"), String16("v2"), String16("v2")}, {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"), - String16("APP3")}); + String16("APP3")}, + {String16(""), String16(""), String16(""), String16("")}); // GMS core node is in the middle. std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"), diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index 67acd6154176..3809a8d78c58 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -132,7 +132,8 @@ TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) { service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get()); // This is a new installation, so there shouldn't be a split (should be same as the without // split case). - service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"), + String16("")); // Goes into the second bucket. service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get()); @@ -145,11 +146,13 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) { SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. - service.mUidMap->updateMap(start, {1}, {1}, {String16(kApp1.c_str())}); + service.mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())}, + {String16("")}); // Force the uidmap to update at timestamp 2. service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get()); - service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"), + String16("")); // Goes into the second bucket. service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get()); @@ -168,7 +171,8 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. - service.mUidMap->updateMap(start, {1}, {1}, {String16(kApp1.c_str())}); + service.mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())}, + {String16("")}); // Force the uidmap to update at timestamp 2. service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get()); @@ -189,13 +193,14 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { StatsService service(nullptr); // Partial buckets don't occur when app is first installed. - service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1); + service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(0)); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); - service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2, + String16("v2"), String16("")); ConfigMetricsReport report = GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true); @@ -206,14 +211,15 @@ TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { StatsService service(nullptr); // Partial buckets don't occur when app is first installed. - service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1); + service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */)); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2; service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); - service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"), + String16("")); ConfigMetricsReport report = GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true); @@ -229,13 +235,14 @@ TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { StatsService service(nullptr); // Partial buckets don't occur when app is first installed. - service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1); + service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeGaugeMetricConfig(0)); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); - service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2, + String16("v2"), String16("")); ConfigMetricsReport report = GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true); @@ -246,14 +253,15 @@ TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) { StatsService service(nullptr); // Partial buckets don't occur when app is first installed. - service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1); + service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */)); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2; service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); - service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2); + service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"), + String16("")); ConfigMetricsReport report = GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true); diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl index 124f2072933e..74d434c51781 100644 --- a/core/java/android/os/IStatsManager.aidl +++ b/core/java/android/os/IStatsManager.aidl @@ -62,12 +62,15 @@ interface IStatsManager { * Inform statsd what the version and package are for each uid. Note that each array should * have the same number of elements, and version[i] and package[i] correspond to uid[i]. */ - oneway void informAllUidData(in int[] uid, in long[] version, in String[] app); + oneway void informAllUidData(in int[] uid, in long[] version, in String[] version_string, + in String[] app, in String[] installer); /** - * Inform statsd what the uid and version are for one app that was updated. + * Inform statsd what the uid, version, version_string, and installer are for one app that was + * updated. */ - oneway void informOnePackage(in String app, in int uid, in long version); + oneway void informOnePackage(in String app, in int uid, in long version, + in String version_string, in String installer); /** * Inform stats that an app was removed. diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 5600749ee437..7c57dd3bc9f3 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -346,6 +346,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { List<Integer> uids = new ArrayList<>(); List<Long> versions = new ArrayList<>(); List<String> apps = new ArrayList<>(); + List<String> versionStrings = new ArrayList<>(); + List<String> installers = new ArrayList<>(); // Add in all the apps for every user/profile. for (UserInfo profile : users) { @@ -353,14 +355,24 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id); for (int j = 0; j < pi.size(); j++) { if (pi.get(j).applicationInfo != null) { + String installer; + try { + installer = pm.getInstallerPackageName(pi.get(j).packageName); + } catch (IllegalArgumentException e) { + installer = ""; + } + installers.add(installer == null ? "" : installer); uids.add(pi.get(j).applicationInfo.uid); versions.add(pi.get(j).getLongVersionCode()); + versionStrings.add(pi.get(j).versionName); apps.add(pi.get(j).packageName); } } } - sStatsd.informAllUidData(toIntArray(uids), toLongArray(versions), apps.toArray(new - String[apps.size()])); + sStatsd.informAllUidData(toIntArray(uids), toLongArray(versions), + versionStrings.toArray(new String[versionStrings.size()]), + apps.toArray(new String[apps.size()]), + installers.toArray(new String[installers.size()])); if (DEBUG) { Slog.d(TAG, "Sent data for " + uids.size() + " apps"); } @@ -402,7 +414,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { int uid = b.getInt(Intent.EXTRA_UID); String app = intent.getData().getSchemeSpecificPart(); PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER); - sStatsd.informOnePackage(app, uid, pi.getLongVersionCode()); + String installer; + try { + installer = pm.getInstallerPackageName(app); + } catch (IllegalArgumentException e) { + installer = ""; + } + sStatsd.informOnePackage(app, uid, pi.getLongVersionCode(), pi.versionName, + installer == null ? "" : installer); } } catch (Exception e) { Slog.w(TAG, "Failed to inform statsd of an app update", e); |