blob: 3439e89ebc1889adc8c4fd5d087cbc9bdbc6b101 [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
Joe Onorato9fc9edf2017-10-15 20:08:52 -070045ConfigManager::ConfigManager() {
46}
47
48ConfigManager::~ConfigManager() {
49}
50
51void ConfigManager::Startup() {
Yao Chenf09569f2017-12-13 17:00:51 -080052 map<ConfigKey, StatsdConfig> configsFromDisk;
53 StorageManager::readConfigFromDisk(configsFromDisk);
yro469cd802018-01-04 14:57:45 -080054 for (const auto& pair : configsFromDisk) {
55 UpdateConfig(pair.first, pair.second);
56 }
57}
Yao Chen3c0b95c2017-12-16 14:34:20 -080058
yro469cd802018-01-04 14:57:45 -080059void ConfigManager::StartupForTest() {
60 // Dummy function to avoid reading configs from disks for tests.
Joe Onorato9fc9edf2017-10-15 20:08:52 -070061}
62
63void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
David Chenfdc123b2018-02-09 17:21:48 -080064 lock_guard<mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -070065 mListeners.push_back(listener);
66}
67
68void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
David Chenfdc123b2018-02-09 17:21:48 -080069 vector<sp<ConfigListener>> broadcastList;
70 {
71 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -070072
yro44907652018-03-12 20:44:05 -070073 const int numBytes = config.ByteSize();
74 vector<uint8_t> buffer(numBytes);
75 config.SerializeToArray(&buffer[0], numBytes);
76
Yao Chen52b478b2018-03-27 10:59:45 -070077 auto uidIt = mConfigs.find(key.GetUid());
78 // GuardRail: Limit the number of configs per uid.
79 if (uidIt != mConfigs.end()) {
80 auto it = uidIt->second.find(key);
81 if (it == uidIt->second.end() &&
82 uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
83 ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
84 return;
85 }
86 }
yro44907652018-03-12 20:44:05 -070087
Yao Chen52b478b2018-03-27 10:59:45 -070088 // Check if it's a duplicate config.
89 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
90 StorageManager::hasIdenticalConfig(key, buffer)) {
91 // This is a duplicate config.
92 ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
93 // Update saved file on disk. We still update timestamp of file when
94 // there exists a duplicate configuration to avoid garbage collection.
95 update_saved_configs_locked(key, buffer, numBytes);
96 return;
97 }
98
99 // Update saved file on disk.
yro44907652018-03-12 20:44:05 -0700100 update_saved_configs_locked(key, buffer, numBytes);
101
Yao Chen52b478b2018-03-27 10:59:45 -0700102 // Add to set.
103 mConfigs[key.GetUid()].insert(key);
David Chenfdc123b2018-02-09 17:21:48 -0800104
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800105 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800106 broadcastList.push_back(listener);
107 }
108 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700109
Yangster-macc04feba2018-04-02 14:37:33 -0700110 const int64_t timestampNs = getElapsedRealtimeNs();
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700111 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800112 for (const sp<ConfigListener>& listener : broadcastList) {
Yangster-macc04feba2018-04-02 14:37:33 -0700113 listener->OnConfigUpdated(timestampNs, key, config);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700114 }
115}
116
David Chen661f7912018-01-22 17:46:24 -0800117void ConfigManager::SetConfigReceiver(const ConfigKey& key, const sp<IBinder>& intentSender) {
David Chenfdc123b2018-02-09 17:21:48 -0800118 lock_guard<mutex> lock(mMutex);
David Chen661f7912018-01-22 17:46:24 -0800119 mConfigReceivers[key] = intentSender;
David Chenadaf8b32017-11-03 15:42:08 -0700120}
121
122void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800123 lock_guard<mutex> lock(mMutex);
David Chenadaf8b32017-11-03 15:42:08 -0700124 mConfigReceivers.erase(key);
125}
126
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800127void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
128 const sp<IBinder>& intentSender) {
129 lock_guard<mutex> lock(mMutex);
130 mActiveConfigsChangedReceivers[uid] = intentSender;
131}
132
133void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
134 lock_guard<mutex> lock(mMutex);
135 mActiveConfigsChangedReceivers.erase(uid);
136}
137
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700138void ConfigManager::RemoveConfig(const ConfigKey& key) {
David Chenfdc123b2018-02-09 17:21:48 -0800139 vector<sp<ConfigListener>> broadcastList;
140 {
141 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700142
Tej Singh6ede28b2019-01-29 17:06:54 -0800143 auto uid = key.GetUid();
144 auto uidIt = mConfigs.find(uid);
Yao Chen52b478b2018-03-27 10:59:45 -0700145 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
David Chenfdc123b2018-02-09 17:21:48 -0800146 // Remove from map
Yao Chen52b478b2018-03-27 10:59:45 -0700147 uidIt->second.erase(key);
Tej Singh6ede28b2019-01-29 17:06:54 -0800148
149 // No more configs for this uid, lets remove the active configs callback.
150 if (uidIt->second.empty()) {
151 auto itActiveConfigsChangedReceiver = mActiveConfigsChangedReceivers.find(uid);
152 if (itActiveConfigsChangedReceiver != mActiveConfigsChangedReceivers.end()) {
153 mActiveConfigsChangedReceivers.erase(itActiveConfigsChangedReceiver);
154 }
155 }
156
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800157 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800158 broadcastList.push_back(listener);
159 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700160 }
David Chenfdc123b2018-02-09 17:21:48 -0800161
162 auto itReceiver = mConfigReceivers.find(key);
163 if (itReceiver != mConfigReceivers.end()) {
164 // Remove from map
165 mConfigReceivers.erase(itReceiver);
166 }
167
168 // Remove from disk. There can still be a lingering file on disk so we check
169 // whether or not the config was on memory.
170 remove_saved_configs(key);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700171 }
yro9c98c052017-11-19 14:33:56 -0800172
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800173 for (const sp<ConfigListener>& listener:broadcastList) {
David Chenfdc123b2018-02-09 17:21:48 -0800174 listener->OnConfigRemoved(key);
175 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700176}
177
yro87d983c2017-11-14 21:31:43 -0800178void ConfigManager::remove_saved_configs(const ConfigKey& key) {
yrof4ae56b2018-02-13 22:06:34 -0800179 string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
yroe5f82922018-01-22 18:37:27 -0800180 StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
yro87d983c2017-11-14 21:31:43 -0800181}
182
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700183void ConfigManager::RemoveConfigs(int uid) {
184 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800185 vector<sp<ConfigListener>> broadcastList;
186 {
187 lock_guard <mutex> lock(mMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700188
Yao Chen52b478b2018-03-27 10:59:45 -0700189 auto uidIt = mConfigs.find(uid);
190 if (uidIt == mConfigs.end()) {
191 return;
192 }
193
194 for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
David Chenfdc123b2018-02-09 17:21:48 -0800195 // Remove from map
David Chenfdc123b2018-02-09 17:21:48 -0800196 remove_saved_configs(*it);
197 removed.push_back(*it);
198 mConfigReceivers.erase(*it);
David Chenfdc123b2018-02-09 17:21:48 -0800199 }
200
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800201 auto itActiveConfigsChangedReceiver = mActiveConfigsChangedReceivers.find(uid);
202 if (itActiveConfigsChangedReceiver != mActiveConfigsChangedReceivers.end()) {
203 mActiveConfigsChangedReceivers.erase(itActiveConfigsChangedReceiver);
204 }
205
Yao Chen52b478b2018-03-27 10:59:45 -0700206 mConfigs.erase(uidIt);
207
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800208 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800209 broadcastList.push_back(listener);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700210 }
211 }
212
213 // Remove separately so if they do anything in the callback they can't mess up our iteration.
214 for (auto& key : removed) {
215 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800216 for (const sp<ConfigListener>& listener:broadcastList) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700217 listener->OnConfigRemoved(key);
218 }
219 }
220}
221
yro74fed972017-11-27 14:42:42 -0800222void ConfigManager::RemoveAllConfigs() {
223 vector<ConfigKey> removed;
David Chenfdc123b2018-02-09 17:21:48 -0800224 vector<sp<ConfigListener>> broadcastList;
225 {
226 lock_guard <mutex> lock(mMutex);
yro74fed972017-11-27 14:42:42 -0800227
Yao Chen52b478b2018-03-27 10:59:45 -0700228 for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
229 for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
230 // Remove from map
231 removed.push_back(*it);
232 it = uidIt->second.erase(it);
David Chenfdc123b2018-02-09 17:21:48 -0800233 }
Yao Chen52b478b2018-03-27 10:59:45 -0700234 uidIt = mConfigs.erase(uidIt);
yro74fed972017-11-27 14:42:42 -0800235 }
David Chenfdc123b2018-02-09 17:21:48 -0800236
Yao Chen52b478b2018-03-27 10:59:45 -0700237 mConfigReceivers.clear();
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800238 mActiveConfigsChangedReceivers.clear();
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800239 for (const sp<ConfigListener>& listener : mListeners) {
David Chenfdc123b2018-02-09 17:21:48 -0800240 broadcastList.push_back(listener);
241 }
yro74fed972017-11-27 14:42:42 -0800242 }
243
244 // Remove separately so if they do anything in the callback they can't mess up our iteration.
245 for (auto& key : removed) {
246 // Tell everyone
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800247 for (const sp<ConfigListener>& listener:broadcastList) {
yro74fed972017-11-27 14:42:42 -0800248 listener->OnConfigRemoved(key);
249 }
250 }
251}
252
Yangster7c334a12017-11-22 14:24:24 -0800253vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
David Chenfdc123b2018-02-09 17:21:48 -0800254 lock_guard<mutex> lock(mMutex);
255
David Chen1d7b0cd2017-11-15 14:20:04 -0800256 vector<ConfigKey> ret;
Yao Chen52b478b2018-03-27 10:59:45 -0700257 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
258 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
259 ret.push_back(*it);
260 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800261 }
262 return ret;
263}
264
David Chen661f7912018-01-22 17:46:24 -0800265const sp<android::IBinder> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
David Chenfdc123b2018-02-09 17:21:48 -0800266 lock_guard<mutex> lock(mMutex);
267
David Chen1d7b0cd2017-11-15 14:20:04 -0800268 auto it = mConfigReceivers.find(key);
269 if (it == mConfigReceivers.end()) {
David Chen661f7912018-01-22 17:46:24 -0800270 return nullptr;
David Chen1d7b0cd2017-11-15 14:20:04 -0800271 } else {
272 return it->second;
273 }
274}
275
Tej Singh2c9ef2a2019-01-22 11:33:51 -0800276const sp<android::IBinder> ConfigManager::GetActiveConfigsChangedReceiver(const int uid) const {
277 lock_guard<mutex> lock(mMutex);
278
279 auto it = mActiveConfigsChangedReceivers.find(uid);
280 if (it == mActiveConfigsChangedReceivers.end()) {
281 return nullptr;
282 } else {
283 return it->second;
284 }
285}
286
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700287void ConfigManager::Dump(FILE* out) {
David Chenfdc123b2018-02-09 17:21:48 -0800288 lock_guard<mutex> lock(mMutex);
289
Yao Chen52b478b2018-03-27 10:59:45 -0700290 fprintf(out, "CONFIGURATIONS\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700291 fprintf(out, " uid name\n");
Yao Chen52b478b2018-03-27 10:59:45 -0700292 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
293 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
294 fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
295 auto receiverIt = mConfigReceivers.find(*it);
296 if (receiverIt != mConfigReceivers.end()) {
297 fprintf(out, " -> received by PendingIntent as binder\n");
298 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800299 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700300 }
301}
302
yro44907652018-03-12 20:44:05 -0700303void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
304 const vector<uint8_t>& buffer,
305 const int numBytes) {
yro9c98c052017-11-19 14:33:56 -0800306 // If there is a pre-existing config with same key we should first delete it.
307 remove_saved_configs(key);
308
309 // Then we save the latest config.
yro44907652018-03-12 20:44:05 -0700310 string file_name =
311 StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
312 key.GetUid(), (long long)key.GetId());
yro947fbce2017-11-15 22:50:23 -0800313 StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700314}
315
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700316} // namespace statsd
317} // namespace os
318} // namespace android