1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, versionCode 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define STATSD_DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "packages/UidMap.h"
20 
21 #include <inttypes.h>
22 #include <private/android_filesystem_config.h>
23 
24 #include "guardrail/StatsdStats.h"
25 #include "hash.h"
26 #include "stats_log_util.h"
27 
28 using namespace android;
29 
30 using android::util::FIELD_COUNT_REPEATED;
31 using android::util::FIELD_TYPE_BOOL;
32 using android::util::FIELD_TYPE_BYTES;
33 using android::util::FIELD_TYPE_FLOAT;
34 using android::util::FIELD_TYPE_INT32;
35 using android::util::FIELD_TYPE_INT64;
36 using android::util::FIELD_TYPE_MESSAGE;
37 using android::util::FIELD_TYPE_STRING;
38 using android::util::FIELD_TYPE_UINT32;
39 using android::util::FIELD_TYPE_UINT64;
40 using android::util::ProtoOutputStream;
41 
42 namespace android {
43 namespace os {
44 namespace statsd {
45 
46 namespace {
47 
48 const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
49 const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
50 const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
51 const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4;
52 const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5;
53 const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING = 6;
54 const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH = 7;
55 const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER = 8;
56 const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH = 9;
57 const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_INDEX = 10;
58 const int FIELD_ID_SNAPSHOT_PACKAGE_TRUNCATED_CERTIFICATE_HASH = 11;
59 const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
60 const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
61 const int FIELD_ID_SNAPSHOTS = 1;
62 const int FIELD_ID_CHANGES = 2;
63 const int FIELD_ID_INSTALLER_HASH = 3;
64 const int FIELD_ID_INSTALLER_NAME = 4;
65 const int FIELD_ID_CHANGE_DELETION = 1;
66 const int FIELD_ID_CHANGE_TIMESTAMP = 2;
67 const int FIELD_ID_CHANGE_PACKAGE = 3;
68 const int FIELD_ID_CHANGE_UID = 4;
69 const int FIELD_ID_CHANGE_NEW_VERSION = 5;
70 const int FIELD_ID_CHANGE_PREV_VERSION = 6;
71 const int FIELD_ID_CHANGE_PACKAGE_HASH = 7;
72 const int FIELD_ID_CHANGE_NEW_VERSION_STRING = 8;
73 const int FIELD_ID_CHANGE_PREV_VERSION_STRING = 9;
74 const int FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH = 10;
75 const int FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH = 11;
76 
omitUid(int32_t uid,const string & packageName,const UidMapOptions & options)77 bool omitUid(int32_t uid, const string& packageName, const UidMapOptions& options) {
78     // Always allow allowlisted packages
79     if (options.allowlistedPackages.contains(packageName)) {
80         return false;
81     }
82     // If omitSystemUids is true, uids for which (uid % AID_USER_OFFSET) is in [0, AID_APP_START)
83     // should be excluded. This takes precedence over if the uid is used or not.
84     if (options.omitSystemUids && uid >= 0 && uid % AID_USER_OFFSET < AID_APP_START) {
85         return true;
86     }
87     // If omitUnusedUids is true, omit the uid unless it is in the used set.
88     return options.omitUnusedUids && !options.usedUids.contains(uid);
89 }
90 
91 }  // namespace
92 
UidMap()93 UidMap::UidMap() : mBytesUsed(0) {
94 }
95 
~UidMap()96 UidMap::~UidMap() {}
97 
getInstance()98 sp<UidMap> UidMap::getInstance() {
99     static sp<UidMap> sInstance = new UidMap();
100     return sInstance;
101 }
102 
hasApp(int uid,const string & packageName) const103 bool UidMap::hasApp(int uid, const string& packageName) const {
104     lock_guard<mutex> lock(mMutex);
105 
106     auto it = mMap.find(std::make_pair(uid, packageName));
107     return it != mMap.end() && !it->second.deleted;
108 }
109 
normalizeAppName(const string & appName) const110 string UidMap::normalizeAppName(const string& appName) const {
111     string normalizedName = appName;
112     std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
113     return normalizedName;
114 }
115 
getAppNamesFromUid(const int32_t uid,bool returnNormalized) const116 std::set<string> UidMap::getAppNamesFromUid(const int32_t uid, bool returnNormalized) const {
117     lock_guard<mutex> lock(mMutex);
118     return getAppNamesFromUidLocked(uid,returnNormalized);
119 }
120 
getAppNamesFromUidLocked(const int32_t uid,bool returnNormalized) const121 std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t uid, bool returnNormalized) const {
122     std::set<string> names;
123     for (const auto& kv : mMap) {
124         if (kv.first.first == uid && !kv.second.deleted) {
125             names.insert(returnNormalized ? normalizeAppName(kv.first.second) : kv.first.second);
126         }
127     }
128     return names;
129 }
130 
getAppVersion(int uid,const string & packageName) const131 int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
132     lock_guard<mutex> lock(mMutex);
133 
134     auto it = mMap.find(std::make_pair(uid, packageName));
135     if (it == mMap.end() || it->second.deleted) {
136         return 0;
137     }
138     return it->second.versionCode;
139 }
140 
updateMap(const int64_t timestamp,const UidData & uidData)141 void UidMap::updateMap(const int64_t timestamp, const UidData& uidData) {
142     wp<PackageInfoListener> broadcast = NULL;
143     {
144         lock_guard<mutex> lock(mMutex);  // Exclusively lock for updates.
145 
146         std::unordered_map<std::pair<int, string>, AppData, PairHash> deletedApps;
147 
148         // Copy all the deleted apps.
149         for (const auto& kv : mMap) {
150             if (kv.second.deleted) {
151                 deletedApps[kv.first] = kv.second;
152             }
153         }
154 
155         mMap.clear();
156         for (const auto& appInfo : uidData.app_info()) {
157             mMap[std::make_pair(appInfo.uid(), appInfo.package_name())] =
158                     AppData(appInfo.version(), appInfo.version_string(), appInfo.installer(),
159                             appInfo.certificate_hash());
160         }
161 
162         for (const auto& kv : deletedApps) {
163             auto mMapIt = mMap.find(kv.first);
164             if (mMapIt != mMap.end()) {
165                 // Insert this deleted app back into the current map.
166                 mMap[kv.first] = kv.second;
167             }
168         }
169 
170         ensureBytesUsedBelowLimit();
171         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
172         broadcast = mSubscriber;
173     }
174     // To avoid invoking callback while holding the internal lock. we get a copy of the listener
175     // and invoke the callback. It's still possible that after we copy the listener, it removes
176     // itself before we call it. It's then the listener's job to handle it (expect the callback to
177     // be called after listener is removed, and the listener should properly ignore it).
178     auto strongPtr = broadcast.promote();
179     if (strongPtr != nullptr) {
180         strongPtr->onUidMapReceived(timestamp);
181     }
182 }
183 
updateApp(const int64_t timestamp,const string & appName,const int32_t uid,const int64_t versionCode,const string & versionString,const string & installer,const vector<uint8_t> & certificateHash)184 void UidMap::updateApp(const int64_t timestamp, const string& appName, const int32_t uid,
185                        const int64_t versionCode, const string& versionString,
186                        const string& installer, const vector<uint8_t>& certificateHash) {
187     wp<PackageInfoListener> broadcast = NULL;
188 
189     const string certificateHashString = string(certificateHash.begin(), certificateHash.end());
190     {
191         lock_guard<mutex> lock(mMutex);
192         int32_t prevVersion = 0;
193         string prevVersionString = "";
194         auto key = std::make_pair(uid, appName);
195         auto it = mMap.find(key);
196         if (it != mMap.end()) {
197             prevVersion = it->second.versionCode;
198             prevVersionString = it->second.versionString;
199             it->second.versionCode = versionCode;
200             it->second.versionString = versionString;
201             it->second.installer = installer;
202             it->second.deleted = false;
203             it->second.certificateHash = certificateHashString;
204 
205             // Only notify the listeners if this is an app upgrade. If this app is being installed
206             // for the first time, then we don't notify the listeners.
207             // It's also OK to split again if we're forming a partial bucket after re-installing an
208             // app after deletion.
209             broadcast = mSubscriber;
210         } else {
211             // Otherwise, we need to add an app at this uid.
212             mMap[key] = AppData(versionCode, versionString, installer, certificateHashString);
213         }
214 
215         mChanges.emplace_back(false, timestamp, appName, uid, versionCode, versionString,
216                               prevVersion, prevVersionString);
217         mBytesUsed += kBytesChangeRecord;
218         ensureBytesUsedBelowLimit();
219         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
220         StatsdStats::getInstance().setUidMapChanges(mChanges.size());
221     }
222 
223     auto strongPtr = broadcast.promote();
224     if (strongPtr != nullptr) {
225         strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
226     }
227 }
228 
ensureBytesUsedBelowLimit()229 void UidMap::ensureBytesUsedBelowLimit() {
230     size_t limit;
231     if (maxBytesOverride <= 0) {
232         limit = StatsdStats::kMaxBytesUsedUidMap;
233     } else {
234         limit = maxBytesOverride;
235     }
236     while (mBytesUsed > limit) {
237         ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
238         if (mChanges.size() > 0) {
239             mBytesUsed -= kBytesChangeRecord;
240             mChanges.pop_front();
241             StatsdStats::getInstance().noteUidMapDropped(1);
242         }
243     }
244 }
245 
removeApp(const int64_t timestamp,const string & app,const int32_t uid)246 void UidMap::removeApp(const int64_t timestamp, const string& app, const int32_t uid) {
247     wp<PackageInfoListener> broadcast = NULL;
248     {
249         lock_guard<mutex> lock(mMutex);
250 
251         int64_t prevVersion = 0;
252         string prevVersionString = "";
253         auto key = std::make_pair(uid, app);
254         auto it = mMap.find(key);
255         if (it != mMap.end() && !it->second.deleted) {
256             prevVersion = it->second.versionCode;
257             prevVersionString = it->second.versionString;
258             it->second.deleted = true;
259             mDeletedApps.push_back(key);
260         }
261         if (mDeletedApps.size() > StatsdStats::kMaxDeletedAppsInUidMap) {
262             // Delete the oldest one.
263             auto oldest = mDeletedApps.front();
264             mDeletedApps.pop_front();
265             mMap.erase(oldest);
266             StatsdStats::getInstance().noteUidMapAppDeletionDropped();
267         }
268         mChanges.emplace_back(true, timestamp, app, uid, 0, "", prevVersion, prevVersionString);
269         mBytesUsed += kBytesChangeRecord;
270         ensureBytesUsedBelowLimit();
271         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
272         StatsdStats::getInstance().setUidMapChanges(mChanges.size());
273         broadcast = mSubscriber;
274     }
275 
276     auto strongPtr = broadcast.promote();
277     if (strongPtr != nullptr) {
278         strongPtr->notifyAppRemoved(timestamp, app, uid);
279     }
280 }
281 
setListener(const wp<PackageInfoListener> & listener)282 void UidMap::setListener(const wp<PackageInfoListener>& listener) {
283     lock_guard<mutex> lock(mMutex);  // Lock for updates
284     mSubscriber = listener;
285 }
286 
assignIsolatedUid(int isolatedUid,int parentUid)287 void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
288     lock_guard<mutex> lock(mIsolatedMutex);
289 
290     mIsolatedUidMap[isolatedUid] = parentUid;
291 }
292 
removeIsolatedUid(int isolatedUid)293 void UidMap::removeIsolatedUid(int isolatedUid) {
294     lock_guard<mutex> lock(mIsolatedMutex);
295 
296     auto it = mIsolatedUidMap.find(isolatedUid);
297     if (it != mIsolatedUidMap.end()) {
298         mIsolatedUidMap.erase(it);
299     }
300 }
301 
getHostUidOrSelf(int uid) const302 int UidMap::getHostUidOrSelf(int uid) const {
303     lock_guard<mutex> lock(mIsolatedMutex);
304 
305     auto it = mIsolatedUidMap.find(uid);
306     if (it != mIsolatedUidMap.end()) {
307         return it->second;
308     }
309     return uid;
310 }
311 
clearOutput()312 void UidMap::clearOutput() {
313     mChanges.clear();
314     // Also update the guardrail trackers.
315     StatsdStats::getInstance().setUidMapChanges(0);
316     mBytesUsed = 0;
317     StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
318 }
319 
getMinimumTimestampNs()320 int64_t UidMap::getMinimumTimestampNs() {
321     int64_t m = 0;
322     for (const auto& kv : mLastUpdatePerConfigKey) {
323         if (m == 0) {
324             m = kv.second;
325         } else if (kv.second < m) {
326             m = kv.second;
327         }
328     }
329     return m;
330 }
331 
getBytesUsed() const332 size_t UidMap::getBytesUsed() const {
333     return mBytesUsed;
334 }
335 
writeUidMapSnapshot(int64_t timestamp,const UidMapOptions & options,const std::set<int32_t> & interestingUids,map<string,int> * installerIndices,std::set<string> * str_set,ProtoOutputStream * proto) const336 void UidMap::writeUidMapSnapshot(int64_t timestamp, const UidMapOptions& options,
337                                  const std::set<int32_t>& interestingUids,
338                                  map<string, int>* installerIndices, std::set<string>* str_set,
339                                  ProtoOutputStream* proto) const {
340     lock_guard<mutex> lock(mMutex);
341 
342     writeUidMapSnapshotLocked(timestamp, options, interestingUids, installerIndices, str_set,
343                               proto);
344 }
345 
writeUidMapSnapshotLocked(const int64_t timestamp,const UidMapOptions & options,const std::set<int32_t> & interestingUids,map<string,int> * installerIndices,std::set<string> * str_set,ProtoOutputStream * proto) const346 void UidMap::writeUidMapSnapshotLocked(const int64_t timestamp, const UidMapOptions& options,
347                                        const std::set<int32_t>& interestingUids,
348                                        map<string, int>* installerIndices,
349                                        std::set<string>* str_set, ProtoOutputStream* proto) const {
350     int curInstallerIndex = 0;
351 
352     proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP, (long long)timestamp);
353     for (const auto& [keyPair, appData] : mMap) {
354         const auto& [uid, packageName] = keyPair;
355         if (omitUid(uid, packageName, options) ||
356             (!interestingUids.empty() && interestingUids.find(uid) == interestingUids.end())) {
357             continue;
358         }
359         uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
360                                       FIELD_ID_SNAPSHOT_PACKAGE_INFO);
361         // Get installer index.
362         int installerIndex = -1;
363         if (options.includeInstaller && installerIndices != nullptr) {
364             const auto& it = installerIndices->find(appData.installer);
365             if (it == installerIndices->end()) {
366                 // We have not encountered this installer yet; add it to installerIndices.
367                 (*installerIndices)[appData.installer] = curInstallerIndex;
368                 installerIndex = curInstallerIndex;
369                 curInstallerIndex++;
370             } else {
371                 installerIndex = it->second;
372             }
373         }
374 
375         if (str_set != nullptr) {  // Hash strings in report
376             str_set->insert(packageName);
377             proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH,
378                          (long long)Hash64(packageName));
379             if (options.includeVersionStrings) {
380                 str_set->insert(appData.versionString);
381                 proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH,
382                              (long long)Hash64(appData.versionString));
383             }
384             if (options.includeInstaller) {
385                 str_set->insert(appData.installer);
386                 if (installerIndex != -1) {
387                     // Write installer index.
388                     proto->write(FIELD_TYPE_UINT32 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_INDEX,
389                                  installerIndex);
390                 } else {
391                     proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH,
392                                  (long long)Hash64(appData.installer));
393                 }
394             }
395         } else {  // Strings not hashed in report
396             proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, packageName);
397             if (options.includeVersionStrings) {
398                 proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING,
399                              appData.versionString);
400             }
401             if (options.includeInstaller) {
402                 if (installerIndex != -1) {
403                     proto->write(FIELD_TYPE_UINT32 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_INDEX,
404                                  installerIndex);
405                 } else {
406                     proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER,
407                                  appData.installer);
408                 }
409             }
410         }
411 
412         const size_t dumpHashSize =
413                 options.truncatedCertificateHashSize <= appData.certificateHash.size()
414                         ? options.truncatedCertificateHashSize
415                         : appData.certificateHash.size();
416         if (dumpHashSize > 0) {
417             proto->write(FIELD_TYPE_BYTES | FIELD_ID_SNAPSHOT_PACKAGE_TRUNCATED_CERTIFICATE_HASH,
418                          appData.certificateHash.c_str(), dumpHashSize);
419         }
420 
421         proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
422                      (long long)appData.versionCode);
423         proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, uid);
424         proto->write(FIELD_TYPE_BOOL | FIELD_ID_SNAPSHOT_PACKAGE_DELETED, appData.deleted);
425         proto->end(token);
426     }
427 }
428 
appendUidMap(const int64_t timestamp,const ConfigKey & key,const UidMapOptions & options,std::set<string> * str_set,ProtoOutputStream * proto)429 void UidMap::appendUidMap(const int64_t timestamp, const ConfigKey& key,
430                           const UidMapOptions& options, std::set<string>* str_set,
431                           ProtoOutputStream* proto) {
432     lock_guard<mutex> lock(mMutex);  // Lock for updates
433 
434     for (const ChangeRecord& record : mChanges) {
435         if (omitUid(record.uid, record.package, options) ||
436             record.timestampNs <= mLastUpdatePerConfigKey[key]) {
437             continue;
438         }
439 
440         uint64_t changesToken =
441                 proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
442         proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
443         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP, (long long)record.timestampNs);
444         if (str_set != nullptr) {
445             str_set->insert(record.package);
446             proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH,
447                          (long long)Hash64(record.package));
448             if (options.includeVersionStrings) {
449                 str_set->insert(record.versionString);
450                 proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH,
451                              (long long)Hash64(record.versionString));
452                 str_set->insert(record.prevVersionString);
453                 proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH,
454                              (long long)Hash64(record.prevVersionString));
455             }
456         } else {
457             proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
458             if (options.includeVersionStrings) {
459                 proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_NEW_VERSION_STRING,
460                              record.versionString);
461                 proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PREV_VERSION_STRING,
462                              record.prevVersionString);
463             }
464         }
465 
466         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
467         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_NEW_VERSION, (long long)record.version);
468         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_PREV_VERSION,
469                      (long long)record.prevVersion);
470         proto->end(changesToken);
471     }
472 
473     map<string, int> installerIndices;
474 
475     // Write snapshot from current uid map state.
476     uint64_t snapshotsToken =
477             proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
478     writeUidMapSnapshotLocked(timestamp, options,
479                               std::set<int32_t>() /*empty uid set means including every uid*/,
480                               &installerIndices, str_set, proto);
481     proto->end(snapshotsToken);
482 
483     vector<string> installers(installerIndices.size(), "");
484     for (const auto& [installer, index] : installerIndices) {
485         // index is guaranteed to be < installers.size().
486         installers[index] = installer;
487     }
488 
489     if (options.includeInstaller) {
490         // Write installer list; either strings or hashes.
491         for (const string& installerName : installers) {
492             if (str_set == nullptr) {  // Strings not hashed
493                 proto->write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | FIELD_ID_INSTALLER_NAME,
494                              installerName);
495             } else {  // Strings are hashed
496                 proto->write(FIELD_TYPE_UINT64 | FIELD_COUNT_REPEATED | FIELD_ID_INSTALLER_HASH,
497                              (long long)Hash64(installerName));
498             }
499         }
500     }
501 
502     int64_t prevMin = getMinimumTimestampNs();
503     mLastUpdatePerConfigKey[key] = timestamp;
504     int64_t newMin = getMinimumTimestampNs();
505 
506     if (newMin > prevMin) {  // Delete anything possible now that the minimum has
507                              // moved forward.
508         int64_t cutoff_nanos = newMin;
509         for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
510             if (it_changes->timestampNs < cutoff_nanos) {
511                 mBytesUsed -= kBytesChangeRecord;
512                 it_changes = mChanges.erase(it_changes);
513             } else {
514                 ++it_changes;
515             }
516         }
517     }
518     StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
519     StatsdStats::getInstance().setUidMapChanges(mChanges.size());
520 }
521 
printUidMap(int out,bool includeCertificateHash) const522 void UidMap::printUidMap(int out, bool includeCertificateHash) const {
523     lock_guard<mutex> lock(mMutex);
524 
525     for (const auto& [keyPair, appData] : mMap) {
526         const auto& [uid, packageName] = keyPair;
527         if (!appData.deleted) {
528             if (includeCertificateHash) {
529                 const string& certificateHashHexString = toHexString(appData.certificateHash);
530                 dprintf(out, "%s, v%" PRId64 ", %s, %s (%i), %s\n", packageName.c_str(),
531                         appData.versionCode, appData.versionString.c_str(),
532                         appData.installer.c_str(), uid, certificateHashHexString.c_str());
533             } else {
534                 dprintf(out, "%s, v%" PRId64 ", %s, %s (%i)\n", packageName.c_str(),
535                         appData.versionCode, appData.versionString.c_str(),
536                         appData.installer.c_str(), uid);
537             }
538         }
539     }
540 }
541 
OnConfigUpdated(const ConfigKey & key)542 void UidMap::OnConfigUpdated(const ConfigKey& key) {
543     mLastUpdatePerConfigKey[key] = -1;
544 }
545 
OnConfigRemoved(const ConfigKey & key)546 void UidMap::OnConfigRemoved(const ConfigKey& key) {
547     mLastUpdatePerConfigKey.erase(key);
548 }
549 
getAppUid(const string & package) const550 set<int32_t> UidMap::getAppUid(const string& package) const {
551     lock_guard<mutex> lock(mMutex);
552 
553     set<int32_t> results;
554     for (const auto& kv : mMap) {
555         if (kv.first.second == package && !kv.second.deleted) {
556             results.insert(kv.first.first);
557         }
558     }
559     return results;
560 }
561 
562 // Note not all the following AIDs are used as uids. Some are used only for gids.
563 // It's ok to leave them in the map, but we won't ever see them in the log's uid field.
564 // App's uid starts from 10000, and will not overlap with the following AIDs.
565 const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
566                                                              {"AID_SYSTEM", 1000},
567                                                              {"AID_RADIO", 1001},
568                                                              {"AID_BLUETOOTH", 1002},
569                                                              {"AID_GRAPHICS", 1003},
570                                                              {"AID_INPUT", 1004},
571                                                              {"AID_AUDIO", 1005},
572                                                              {"AID_CAMERA", 1006},
573                                                              {"AID_LOG", 1007},
574                                                              {"AID_COMPASS", 1008},
575                                                              {"AID_MOUNT", 1009},
576                                                              {"AID_WIFI", 1010},
577                                                              {"AID_ADB", 1011},
578                                                              {"AID_INSTALL", 1012},
579                                                              {"AID_MEDIA", 1013},
580                                                              {"AID_DHCP", 1014},
581                                                              {"AID_SDCARD_RW", 1015},
582                                                              {"AID_VPN", 1016},
583                                                              {"AID_KEYSTORE", 1017},
584                                                              {"AID_USB", 1018},
585                                                              {"AID_DRM", 1019},
586                                                              {"AID_MDNSR", 1020},
587                                                              {"AID_GPS", 1021},
588                                                              // {"AID_UNUSED1", 1022},
589                                                              {"AID_MEDIA_RW", 1023},
590                                                              {"AID_MTP", 1024},
591                                                              // {"AID_UNUSED2", 1025},
592                                                              {"AID_DRMRPC", 1026},
593                                                              {"AID_NFC", 1027},
594                                                              {"AID_SDCARD_R", 1028},
595                                                              {"AID_CLAT", 1029},
596                                                              {"AID_LOOP_RADIO", 1030},
597                                                              {"AID_MEDIA_DRM", 1031},
598                                                              {"AID_PACKAGE_INFO", 1032},
599                                                              {"AID_SDCARD_PICS", 1033},
600                                                              {"AID_SDCARD_AV", 1034},
601                                                              {"AID_SDCARD_ALL", 1035},
602                                                              {"AID_LOGD", 1036},
603                                                              {"AID_SHARED_RELRO", 1037},
604                                                              {"AID_DBUS", 1038},
605                                                              {"AID_TLSDATE", 1039},
606                                                              {"AID_MEDIA_EX", 1040},
607                                                              {"AID_AUDIOSERVER", 1041},
608                                                              {"AID_METRICS_COLL", 1042},
609                                                              {"AID_METRICSD", 1043},
610                                                              {"AID_WEBSERV", 1044},
611                                                              {"AID_DEBUGGERD", 1045},
612                                                              {"AID_MEDIA_CODEC", 1046},
613                                                              {"AID_CAMERASERVER", 1047},
614                                                              {"AID_FIREWALL", 1048},
615                                                              {"AID_TRUNKS", 1049},
616                                                              {"AID_NVRAM", 1050},
617                                                              {"AID_DNS", 1051},
618                                                              {"AID_DNS_TETHER", 1052},
619                                                              {"AID_WEBVIEW_ZYGOTE", 1053},
620                                                              {"AID_VEHICLE_NETWORK", 1054},
621                                                              {"AID_MEDIA_AUDIO", 1055},
622                                                              {"AID_MEDIA_VIDEO", 1056},
623                                                              {"AID_MEDIA_IMAGE", 1057},
624                                                              {"AID_TOMBSTONED", 1058},
625                                                              {"AID_MEDIA_OBB", 1059},
626                                                              {"AID_ESE", 1060},
627                                                              {"AID_OTA_UPDATE", 1061},
628                                                              {"AID_AUTOMOTIVE_EVS", 1062},
629                                                              {"AID_LOWPAN", 1063},
630                                                              {"AID_HSM", 1064},
631                                                              {"AID_RESERVED_DISK", 1065},
632                                                              {"AID_STATSD", 1066},
633                                                              {"AID_INCIDENTD", 1067},
634                                                              {"AID_SECURE_ELEMENT", 1068},
635                                                              {"AID_LMKD", 1069},
636                                                              {"AID_LLKD", 1070},
637                                                              {"AID_IORAPD", 1071},
638                                                              {"AID_GPU_SERVICE", 1072},
639                                                              {"AID_NETWORK_STACK", 1073},
640                                                              {"AID_GSID", 1074},
641                                                              {"AID_FSVERITY_CERT", 1075},
642                                                              {"AID_CREDSTORE", 1076},
643                                                              {"AID_EXTERNAL_STORAGE", 1077},
644                                                              {"AID_EXT_DATA_RW", 1078},
645                                                              {"AID_EXT_OBB_RW", 1079},
646                                                              {"AID_CONTEXT_HUB", 1080},
647                                                              {"AID_VIRTUALIZATIONSERVICE", 1081},
648                                                              {"AID_ARTD", 1082},
649                                                              {"AID_UWB", 1083},
650                                                              {"AID_THREAD_NETWORK", 1084},
651                                                              {"AID_DICED", 1085},
652                                                              {"AID_DMESGD", 1086},
653                                                              {"AID_JC_WEAVER", 1087},
654                                                              {"AID_JC_STRONGBOX", 1088},
655                                                              {"AID_JC_IDENTITYCRED", 1089},
656                                                              {"AID_SDK_SANDBOX", 1090},
657                                                              {"AID_SECURITY_LOG_WRITER", 1091},
658                                                              {"AID_PRNG_SEEDER", 1092},
659                                                              {"AID_UPROBESTATS", 1093},
660                                                              {"AID_SHELL", 2000},
661                                                              {"AID_CACHE", 2001},
662                                                              {"AID_DIAG", 2002},
663                                                              {"AID_NOBODY", 9999}};
664 
665 }  // namespace statsd
666 }  // namespace os
667 }  // namespace android
668