blob: fc949b4941947aed13ce7d25b084639318a11e8f [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
yro87d983c2017-11-14 21:31:43 -080028#include <android-base/file.h>
29#include <dirent.h>
Joe Onorato9fc9edf2017-10-15 20:08:52 -070030#include <stdio.h>
yro87d983c2017-11-14 21:31:43 -080031#include <vector>
32#include "android-base/stringprintf.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070033
34namespace android {
35namespace os {
36namespace statsd {
37
Yao Chenf09569f2017-12-13 17:00:51 -080038using std::map;
39using std::pair;
40using std::set;
41using std::string;
42using std::vector;
43
yro03faf092017-12-12 00:17:50 -080044#define STATS_SERVICE_DIR "/data/misc/stats-service"
yro87d983c2017-11-14 21:31:43 -080045
yro87d983c2017-11-14 21:31:43 -080046using android::base::StringPrintf;
47using std::unique_ptr;
48
Joe Onorato9fc9edf2017-10-15 20:08:52 -070049ConfigManager::ConfigManager() {
50}
51
52ConfigManager::~ConfigManager() {
53}
54
55void ConfigManager::Startup() {
Yao Chenf09569f2017-12-13 17:00:51 -080056 map<ConfigKey, StatsdConfig> configsFromDisk;
57 StorageManager::readConfigFromDisk(configsFromDisk);
yro469cd802018-01-04 14:57:45 -080058 for (const auto& pair : configsFromDisk) {
59 UpdateConfig(pair.first, pair.second);
60 }
61}
Yao Chen3c0b95c2017-12-16 14:34:20 -080062
yro469cd802018-01-04 14:57:45 -080063void ConfigManager::StartupForTest() {
64 // Dummy function to avoid reading configs from disks for tests.
Joe Onorato9fc9edf2017-10-15 20:08:52 -070065}
66
67void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
David Chenfdc123b2018-02-09 17:21:48 -080068 lock_guard<mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -070069 mListeners.push_back(listener);
70}
71
72void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
David Chenfdc123b2018-02-09 17:21:48 -080073 vector<sp<ConfigListener>> broadcastList;
74 {
75 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -070076
yro44907652018-03-12 20:44:05 -070077 const int numBytes = config.ByteSize();
78 vector<uint8_t> buffer(numBytes);
79 config.SerializeToArray(&buffer[0], numBytes);
80
Yao Chen52b478b2018-03-27 10:59:45 -070081 auto uidIt = mConfigs.find(key.GetUid());
82 // GuardRail: Limit the number of configs per uid.
83 if (uidIt != mConfigs.end()) {
84 auto it = uidIt->second.find(key);
85 if (it == uidIt->second.end() &&
86 uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
87 ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
88 return;
89 }
90 }
yro44907652018-03-12 20:44:05 -070091
Yao Chen52b478b2018-03-27 10:59:45 -070092 // Check if it's a duplicate config.
93 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
94 StorageManager::hasIdenticalConfig(key, buffer)) {
95 // This is a duplicate config.
96 ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
97 // Update saved file on disk. We still update timestamp of file when
98 // there exists a duplicate configuration to avoid garbage collection.
99 update_saved_configs_locked(key, buffer, numBytes);
100 return;
101 }
102
103 // Update saved file on disk.
yro44907652018-03-12 20:44:05 -0700104 update_saved_configs_locked(key, buffer, numBytes);
105
Yao Chen52b478b2018-03-27 10:59:45 -0700106 // Add to set.
107 mConfigs[key.GetUid()].insert(key);
David Chenfdc123b2018-02-09 17:21:48 -0800108
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800109 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800110 broadcastList.push_back(listener);
111 }
112 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700113
Yangster-macc04feba2018-04-02 14:37:33 -0700114 const int64_t timestampNs = getElapsedRealtimeNs();
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700115 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800116 for (const sp<ConfigListener>& listener : broadcastList) {
Yangster-macc04feba2018-04-02 14:37:33 -0700117 listener->OnConfigUpdated(timestampNs, key, config);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700118 }
119}
120
David Chen661f7912018-01-22 17:46:24 -0800121void ConfigManager::SetConfigReceiver(const ConfigKey& key, const sp<IBinder>& intentSender) {
David Chenfdc123b2018-02-09 17:21:48 -0800122 lock_guard<mutex> lock(mMutex);
David Chen661f7912018-01-22 17:46:24 -0800123 mConfigReceivers[key] = intentSender;
David Chenadaf8b32017-11-03 15:42:08 -0700124}
125
126void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800127 lock_guard<mutex> lock(mMutex);
David Chenadaf8b32017-11-03 15:42:08 -0700128 mConfigReceivers.erase(key);
129}
130
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800131void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
132 const sp<IBinder>& intentSender) {
133 lock_guard<mutex> lock(mMutex);
134 mActiveConfigsChangedReceivers[uid] = intentSender;
135}
136
137void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
138 lock_guard<mutex> lock(mMutex);
139 mActiveConfigsChangedReceivers.erase(uid);
140}
141
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700142void ConfigManager::RemoveConfig(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800143 vector<sp<ConfigListener>> broadcastList;
144 {
145 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700146
Tej Singh6ede28b2019-01-29 17:06:54 -0800147 auto uid = key.GetUid();
148 auto uidIt = mConfigs.find(uid);
Yao Chen52b478b2018-03-27 10:59:45 -0700149 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
David Chenfdc123b2018-02-09 17:21:48 -0800150 // Remove from map
Yao Chen52b478b2018-03-27 10:59:45 -0700151 uidIt->second.erase(key);
Tej Singh6ede28b2019-01-29 17:06:54 -0800152
153 // No more configs for this uid, lets remove the active configs callback.
154 if (uidIt->second.empty()) {
155 auto itActiveConfigsChangedReceiver = mActiveConfigsChangedReceivers.find(uid);
156 if (itActiveConfigsChangedReceiver != mActiveConfigsChangedReceivers.end()) {
157 mActiveConfigsChangedReceivers.erase(itActiveConfigsChangedReceiver);
158 }
159 }
160
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800161 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800162 broadcastList.push_back(listener);
163 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700164 }
David Chenfdc123b2018-02-09 17:21:48 -0800165
166 auto itReceiver = mConfigReceivers.find(key);
167 if (itReceiver != mConfigReceivers.end()) {
168 // Remove from map
169 mConfigReceivers.erase(itReceiver);
170 }
171
172 // Remove from disk. There can still be a lingering file on disk so we check
173 // whether or not the config was on memory.
174 remove_saved_configs(key);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700175 }
yro9c98c052017-11-19 14:33:56 -0800176
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800177 for (const sp<ConfigListener>& listener:broadcastList) {
David Chenfdc123b2018-02-09 17:21:48 -0800178 listener->OnConfigRemoved(key);
179 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700180}
181
yro87d983c2017-11-14 21:31:43 -0800182void ConfigManager::remove_saved_configs(const ConfigKey& key) {
yrof4ae56b2018-02-13 22:06:34 -0800183 string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
yroe5f82922018-01-22 18:37:27 -0800184 StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
yro87d983c2017-11-14 21:31:43 -0800185}
186
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700187void ConfigManager::RemoveConfigs(int uid) {
188 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800189 vector<sp<ConfigListener>> broadcastList;
190 {
191 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700192
Yao Chen52b478b2018-03-27 10:59:45 -0700193 auto uidIt = mConfigs.find(uid);
194 if (uidIt == mConfigs.end()) {
195 return;
196 }
197
198 for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
David Chenfdc123b2018-02-09 17:21:48 -0800199 // Remove from map
David Chenfdc123b2018-02-09 17:21:48 -0800200 remove_saved_configs(*it);
201 removed.push_back(*it);
202 mConfigReceivers.erase(*it);
David Chenfdc123b2018-02-09 17:21:48 -0800203 }
204
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800205 auto itActiveConfigsChangedReceiver = mActiveConfigsChangedReceivers.find(uid);
206 if (itActiveConfigsChangedReceiver != mActiveConfigsChangedReceivers.end()) {
207 mActiveConfigsChangedReceivers.erase(itActiveConfigsChangedReceiver);
208 }
209
Yao Chen52b478b2018-03-27 10:59:45 -0700210 mConfigs.erase(uidIt);
211
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800212 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800213 broadcastList.push_back(listener);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700214 }
215 }
216
217 // Remove separately so if they do anything in the callback they can't mess up our iteration.
218 for (auto& key : removed) {
219 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800220 for (const sp<ConfigListener>& listener:broadcastList) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700221 listener->OnConfigRemoved(key);
222 }
223 }
224}
225
yro74fed972017-11-27 14:42:42 -0800226void ConfigManager::RemoveAllConfigs() {
227 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800228 vector<sp<ConfigListener>> broadcastList;
229 {
230 lock_guard <mutex> lock(mMutex);
yro74fed972017-11-27 14:42:42 -0800231
Yao Chen52b478b2018-03-27 10:59:45 -0700232 for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
233 for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
234 // Remove from map
235 removed.push_back(*it);
236 it = uidIt->second.erase(it);
David Chenfdc123b2018-02-09 17:21:48 -0800237 }
Yao Chen52b478b2018-03-27 10:59:45 -0700238 uidIt = mConfigs.erase(uidIt);
yro74fed972017-11-27 14:42:42 -0800239 }
David Chenfdc123b2018-02-09 17:21:48 -0800240
Yao Chen52b478b2018-03-27 10:59:45 -0700241 mConfigReceivers.clear();
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800242 mActiveConfigsChangedReceivers.clear();
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800243 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800244 broadcastList.push_back(listener);
245 }
yro74fed972017-11-27 14:42:42 -0800246 }
247
248 // Remove separately so if they do anything in the callback they can't mess up our iteration.
249 for (auto& key : removed) {
250 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800251 for (const sp<ConfigListener>& listener:broadcastList) {
yro74fed972017-11-27 14:42:42 -0800252 listener->OnConfigRemoved(key);
253 }
254 }
255}
256
Yangster7c334a12017-11-22 14:24:24 -0800257vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
David Chenfdc123b2018-02-09 17:21:48 -0800258 lock_guard<mutex> lock(mMutex);
259
David Chen1d7b0cd2017-11-15 14:20:04 -0800260 vector<ConfigKey> ret;
Yao Chen52b478b2018-03-27 10:59:45 -0700261 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
262 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
263 ret.push_back(*it);
264 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800265 }
266 return ret;
267}
268
David Chen661f7912018-01-22 17:46:24 -0800269const sp<android::IBinder> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
David Chenfdc123b2018-02-09 17:21:48 -0800270 lock_guard<mutex> lock(mMutex);
271
David Chen1d7b0cd2017-11-15 14:20:04 -0800272 auto it = mConfigReceivers.find(key);
273 if (it == mConfigReceivers.end()) {
David Chen661f7912018-01-22 17:46:24 -0800274 return nullptr;
David Chen1d7b0cd2017-11-15 14:20:04 -0800275 } else {
276 return it->second;
277 }
278}
279
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800280const sp<android::IBinder> ConfigManager::GetActiveConfigsChangedReceiver(const int uid) const {
281 lock_guard<mutex> lock(mMutex);
282
283 auto it = mActiveConfigsChangedReceivers.find(uid);
284 if (it == mActiveConfigsChangedReceivers.end()) {
285 return nullptr;
286 } else {
287 return it->second;
288 }
289}
290
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700291void ConfigManager::Dump(FILE* out) {
David Chenfdc123b2018-02-09 17:21:48 -0800292 lock_guard<mutex> lock(mMutex);
293
Yao Chen52b478b2018-03-27 10:59:45 -0700294 fprintf(out, "CONFIGURATIONS\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700295 fprintf(out, " uid name\n");
Yao Chen52b478b2018-03-27 10:59:45 -0700296 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
297 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
298 fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
299 auto receiverIt = mConfigReceivers.find(*it);
300 if (receiverIt != mConfigReceivers.end()) {
301 fprintf(out, " -> received by PendingIntent as binder\n");
302 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800303 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700304 }
305}
306
yro44907652018-03-12 20:44:05 -0700307void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
308 const vector<uint8_t>& buffer,
309 const int numBytes) {
yro9c98c052017-11-19 14:33:56 -0800310 // If there is a pre-existing config with same key we should first delete it.
311 remove_saved_configs(key);
312
313 // Then we save the latest config.
yro44907652018-03-12 20:44:05 -0700314 string file_name =
315 StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
316 key.GetUid(), (long long)key.GetId());
yro947fbce2017-11-15 22:50:23 -0800317 StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700318}
319
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700320} // namespace statsd
321} // namespace os
322} // namespace android