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