blob: 3d07c4465d067e2156c48fa11490da9f7a3b649d [file] [log] [blame]
David Chende701692017-10-05 13:16:02 -07001/*
yro0feae942017-11-15 14:38:48 -08002 * Copyright (C) 2017 The Android Open Source Project
David Chende701692017-10-05 13:16:02 -07003 *
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 */
David Chenf384b902018-03-14 18:36:45 -070016#define DEBUG false // STOPSHIP if true
Joe Onorato9fc9edf2017-10-15 20:08:52 -070017#include "Log.h"
18
Yangster-mac330af582018-02-08 15:24:38 -080019#include "stats_log_util.h"
David Chenc136f45a2017-11-27 11:52:26 -080020#include "guardrail/StatsdStats.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070021#include "packages/UidMap.h"
22
David Chenc136f45a2017-11-27 11:52:26 -080023#include <android/os/IStatsCompanionService.h>
24#include <binder/IServiceManager.h>
David Chende701692017-10-05 13:16:02 -070025#include <utils/Errors.h>
26
Dianne Hackborn3accca02013-09-20 09:32:11 -070027#include <inttypes.h>
28
David Chende701692017-10-05 13:16:02 -070029using namespace android;
30
David Chenf384b902018-03-14 18:36:45 -070031using android::base::StringPrintf;
32using android::util::FIELD_COUNT_REPEATED;
33using android::util::FIELD_TYPE_BOOL;
34using android::util::FIELD_TYPE_FLOAT;
35using android::util::FIELD_TYPE_INT32;
36using android::util::FIELD_TYPE_INT64;
37using android::util::FIELD_TYPE_MESSAGE;
38using android::util::FIELD_TYPE_STRING;
39using android::util::ProtoOutputStream;
40
David Chende701692017-10-05 13:16:02 -070041namespace android {
42namespace os {
43namespace statsd {
44
David Chenf384b902018-03-14 18:36:45 -070045const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
46const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
47const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
48const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
49const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
50const int FIELD_ID_SNAPSHOTS = 1;
51const int FIELD_ID_CHANGES = 2;
52const int FIELD_ID_CHANGE_DELETION = 1;
53const int FIELD_ID_CHANGE_TIMESTAMP = 2;
54const int FIELD_ID_CHANGE_PACKAGE = 3;
55const int FIELD_ID_CHANGE_UID = 4;
56const int FIELD_ID_CHANGE_VERSION = 5;
57
Yangster9df9a7f2017-12-18 13:33:05 -080058UidMap::UidMap() : mBytesUsed(0) {}
59
60UidMap::~UidMap() {}
David Chenc136f45a2017-11-27 11:52:26 -080061
David Chende701692017-10-05 13:16:02 -070062bool UidMap::hasApp(int uid, const string& packageName) const {
63 lock_guard<mutex> lock(mMutex);
64
65 auto range = mMap.equal_range(uid);
66 for (auto it = range.first; it != range.second; ++it) {
67 if (it->second.packageName == packageName) {
68 return true;
69 }
70 }
71 return false;
72}
73
Yangster9df9a7f2017-12-18 13:33:05 -080074string UidMap::normalizeAppName(const string& appName) const {
75 string normalizedName = appName;
76 std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
77 return normalizedName;
78}
79
80std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
81 lock_guard<mutex> lock(mMutex);
82 return getAppNamesFromUidLocked(uid,returnNormalized);
83}
84
85std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
86 std::set<string> names;
87 auto range = mMap.equal_range(uid);
88 for (auto it = range.first; it != range.second; ++it) {
89 names.insert(returnNormalized ?
90 normalizeAppName(it->second.packageName) : it->second.packageName);
91 }
92 return names;
93}
94
Dianne Hackborn3accca02013-09-20 09:32:11 -070095int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
David Chende701692017-10-05 13:16:02 -070096 lock_guard<mutex> lock(mMutex);
97
98 auto range = mMap.equal_range(uid);
99 for (auto it = range.first; it != range.second; ++it) {
100 if (it->second.packageName == packageName) {
101 return it->second.versionCode;
102 }
103 }
104 return 0;
105}
106
Dianne Hackborn3accca02013-09-20 09:32:11 -0700107void UidMap::updateMap(const vector<int32_t>& uid, const vector<int64_t>& versionCode,
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700108 const vector<String16>& packageName) {
Yangster-mac330af582018-02-08 15:24:38 -0800109 updateMap(getElapsedRealtimeNs(), uid, versionCode, packageName);
David Chend6896892017-10-25 11:49:03 -0700110}
111
112void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
Dianne Hackborn3accca02013-09-20 09:32:11 -0700113 const vector<int64_t>& versionCode, const vector<String16>& packageName) {
Yao Chend10f7b12017-12-18 12:53:50 -0800114 vector<wp<PackageInfoListener>> broadcastList;
115 {
116 lock_guard<mutex> lock(mMutex); // Exclusively lock for updates.
David Chende701692017-10-05 13:16:02 -0700117
Yao Chend10f7b12017-12-18 12:53:50 -0800118 mMap.clear();
David Chenf384b902018-03-14 18:36:45 -0700119 ProtoOutputStream proto;
120 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
121 FIELD_ID_SNAPSHOT_PACKAGE_INFO);
Yao Chend10f7b12017-12-18 12:53:50 -0800122 for (size_t j = 0; j < uid.size(); j++) {
David Chenf384b902018-03-14 18:36:45 -0700123 string package = string(String8(packageName[j]).string());
124 mMap.insert(make_pair(uid[j], AppData(package, versionCode[j])));
125 proto.write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, package);
126 proto.write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION, (int)versionCode[j]);
127 proto.write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, (int)uid[j]);
Yao Chend10f7b12017-12-18 12:53:50 -0800128 }
David Chenf384b902018-03-14 18:36:45 -0700129 proto.end(token);
David Chende701692017-10-05 13:16:02 -0700130
David Chenf384b902018-03-14 18:36:45 -0700131 // Copy ProtoOutputStream output to
132 auto iter = proto.data();
133 size_t pos = 0;
134 vector<char> outData(proto.size());
135 while (iter.readBuffer() != NULL) {
136 size_t toRead = iter.currentToRead();
137 std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
138 pos += toRead;
139 iter.rp()->move(toRead);
Yao Chend10f7b12017-12-18 12:53:50 -0800140 }
David Chenf384b902018-03-14 18:36:45 -0700141 SnapshotRecord record(timestamp, outData);
142 mSnapshots.push_back(record);
143
144 mBytesUsed += proto.size() + kBytesTimestampField;
David Chenc0f6f632018-01-18 16:02:42 -0800145 ensureBytesUsedBelowLimit();
Yao Chend10f7b12017-12-18 12:53:50 -0800146 StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
David Chenf384b902018-03-14 18:36:45 -0700147 StatsdStats::getInstance().setUidMapSnapshots(mSnapshots.size());
Yao Chend10f7b12017-12-18 12:53:50 -0800148 getListenerListCopyLocked(&broadcastList);
David Chende701692017-10-05 13:16:02 -0700149 }
Yao Chend10f7b12017-12-18 12:53:50 -0800150 // To avoid invoking callback while holding the internal lock. we get a copy of the listener
151 // list and invoke the callback. It's still possible that after we copy the list, a
152 // listener removes itself before we call it. It's then the listener's job to handle it (expect
153 // the callback to be called after listener is removed, and the listener should properly
154 // ignore it).
155 for (auto weakPtr : broadcastList) {
156 auto strongPtr = weakPtr.promote();
157 if (strongPtr != NULL) {
David Chen27785a82018-01-19 17:06:45 -0800158 strongPtr->onUidMapReceived(timestamp);
Yao Chend10f7b12017-12-18 12:53:50 -0800159 }
160 }
David Chende701692017-10-05 13:16:02 -0700161}
162
Dianne Hackborn3accca02013-09-20 09:32:11 -0700163void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int64_t& versionCode) {
Yangster-mac330af582018-02-08 15:24:38 -0800164 updateApp(getElapsedRealtimeNs(), app_16, uid, versionCode);
David Chend6896892017-10-25 11:49:03 -0700165}
166
167void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
Dianne Hackborn3accca02013-09-20 09:32:11 -0700168 const int64_t& versionCode) {
Yao Chend10f7b12017-12-18 12:53:50 -0800169 vector<wp<PackageInfoListener>> broadcastList;
Yangster9df9a7f2017-12-18 13:33:05 -0800170 string appName = string(String8(app_16).string());
Yao Chend10f7b12017-12-18 12:53:50 -0800171 {
172 lock_guard<mutex> lock(mMutex);
David Chende701692017-10-05 13:16:02 -0700173
David Chenf384b902018-03-14 18:36:45 -0700174 mChanges.emplace_back(false, timestamp, appName, uid, versionCode);
175 mBytesUsed += kBytesChangeRecord;
David Chenc0f6f632018-01-18 16:02:42 -0800176 ensureBytesUsedBelowLimit();
Yao Chend10f7b12017-12-18 12:53:50 -0800177 StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
David Chenf384b902018-03-14 18:36:45 -0700178 StatsdStats::getInstance().setUidMapChanges(mChanges.size());
Yao Chend10f7b12017-12-18 12:53:50 -0800179
180 auto range = mMap.equal_range(int(uid));
181 bool found = false;
182 for (auto it = range.first; it != range.second; ++it) {
183 // If we find the exact same app name and uid, update the app version directly.
184 if (it->second.packageName == appName) {
185 it->second.versionCode = versionCode;
186 found = true;
187 break;
188 }
189 }
190 if (!found) {
191 // Otherwise, we need to add an app at this uid.
192 mMap.insert(make_pair(uid, AppData(appName, versionCode)));
193 }
194 getListenerListCopyLocked(&broadcastList);
David Chende701692017-10-05 13:16:02 -0700195 }
196
Yao Chend10f7b12017-12-18 12:53:50 -0800197 for (auto weakPtr : broadcastList) {
198 auto strongPtr = weakPtr.promote();
199 if (strongPtr != NULL) {
David Chen27785a82018-01-19 17:06:45 -0800200 strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
David Chende701692017-10-05 13:16:02 -0700201 }
David Chende701692017-10-05 13:16:02 -0700202 }
David Chende701692017-10-05 13:16:02 -0700203}
204
David Chenc136f45a2017-11-27 11:52:26 -0800205void UidMap::ensureBytesUsedBelowLimit() {
206 size_t limit;
207 if (maxBytesOverride <= 0) {
208 limit = StatsdStats::kMaxBytesUsedUidMap;
209 } else {
210 limit = maxBytesOverride;
211 }
212 while (mBytesUsed > limit) {
David Chenf384b902018-03-14 18:36:45 -0700213 ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
214 if (mSnapshots.size() > 0) {
215 mBytesUsed -= mSnapshots.front().bytes.size() + kBytesTimestampField;
216 mSnapshots.pop_front();
David Chenc136f45a2017-11-27 11:52:26 -0800217 StatsdStats::getInstance().noteUidMapDropped(1, 0);
David Chenf384b902018-03-14 18:36:45 -0700218 } else if (mChanges.size() > 0) {
219 mBytesUsed -= kBytesChangeRecord;
220 mChanges.pop_front();
David Chenc136f45a2017-11-27 11:52:26 -0800221 StatsdStats::getInstance().noteUidMapDropped(0, 1);
222 }
David Chenc136f45a2017-11-27 11:52:26 -0800223 }
224}
225
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700226void UidMap::removeApp(const String16& app_16, const int32_t& uid) {
Yangster-mac330af582018-02-08 15:24:38 -0800227 removeApp(getElapsedRealtimeNs(), app_16, uid);
David Chend6896892017-10-25 11:49:03 -0700228}
Yangster9df9a7f2017-12-18 13:33:05 -0800229
Yao Chend10f7b12017-12-18 12:53:50 -0800230void UidMap::getListenerListCopyLocked(vector<wp<PackageInfoListener>>* output) {
231 for (auto weakIt = mSubscribers.begin(); weakIt != mSubscribers.end();) {
232 auto strongPtr = weakIt->promote();
233 if (strongPtr != NULL) {
234 output->push_back(*weakIt);
235 weakIt++;
236 } else {
237 weakIt = mSubscribers.erase(weakIt);
238 VLOG("The UidMap listener is gone, remove it now");
David Chende701692017-10-05 13:16:02 -0700239 }
240 }
David Chende701692017-10-05 13:16:02 -0700241}
242
Yao Chend10f7b12017-12-18 12:53:50 -0800243void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
244 vector<wp<PackageInfoListener>> broadcastList;
245 string app = string(String8(app_16).string());
246 {
247 lock_guard<mutex> lock(mMutex);
248
David Chenf384b902018-03-14 18:36:45 -0700249 mChanges.emplace_back(true, timestamp, app, uid, 0);
250 mBytesUsed += kBytesChangeRecord;
David Chenc0f6f632018-01-18 16:02:42 -0800251 ensureBytesUsedBelowLimit();
Yao Chend10f7b12017-12-18 12:53:50 -0800252 StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
David Chenf384b902018-03-14 18:36:45 -0700253 StatsdStats::getInstance().setUidMapChanges(mChanges.size());
Yao Chend10f7b12017-12-18 12:53:50 -0800254
255 auto range = mMap.equal_range(int(uid));
256 for (auto it = range.first; it != range.second; ++it) {
257 if (it->second.packageName == app) {
258 mMap.erase(it);
259 break;
260 }
261 }
262 getListenerListCopyLocked(&broadcastList);
263 }
264
265 for (auto weakPtr : broadcastList) {
266 auto strongPtr = weakPtr.promote();
267 if (strongPtr != NULL) {
David Chen27785a82018-01-19 17:06:45 -0800268 strongPtr->notifyAppRemoved(timestamp, app, uid);
Yao Chend10f7b12017-12-18 12:53:50 -0800269 }
270 }
271}
272
273void UidMap::addListener(wp<PackageInfoListener> producer) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700274 lock_guard<mutex> lock(mMutex); // Lock for updates
David Chende701692017-10-05 13:16:02 -0700275 mSubscribers.insert(producer);
276}
277
Yao Chend10f7b12017-12-18 12:53:50 -0800278void UidMap::removeListener(wp<PackageInfoListener> producer) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700279 lock_guard<mutex> lock(mMutex); // Lock for updates
David Chende701692017-10-05 13:16:02 -0700280 mSubscribers.erase(producer);
281}
282
David Chen21582962017-11-01 17:32:46 -0700283void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
284 lock_guard<mutex> lock(mIsolatedMutex);
285
286 mIsolatedUidMap[isolatedUid] = parentUid;
287}
288
289void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) {
290 lock_guard<mutex> lock(mIsolatedMutex);
291
292 auto it = mIsolatedUidMap.find(isolatedUid);
293 if (it != mIsolatedUidMap.end()) {
294 mIsolatedUidMap.erase(it);
295 }
296}
297
Yangster-macd40053e2018-01-09 16:29:22 -0800298int UidMap::getHostUidOrSelf(int uid) const {
David Chen21582962017-11-01 17:32:46 -0700299 lock_guard<mutex> lock(mIsolatedMutex);
300
301 auto it = mIsolatedUidMap.find(uid);
302 if (it != mIsolatedUidMap.end()) {
303 return it->second;
304 }
305 return uid;
306}
307
David Chend6896892017-10-25 11:49:03 -0700308void UidMap::clearOutput() {
David Chenf384b902018-03-14 18:36:45 -0700309 mSnapshots.clear();
310 mChanges.clear();
David Chenc136f45a2017-11-27 11:52:26 -0800311 // Also update the guardrail trackers.
312 StatsdStats::getInstance().setUidMapChanges(0);
313 StatsdStats::getInstance().setUidMapSnapshots(1);
David Chencfc311d2018-01-23 17:55:54 -0800314 mBytesUsed = 0;
David Chenc136f45a2017-11-27 11:52:26 -0800315 StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
David Chend6896892017-10-25 11:49:03 -0700316}
David Chende701692017-10-05 13:16:02 -0700317
David Chend6896892017-10-25 11:49:03 -0700318int64_t UidMap::getMinimumTimestampNs() {
319 int64_t m = 0;
320 for (auto it : mLastUpdatePerConfigKey) {
321 if (m == 0) {
322 m = it.second;
323 } else if (it.second < m) {
324 m = it.second;
325 }
326 }
327 return m;
328}
329
Yao Chend10f7b12017-12-18 12:53:50 -0800330size_t UidMap::getBytesUsed() const {
David Chenc136f45a2017-11-27 11:52:26 -0800331 return mBytesUsed;
332}
333
yro4beccbe2018-03-15 19:42:05 -0700334void UidMap::appendUidMap(const ConfigKey& key, ProtoOutputStream* proto) {
335 appendUidMap(getElapsedRealtimeNs(), key, proto);
David Chend6896892017-10-25 11:49:03 -0700336}
337
yro4beccbe2018-03-15 19:42:05 -0700338void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key,
339 ProtoOutputStream* proto) {
David Chend6896892017-10-25 11:49:03 -0700340 lock_guard<mutex> lock(mMutex); // Lock for updates
341
David Chenf384b902018-03-14 18:36:45 -0700342 for (const ChangeRecord& record : mChanges) {
343 if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
344 uint64_t changesToken =
yro4beccbe2018-03-15 19:42:05 -0700345 proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
346 proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
347 proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
348 (long long)record.timestampNs);
349 proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
350 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
351 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_VERSION, (int)record.version);
352 proto->end(changesToken);
David Chenf384b902018-03-14 18:36:45 -0700353 }
354 }
355
356 bool atLeastOneSnapshot = false;
357 unsigned int count = 0;
358 for (const SnapshotRecord& record : mSnapshots) {
359 // Ensure that we include at least the latest snapshot.
360 if ((count == mSnapshots.size() - 1 && !atLeastOneSnapshot) ||
361 record.timestampNs > mLastUpdatePerConfigKey[key]) {
362 uint64_t snapshotsToken =
yro4beccbe2018-03-15 19:42:05 -0700363 proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
David Chenf384b902018-03-14 18:36:45 -0700364 atLeastOneSnapshot = true;
365 count++;
yro4beccbe2018-03-15 19:42:05 -0700366 proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP,
367 (long long)record.timestampNs);
368 proto->write(FIELD_TYPE_MESSAGE | FIELD_ID_SNAPSHOT_PACKAGE_INFO, record.bytes.data());
369 proto->end(snapshotsToken);
David Chenf384b902018-03-14 18:36:45 -0700370 }
371 }
372
David Chend6896892017-10-25 11:49:03 -0700373 int64_t prevMin = getMinimumTimestampNs();
374 mLastUpdatePerConfigKey[key] = timestamp;
375 int64_t newMin = getMinimumTimestampNs();
376
David Chenf384b902018-03-14 18:36:45 -0700377 if (newMin > prevMin) { // Delete anything possible now that the minimum has
378 // moved forward.
David Chend6896892017-10-25 11:49:03 -0700379 int64_t cutoff_nanos = newMin;
David Chenf384b902018-03-14 18:36:45 -0700380 for (auto it_snapshots = mSnapshots.begin(); it_snapshots != mSnapshots.end();
381 ++it_snapshots) {
382 if (it_snapshots->timestampNs < cutoff_nanos) {
383 mBytesUsed -= it_snapshots->bytes.size() + kBytesTimestampField;
384 mSnapshots.erase(it_snapshots);
David Chend6896892017-10-25 11:49:03 -0700385 }
386 }
David Chenf384b902018-03-14 18:36:45 -0700387 for (auto it_changes = mChanges.begin(); it_changes != mChanges.end(); ++it_changes) {
388 if (it_changes->timestampNs < cutoff_nanos) {
389 mBytesUsed -= kBytesChangeRecord;
390 mChanges.erase(it_changes);
David Chend6896892017-10-25 11:49:03 -0700391 }
392 }
David Chencfc311d2018-01-23 17:55:54 -0800393
David Chenf384b902018-03-14 18:36:45 -0700394 if (mSnapshots.size() == 0) {
395 // Produce another snapshot. This results in extra data being uploaded but
396 // helps ensure we can re-construct the UID->app name, versionCode mapping
397 // in server.
yro4beccbe2018-03-15 19:42:05 -0700398 ProtoOutputStream snapshotProto;
399 uint64_t token = snapshotProto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
400 FIELD_ID_SNAPSHOT_PACKAGE_INFO);
David Chenf384b902018-03-14 18:36:45 -0700401 for (const auto& it : mMap) {
yro4beccbe2018-03-15 19:42:05 -0700402 snapshotProto.write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME,
403 it.second.packageName);
404 snapshotProto.write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
405 (int)it.second.versionCode);
406 snapshotProto.write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID,
407 (int)it.first);
David Chencfc311d2018-01-23 17:55:54 -0800408 }
yro4beccbe2018-03-15 19:42:05 -0700409 snapshotProto.end(token);
David Chenf384b902018-03-14 18:36:45 -0700410
411 // Copy ProtoOutputStream output to
yro4beccbe2018-03-15 19:42:05 -0700412 auto iter = snapshotProto.data();
413 vector<char> snapshotData(snapshotProto.size());
David Chenf384b902018-03-14 18:36:45 -0700414 size_t pos = 0;
415 while (iter.readBuffer() != NULL) {
416 size_t toRead = iter.currentToRead();
yro4beccbe2018-03-15 19:42:05 -0700417 std::memcpy(&(snapshotData[pos]), iter.readBuffer(), toRead);
David Chenf384b902018-03-14 18:36:45 -0700418 pos += toRead;
419 iter.rp()->move(toRead);
420 }
yro4beccbe2018-03-15 19:42:05 -0700421 mSnapshots.emplace_back(timestamp, snapshotData);
422 mBytesUsed += kBytesTimestampField + snapshotData.size();
David Chencfc311d2018-01-23 17:55:54 -0800423 }
David Chend6896892017-10-25 11:49:03 -0700424 }
David Chenc136f45a2017-11-27 11:52:26 -0800425 StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
David Chenf384b902018-03-14 18:36:45 -0700426 StatsdStats::getInstance().setUidMapChanges(mChanges.size());
427 StatsdStats::getInstance().setUidMapSnapshots(mSnapshots.size());
David Chende701692017-10-05 13:16:02 -0700428}
429
Yao Chend10f7b12017-12-18 12:53:50 -0800430void UidMap::printUidMap(FILE* out) const {
David Chende701692017-10-05 13:16:02 -0700431 lock_guard<mutex> lock(mMutex);
432
433 for (auto it : mMap) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700434 fprintf(out, "%s, v%" PRId64 " (%i)\n", it.second.packageName.c_str(),
435 it.second.versionCode, it.first);
David Chende701692017-10-05 13:16:02 -0700436 }
437}
438
David Chend6896892017-10-25 11:49:03 -0700439void UidMap::OnConfigUpdated(const ConfigKey& key) {
440 mLastUpdatePerConfigKey[key] = -1;
David Chenc136f45a2017-11-27 11:52:26 -0800441
442 // Ensure there is at least one snapshot available since this configuration also needs to know
443 // what all the uid's represent.
David Chenf384b902018-03-14 18:36:45 -0700444 if (mSnapshots.size() == 0) {
David Chenc136f45a2017-11-27 11:52:26 -0800445 sp<IStatsCompanionService> statsCompanion = nullptr;
446 // Get statscompanion service from service manager
447 const sp<IServiceManager> sm(defaultServiceManager());
448 if (sm != nullptr) {
449 const String16 name("statscompanion");
450 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
451 if (statsCompanion == nullptr) {
452 ALOGW("statscompanion service unavailable!");
453 return;
454 }
455 statsCompanion->triggerUidSnapshot();
456 }
457 }
David Chend6896892017-10-25 11:49:03 -0700458}
459
460void UidMap::OnConfigRemoved(const ConfigKey& key) {
461 mLastUpdatePerConfigKey.erase(key);
462}
463
Yao Chend10f7b12017-12-18 12:53:50 -0800464set<int32_t> UidMap::getAppUid(const string& package) const {
465 lock_guard<mutex> lock(mMutex);
466
467 set<int32_t> results;
468 for (const auto& pair : mMap) {
469 if (pair.second.packageName == package) {
470 results.insert(pair.first);
471 }
472 }
473 return results;
474}
475
Yao Chen147ce602017-12-22 14:35:34 -0800476// Note not all the following AIDs are used as uids. Some are used only for gids.
477// It's ok to leave them in the map, but we won't ever see them in the log's uid field.
478// App's uid starts from 10000, and will not overlap with the following AIDs.
479const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
480 {"AID_SYSTEM", 1000},
481 {"AID_RADIO", 1001},
482 {"AID_BLUETOOTH", 1002},
483 {"AID_GRAPHICS", 1003},
484 {"AID_INPUT", 1004},
485 {"AID_AUDIO", 1005},
486 {"AID_CAMERA", 1006},
487 {"AID_LOG", 1007},
488 {"AID_COMPASS", 1008},
489 {"AID_MOUNT", 1009},
490 {"AID_WIFI", 1010},
491 {"AID_ADB", 1011},
492 {"AID_INSTALL", 1012},
493 {"AID_MEDIA", 1013},
494 {"AID_DHCP", 1014},
495 {"AID_SDCARD_RW", 1015},
496 {"AID_VPN", 1016},
497 {"AID_KEYSTORE", 1017},
498 {"AID_USB", 1018},
499 {"AID_DRM", 1019},
500 {"AID_MDNSR", 1020},
501 {"AID_GPS", 1021},
502 // {"AID_UNUSED1", 1022},
503 {"AID_MEDIA_RW", 1023},
504 {"AID_MTP", 1024},
505 // {"AID_UNUSED2", 1025},
506 {"AID_DRMRPC", 1026},
507 {"AID_NFC", 1027},
508 {"AID_SDCARD_R", 1028},
509 {"AID_CLAT", 1029},
510 {"AID_LOOP_RADIO", 1030},
511 {"AID_MEDIA_DRM", 1031},
512 {"AID_PACKAGE_INFO", 1032},
513 {"AID_SDCARD_PICS", 1033},
514 {"AID_SDCARD_AV", 1034},
515 {"AID_SDCARD_ALL", 1035},
516 {"AID_LOGD", 1036},
517 {"AID_SHARED_RELRO", 1037},
518 {"AID_DBUS", 1038},
519 {"AID_TLSDATE", 1039},
520 {"AID_MEDIA_EX", 1040},
521 {"AID_AUDIOSERVER", 1041},
522 {"AID_METRICS_COLL", 1042},
523 {"AID_METRICSD", 1043},
524 {"AID_WEBSERV", 1044},
525 {"AID_DEBUGGERD", 1045},
526 {"AID_MEDIA_CODEC", 1046},
527 {"AID_CAMERASERVER", 1047},
528 {"AID_FIREWALL", 1048},
529 {"AID_TRUNKS", 1049},
530 {"AID_NVRAM", 1050},
531 {"AID_DNS", 1051},
532 {"AID_DNS_TETHER", 1052},
533 {"AID_WEBVIEW_ZYGOTE", 1053},
534 {"AID_VEHICLE_NETWORK", 1054},
535 {"AID_MEDIA_AUDIO", 1055},
536 {"AID_MEDIA_VIDEO", 1056},
537 {"AID_MEDIA_IMAGE", 1057},
538 {"AID_TOMBSTONED", 1058},
539 {"AID_MEDIA_OBB", 1059},
540 {"AID_ESE", 1060},
541 {"AID_OTA_UPDATE", 1061},
542 {"AID_AUTOMOTIVE_EVS", 1062},
543 {"AID_LOWPAN", 1063},
544 {"AID_HSM", 1064},
Yao Chen29f79b52018-01-17 10:56:48 -0800545 {"AID_RESERVED_DISK", 1065},
546 {"AID_STATSD", 1066},
547 {"AID_INCIDENTD", 1067},
Yao Chen147ce602017-12-22 14:35:34 -0800548 {"AID_SHELL", 2000},
549 {"AID_CACHE", 2001},
550 {"AID_DIAG", 2002}};
551
David Chende701692017-10-05 13:16:02 -0700552} // namespace statsd
553} // namespace os
Yao Chen29f79b52018-01-17 10:56:48 -0800554} // namespace android