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