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