blob: 76a7f3f28dee1f289eb7fcebc1bf06d5ccd10cbd [file] [log] [blame]
David Chende701692017-10-05 13:16:02 -07001/*
2 * Copyright (C) 2016 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
17#include "UidMap.h"
18#include <cutils/log.h>
19#include <utils/Errors.h>
20
21using namespace android;
22
23namespace android {
24namespace os {
25namespace statsd {
26
27bool UidMap::hasApp(int uid, const string& packageName) const {
28 lock_guard<mutex> lock(mMutex);
29
30 auto range = mMap.equal_range(uid);
31 for (auto it = range.first; it != range.second; ++it) {
32 if (it->second.packageName == packageName) {
33 return true;
34 }
35 }
36 return false;
37}
38
39int UidMap::getAppVersion(int uid, const string& packageName) const {
40 lock_guard<mutex> lock(mMutex);
41
42 auto range = mMap.equal_range(uid);
43 for (auto it = range.first; it != range.second; ++it) {
44 if (it->second.packageName == packageName) {
45 return it->second.versionCode;
46 }
47 }
48 return 0;
49}
50
51void UidMap::updateMap(const vector <int32_t> &uid, const vector <int32_t> &versionCode,
52 const vector <String16> &packageName) {
53 lock_guard<mutex> lock(mMutex); // Exclusively lock for updates.
54
55 mMap.clear();
56 for (unsigned long j=0; j<uid.size(); j++) {
57 mMap.insert(make_pair(uid[j], AppData(string(String8(packageName[j]).string()),
58 versionCode[j])));
59 }
60
61 if (mOutput.initial_size() == 0) { // Provide the initial states in the mOutput proto
62 for (unsigned long j=0; j<uid.size(); j++) {
63 auto t = mOutput.add_initial();
64 t->set_app(string(String8(packageName[j]).string()));
65 t->set_version(int(versionCode[j]));
66 t->set_uid(uid[j]);
67 }
68 }
69}
70
71void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t& versionCode){
72 lock_guard<mutex> lock(mMutex);
73
74 string app = string(String8(app_16).string());
75
76 // Notify any interested producers that this app has updated
77 for (auto it : mSubscribers) {
78 it->notifyAppUpgrade(app, uid, versionCode);
79 }
80
81 auto log = mOutput.add_changes();
82 log->set_deletion(false);
83 //log.timestamp = TODO: choose how timestamps are computed
84 log->set_app(app);
85 log->set_uid(uid);
86 log->set_version(versionCode);
87
88 auto range = mMap.equal_range(int(uid));
89 for (auto it = range.first; it != range.second; ++it) {
90 if (it->second.packageName == app) {
91 it->second.versionCode = int(versionCode);
92 return;
93 }
94 ALOGD("updateApp failed to find the app %s with uid %i to update", app.c_str(), uid);
95 return;
96 }
97
98 // Otherwise, we need to add an app at this uid.
99 mMap.insert(make_pair(uid, AppData(app, int(versionCode))));
100}
101
102
103void UidMap::removeApp(const String16& app_16, const int32_t& uid){
104 lock_guard<mutex> lock(mMutex);
105
106 string app = string(String8(app_16).string());
107
108 auto log = mOutput.add_changes();
109 log->set_deletion(true);
110 //log.timestamp = TODO: choose how timestamps are computed
111 log->set_app(app);
112 log->set_uid(uid);
113
114 auto range = mMap.equal_range(int(uid));
115 for (auto it = range.first; it != range.second; ++it) {
116 if (it->second.packageName == app) {
117 mMap.erase(it);
118 return;
119 }
120 }
121 ALOGD("removeApp failed to find the app %s with uid %i to remove", app.c_str(), uid);
122 return;
123}
124
125void UidMap::addListener(sp<PackageInfoListener> producer) {
126 lock_guard<mutex> lock(mMutex); // Lock for updates
127 mSubscribers.insert(producer);
128}
129
130void UidMap::removeListener(sp<PackageInfoListener> producer) {
131 lock_guard<mutex> lock(mMutex); // Lock for updates
132 mSubscribers.erase(producer);
133}
134
135UidMapping UidMap::getAndClearOutput() {
136 lock_guard<mutex> lock(mMutex); // Lock for updates
137
138 auto ret = UidMapping(mOutput); // Copy that will be returned.
139 mOutput.Clear();
140
141 // Re-initialize the initial state for the outputs. This results in extra data being uploaded
142 // but helps ensure we can't re-construct the UID->app name, versionCode mapping in server.
143 for (auto it : mMap) {
144 auto t = mOutput.add_initial();
145 t->set_app(it.second.packageName);
146 t->set_version(it.second.versionCode);
147 t->set_uid(it.first);
148 }
149
150 return ret;
151}
152
153void UidMap::printUidMap(FILE* out) {
154 lock_guard<mutex> lock(mMutex);
155
156 for (auto it : mMap) {
157 fprintf(out, "%s, v%d (%i)\n", it.second.packageName.c_str(), it.second.versionCode, it.first);
158 }
159}
160
161
162} // namespace statsd
163} // namespace os
164} // namespace android