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