blob: 6d9c644bb40eb6c319a24378483f53de83dd0c07 [file] [log] [blame]
Joe Onorato9fc9edf2017-10-15 20:08:52 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 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
Yao Chen52b478b2018-03-27 10:59:45 -070017#define DEBUG false // STOPSHIP if true
18#include "Log.h"
19
Joe Onorato9fc9edf2017-10-15 20:08:52 -070020#include "config/ConfigManager.h"
yro947fbce2017-11-15 22:50:23 -080021#include "storage/StorageManager.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070022
Yao Chen52b478b2018-03-27 10:59:45 -070023#include "guardrail/StatsdStats.h"
Yangster-macc04feba2018-04-02 14:37:33 -070024#include "stats_log_util.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070025#include "stats_util.h"
Yangster-macb142cc82018-03-30 15:22:08 -070026#include "stats_log_util.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070027
Joe Onorato9fc9edf2017-10-15 20:08:52 -070028#include <stdio.h>
yro87d983c2017-11-14 21:31:43 -080029#include <vector>
30#include "android-base/stringprintf.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070031
32namespace android {
33namespace os {
34namespace statsd {
35
Yao Chenf09569f2017-12-13 17:00:51 -080036using std::pair;
Yao Chenf09569f2017-12-13 17:00:51 -080037using std::string;
38using std::vector;
39
yro03faf092017-12-12 00:17:50 -080040#define STATS_SERVICE_DIR "/data/misc/stats-service"
yro87d983c2017-11-14 21:31:43 -080041
yro87d983c2017-11-14 21:31:43 -080042using android::base::StringPrintf;
43using std::unique_ptr;
44
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080045struct ConfigReceiverDeathCookie {
46 ConfigReceiverDeathCookie(sp<ConfigManager> configManager, const ConfigKey& configKey,
47 const shared_ptr<IPendingIntentRef>& pir):
48 mConfigManager(configManager),
49 mConfigKey(configKey),
50 mPir(pir) {}
Jeffrey Huangad213742019-12-16 13:50:06 -080051
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080052 sp<ConfigManager> mConfigManager;
53 ConfigKey mConfigKey;
54 shared_ptr<IPendingIntentRef> mPir;
Jeffrey Huangad213742019-12-16 13:50:06 -080055};
56
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080057void ConfigManager::configReceiverDied(void* cookie) {
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080058 auto cookie_ = static_cast<ConfigReceiverDeathCookie*>(cookie);
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080059 sp<ConfigManager>& thiz = cookie_->mConfigManager;
60 ConfigKey& configKey = cookie_->mConfigKey;
61 shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
Jeffrey Huang47537a12020-01-06 15:35:34 -080062
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080063 // Erase the mapping from the config key to the config receiver (pir) if the
64 // mapping still exists.
65 lock_guard<mutex> lock(thiz->mMutex);
66 auto it = thiz->mConfigReceivers.find(configKey);
67 if (it != thiz->mConfigReceivers.end() && it->second == pir) {
68 thiz->mConfigReceivers.erase(configKey);
Jeffrey Huang47537a12020-01-06 15:35:34 -080069 }
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080070
71 // The death recipient corresponding to this specific pir can never be
72 // triggered again, so free up resources.
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080073 delete cookie_;
74}
75
76struct ActiveConfigChangedReceiverDeathCookie {
77 ActiveConfigChangedReceiverDeathCookie(sp<ConfigManager> configManager, const int uid,
78 const shared_ptr<IPendingIntentRef>& pir):
79 mConfigManager(configManager),
80 mUid(uid),
81 mPir(pir) {}
82
83 sp<ConfigManager> mConfigManager;
84 int mUid;
85 shared_ptr<IPendingIntentRef> mPir;
Jeffrey Huang47537a12020-01-06 15:35:34 -080086};
87
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080088void ConfigManager::activeConfigChangedReceiverDied(void* cookie) {
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080089 auto cookie_ = static_cast<ActiveConfigChangedReceiverDeathCookie*>(cookie);
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080090 sp<ConfigManager>& thiz = cookie_->mConfigManager;
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080091 int uid = cookie_->mUid;
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080092 shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
Ruchir Rastogie449b0c2020-02-10 17:40:09 -080093
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -080094 // Erase the mapping from the config key to the active config changed
95 // receiver (pir) if the mapping still exists.
96 lock_guard<mutex> lock(thiz->mMutex);
97 auto it = thiz->mActiveConfigsChangedReceivers.find(uid);
98 if (it != thiz->mActiveConfigsChangedReceivers.end() && it->second == pir) {
99 thiz->mActiveConfigsChangedReceivers.erase(uid);
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800100 }
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -0800101
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800102 // The death recipient corresponding to this specific pir can never
103 // be triggered again, so free up resources.
104 delete cookie_;
105}
106
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -0800107ConfigManager::ConfigManager() :
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800108 mConfigReceiverDeathRecipient(AIBinder_DeathRecipient_new(configReceiverDied)),
109 mActiveConfigChangedReceiverDeathRecipient(
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -0800110 AIBinder_DeathRecipient_new(activeConfigChangedReceiverDied)) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700111}
112
113ConfigManager::~ConfigManager() {
114}
115
116void ConfigManager::Startup() {
Yao Chenf09569f2017-12-13 17:00:51 -0800117 map<ConfigKey, StatsdConfig> configsFromDisk;
118 StorageManager::readConfigFromDisk(configsFromDisk);
yro469cd802018-01-04 14:57:45 -0800119 for (const auto& pair : configsFromDisk) {
120 UpdateConfig(pair.first, pair.second);
121 }
122}
Yao Chen3c0b95c2017-12-16 14:34:20 -0800123
yro469cd802018-01-04 14:57:45 -0800124void ConfigManager::StartupForTest() {
125 // Dummy function to avoid reading configs from disks for tests.
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700126}
127
128void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
David Chenfdc123b2018-02-09 17:21:48 -0800129 lock_guard<mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700130 mListeners.push_back(listener);
131}
132
133void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
David Chenfdc123b2018-02-09 17:21:48 -0800134 vector<sp<ConfigListener>> broadcastList;
135 {
136 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700137
yro44907652018-03-12 20:44:05 -0700138 const int numBytes = config.ByteSize();
139 vector<uint8_t> buffer(numBytes);
140 config.SerializeToArray(&buffer[0], numBytes);
141
Yao Chen52b478b2018-03-27 10:59:45 -0700142 auto uidIt = mConfigs.find(key.GetUid());
143 // GuardRail: Limit the number of configs per uid.
144 if (uidIt != mConfigs.end()) {
145 auto it = uidIt->second.find(key);
146 if (it == uidIt->second.end() &&
147 uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
148 ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
149 return;
150 }
151 }
yro44907652018-03-12 20:44:05 -0700152
Yao Chen52b478b2018-03-27 10:59:45 -0700153 // Check if it's a duplicate config.
154 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
155 StorageManager::hasIdenticalConfig(key, buffer)) {
156 // This is a duplicate config.
157 ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
158 // Update saved file on disk. We still update timestamp of file when
159 // there exists a duplicate configuration to avoid garbage collection.
160 update_saved_configs_locked(key, buffer, numBytes);
161 return;
162 }
163
164 // Update saved file on disk.
yro44907652018-03-12 20:44:05 -0700165 update_saved_configs_locked(key, buffer, numBytes);
166
Yao Chen52b478b2018-03-27 10:59:45 -0700167 // Add to set.
168 mConfigs[key.GetUid()].insert(key);
David Chenfdc123b2018-02-09 17:21:48 -0800169
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800170 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800171 broadcastList.push_back(listener);
172 }
173 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700174
Yangster-macc04feba2018-04-02 14:37:33 -0700175 const int64_t timestampNs = getElapsedRealtimeNs();
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700176 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800177 for (const sp<ConfigListener>& listener : broadcastList) {
Yangster-macc04feba2018-04-02 14:37:33 -0700178 listener->OnConfigUpdated(timestampNs, key, config);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700179 }
180}
181
Jeffrey Huangad213742019-12-16 13:50:06 -0800182void ConfigManager::SetConfigReceiver(const ConfigKey& key,
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800183 const shared_ptr<IPendingIntentRef>& pir) {
David Chenfdc123b2018-02-09 17:21:48 -0800184 lock_guard<mutex> lock(mMutex);
Jeffrey Huangad213742019-12-16 13:50:06 -0800185 mConfigReceivers[key] = pir;
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800186 AIBinder_linkToDeath(pir->asBinder().get(), mConfigReceiverDeathRecipient.get(),
187 new ConfigReceiverDeathCookie(this, key, pir));
David Chenadaf8b32017-11-03 15:42:08 -0700188}
189
190void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800191 lock_guard<mutex> lock(mMutex);
David Chenadaf8b32017-11-03 15:42:08 -0700192 mConfigReceivers.erase(key);
193}
194
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800195void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800196 const shared_ptr<IPendingIntentRef>& pir) {
Ruchir Rastogi1497e8f2020-03-03 16:04:42 -0800197 {
198 lock_guard<mutex> lock(mMutex);
199 mActiveConfigsChangedReceivers[uid] = pir;
200 }
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800201 AIBinder_linkToDeath(pir->asBinder().get(), mActiveConfigChangedReceiverDeathRecipient.get(),
202 new ActiveConfigChangedReceiverDeathCookie(this, uid, pir));
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800203}
204
205void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
206 lock_guard<mutex> lock(mMutex);
207 mActiveConfigsChangedReceivers.erase(uid);
208}
209
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700210void ConfigManager::RemoveConfig(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800211 vector<sp<ConfigListener>> broadcastList;
212 {
213 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700214
Tej Singh6ede28b2019-01-29 17:06:54 -0800215 auto uid = key.GetUid();
216 auto uidIt = mConfigs.find(uid);
Yao Chen52b478b2018-03-27 10:59:45 -0700217 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
David Chenfdc123b2018-02-09 17:21:48 -0800218 // Remove from map
Yao Chen52b478b2018-03-27 10:59:45 -0700219 uidIt->second.erase(key);
Tej Singh6ede28b2019-01-29 17:06:54 -0800220
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800221 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800222 broadcastList.push_back(listener);
223 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700224 }
David Chenfdc123b2018-02-09 17:21:48 -0800225
David Chenfdc123b2018-02-09 17:21:48 -0800226 // Remove from disk. There can still be a lingering file on disk so we check
227 // whether or not the config was on memory.
228 remove_saved_configs(key);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700229 }
yro9c98c052017-11-19 14:33:56 -0800230
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800231 for (const sp<ConfigListener>& listener:broadcastList) {
David Chenfdc123b2018-02-09 17:21:48 -0800232 listener->OnConfigRemoved(key);
233 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700234}
235
yro87d983c2017-11-14 21:31:43 -0800236void ConfigManager::remove_saved_configs(const ConfigKey& key) {
yrof4ae56b2018-02-13 22:06:34 -0800237 string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
yroe5f82922018-01-22 18:37:27 -0800238 StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
yro87d983c2017-11-14 21:31:43 -0800239}
240
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700241void ConfigManager::RemoveConfigs(int uid) {
242 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800243 vector<sp<ConfigListener>> broadcastList;
244 {
245 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700246
Yao Chen52b478b2018-03-27 10:59:45 -0700247 auto uidIt = mConfigs.find(uid);
248 if (uidIt == mConfigs.end()) {
249 return;
250 }
251
252 for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
David Chenfdc123b2018-02-09 17:21:48 -0800253 // Remove from map
David Chenfdc123b2018-02-09 17:21:48 -0800254 remove_saved_configs(*it);
255 removed.push_back(*it);
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800256 }
257
Yao Chen52b478b2018-03-27 10:59:45 -0700258 mConfigs.erase(uidIt);
259
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800260 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800261 broadcastList.push_back(listener);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700262 }
263 }
264
265 // Remove separately so if they do anything in the callback they can't mess up our iteration.
266 for (auto& key : removed) {
267 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800268 for (const sp<ConfigListener>& listener:broadcastList) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700269 listener->OnConfigRemoved(key);
270 }
271 }
272}
273
yro74fed972017-11-27 14:42:42 -0800274void ConfigManager::RemoveAllConfigs() {
275 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800276 vector<sp<ConfigListener>> broadcastList;
277 {
278 lock_guard <mutex> lock(mMutex);
yro74fed972017-11-27 14:42:42 -0800279
Yao Chen52b478b2018-03-27 10:59:45 -0700280 for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
281 for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
282 // Remove from map
283 removed.push_back(*it);
284 it = uidIt->second.erase(it);
David Chenfdc123b2018-02-09 17:21:48 -0800285 }
Yao Chen52b478b2018-03-27 10:59:45 -0700286 uidIt = mConfigs.erase(uidIt);
yro74fed972017-11-27 14:42:42 -0800287 }
David Chenfdc123b2018-02-09 17:21:48 -0800288
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800289 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800290 broadcastList.push_back(listener);
291 }
yro74fed972017-11-27 14:42:42 -0800292 }
293
294 // Remove separately so if they do anything in the callback they can't mess up our iteration.
295 for (auto& key : removed) {
296 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800297 for (const sp<ConfigListener>& listener:broadcastList) {
yro74fed972017-11-27 14:42:42 -0800298 listener->OnConfigRemoved(key);
299 }
300 }
301}
302
Yangster7c334a12017-11-22 14:24:24 -0800303vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
David Chenfdc123b2018-02-09 17:21:48 -0800304 lock_guard<mutex> lock(mMutex);
305
David Chen1d7b0cd2017-11-15 14:20:04 -0800306 vector<ConfigKey> ret;
Yao Chen52b478b2018-03-27 10:59:45 -0700307 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
308 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
309 ret.push_back(*it);
310 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800311 }
312 return ret;
313}
314
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800315const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
David Chenfdc123b2018-02-09 17:21:48 -0800316 lock_guard<mutex> lock(mMutex);
317
David Chen1d7b0cd2017-11-15 14:20:04 -0800318 auto it = mConfigReceivers.find(key);
319 if (it == mConfigReceivers.end()) {
David Chen661f7912018-01-22 17:46:24 -0800320 return nullptr;
David Chen1d7b0cd2017-11-15 14:20:04 -0800321 } else {
322 return it->second;
323 }
324}
325
Ruchir Rastogie449b0c2020-02-10 17:40:09 -0800326const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
327 const {
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800328 lock_guard<mutex> lock(mMutex);
329
330 auto it = mActiveConfigsChangedReceivers.find(uid);
331 if (it == mActiveConfigsChangedReceivers.end()) {
332 return nullptr;
333 } else {
334 return it->second;
335 }
336}
337
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700338void ConfigManager::Dump(FILE* out) {
David Chenfdc123b2018-02-09 17:21:48 -0800339 lock_guard<mutex> lock(mMutex);
340
Yao Chen52b478b2018-03-27 10:59:45 -0700341 fprintf(out, "CONFIGURATIONS\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700342 fprintf(out, " uid name\n");
Yao Chen52b478b2018-03-27 10:59:45 -0700343 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
344 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
345 fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
346 auto receiverIt = mConfigReceivers.find(*it);
347 if (receiverIt != mConfigReceivers.end()) {
348 fprintf(out, " -> received by PendingIntent as binder\n");
349 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800350 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700351 }
352}
353
yro44907652018-03-12 20:44:05 -0700354void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
355 const vector<uint8_t>& buffer,
356 const int numBytes) {
yro9c98c052017-11-19 14:33:56 -0800357 // If there is a pre-existing config with same key we should first delete it.
358 remove_saved_configs(key);
359
360 // Then we save the latest config.
yro44907652018-03-12 20:44:05 -0700361 string file_name =
362 StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
363 key.GetUid(), (long long)key.GetId());
yro947fbce2017-11-15 22:50:23 -0800364 StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700365}
366
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700367} // namespace statsd
368} // namespace os
369} // namespace android