blob: ca88c62d88323e47d8752086548200212c51567a [file] [log] [blame]
Joe Onoratoda8cca72017-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
satayev134c97a2022-02-09 12:45:25 +000017#define STATSD_DEBUG false // STOPSHIP if true
Yao Chen341db892018-03-27 10:59:45 -070018#include "Log.h"
19
Joe Onoratoda8cca72017-10-15 20:08:52 -070020#include "config/ConfigManager.h"
yro1528e0f2017-11-15 22:50:23 -080021#include "storage/StorageManager.h"
Joe Onoratoda8cca72017-10-15 20:08:52 -070022
Yao Chen341db892018-03-27 10:59:45 -070023#include "guardrail/StatsdStats.h"
Yangster-mace9b52eb2018-04-02 14:37:33 -070024#include "stats_log_util.h"
Joe Onoratoda8cca72017-10-15 20:08:52 -070025#include "stats_util.h"
Yangster-macf50f12b2018-03-30 15:22:08 -070026#include "stats_log_util.h"
Joe Onoratoda8cca72017-10-15 20:08:52 -070027
Joe Onoratoda8cca72017-10-15 20:08:52 -070028#include <stdio.h>
yrod3a24362017-11-14 21:31:43 -080029#include <vector>
30#include "android-base/stringprintf.h"
Joe Onoratoda8cca72017-10-15 20:08:52 -070031
32namespace android {
33namespace os {
34namespace statsd {
35
Yao Chena277da32017-12-13 17:00:51 -080036using std::pair;
Yao Chena277da32017-12-13 17:00:51 -080037using std::string;
38using std::vector;
39
yro06849152017-12-12 00:17:50 -080040#define STATS_SERVICE_DIR "/data/misc/stats-service"
yrod3a24362017-11-14 21:31:43 -080041
yrod3a24362017-11-14 21:31:43 -080042using android::base::StringPrintf;
43using std::unique_ptr;
44
Tej Singh81e38f42021-10-19 23:40:07 -070045ConfigManager::ConfigManager() {
Joe Onoratoda8cca72017-10-15 20:08:52 -070046}
47
48ConfigManager::~ConfigManager() {
49}
50
51void ConfigManager::Startup() {
Yao Chena277da32017-12-13 17:00:51 -080052 map<ConfigKey, StatsdConfig> configsFromDisk;
53 StorageManager::readConfigFromDisk(configsFromDisk);
yro1d5bb082018-01-04 14:57:45 -080054 for (const auto& pair : configsFromDisk) {
55 UpdateConfig(pair.first, pair.second);
56 }
57}
Yao Chen0cf61892017-12-16 14:34:20 -080058
yro1d5bb082018-01-04 14:57:45 -080059void ConfigManager::StartupForTest() {
Kelly Rossmoyera685f902020-07-29 21:22:15 +000060 // No-op function to avoid reading configs from disks for tests.
Joe Onoratoda8cca72017-10-15 20:08:52 -070061}
62
63void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
David Chen687dbd12018-02-09 17:21:48 -080064 lock_guard<mutex> lock(mMutex);
Joe Onoratoda8cca72017-10-15 20:08:52 -070065 mListeners.push_back(listener);
66}
67
68void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
David Chen687dbd12018-02-09 17:21:48 -080069 vector<sp<ConfigListener>> broadcastList;
70 {
71 lock_guard <mutex> lock(mMutex);
Joe Onoratoda8cca72017-10-15 20:08:52 -070072
yro2918b552018-03-12 20:44:05 -070073 const int numBytes = config.ByteSize();
74 vector<uint8_t> buffer(numBytes);
Muhammad Qureshif4951fb2022-03-29 07:00:28 -070075 config.SerializeToArray(buffer.data(), numBytes);
yro2918b552018-03-12 20:44:05 -070076
Yao Chen341db892018-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 }
yro2918b552018-03-12 20:44:05 -070087
Yao Chen341db892018-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.
yro2918b552018-03-12 20:44:05 -0700100 update_saved_configs_locked(key, buffer, numBytes);
101
Yao Chen341db892018-03-27 10:59:45 -0700102 // Add to set.
103 mConfigs[key.GetUid()].insert(key);
David Chen687dbd12018-02-09 17:21:48 -0800104
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800105 for (const sp<ConfigListener>& listener : mListeners) {
David Chen687dbd12018-02-09 17:21:48 -0800106 broadcastList.push_back(listener);
107 }
108 }
Joe Onoratoda8cca72017-10-15 20:08:52 -0700109
Yangster-mace9b52eb2018-04-02 14:37:33 -0700110 const int64_t timestampNs = getElapsedRealtimeNs();
Joe Onoratoda8cca72017-10-15 20:08:52 -0700111 // Tell everyone
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800112 for (const sp<ConfigListener>& listener : broadcastList) {
Yangster-mace9b52eb2018-04-02 14:37:33 -0700113 listener->OnConfigUpdated(timestampNs, key, config);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700114 }
115}
116
Jeffrey Huangd0c3d342019-12-16 13:50:06 -0800117void ConfigManager::SetConfigReceiver(const ConfigKey& key,
Ruchir Rastogid36dd0b2020-02-10 17:40:09 -0800118 const shared_ptr<IPendingIntentRef>& pir) {
David Chen687dbd12018-02-09 17:21:48 -0800119 lock_guard<mutex> lock(mMutex);
Jeffrey Huangd0c3d342019-12-16 13:50:06 -0800120 mConfigReceivers[key] = pir;
David Chenec84d132017-11-03 15:42:08 -0700121}
122
123void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
David Chen687dbd12018-02-09 17:21:48 -0800124 lock_guard<mutex> lock(mMutex);
David Chenec84d132017-11-03 15:42:08 -0700125 mConfigReceivers.erase(key);
126}
127
Tej Singh81e38f42021-10-19 23:40:07 -0700128void ConfigManager::RemoveConfigReceiver(const ConfigKey& key,
129 const shared_ptr<IPendingIntentRef>& pir) {
130 lock_guard<mutex> lock(mMutex);
131 auto it = mConfigReceivers.find(key);
132 if (it != mConfigReceivers.end() && it->second == pir) {
133 mConfigReceivers.erase(key);
134 }
135}
136
Tej Singhfad59e32019-01-22 11:33:51 -0800137void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
Ruchir Rastogid36dd0b2020-02-10 17:40:09 -0800138 const shared_ptr<IPendingIntentRef>& pir) {
Tej Singh81e38f42021-10-19 23:40:07 -0700139 lock_guard<mutex> lock(mMutex);
140 mActiveConfigsChangedReceivers[uid] = pir;
Tej Singhfad59e32019-01-22 11:33:51 -0800141}
142
143void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
144 lock_guard<mutex> lock(mMutex);
145 mActiveConfigsChangedReceivers.erase(uid);
146}
147
Tej Singh81e38f42021-10-19 23:40:07 -0700148void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid,
149 const shared_ptr<IPendingIntentRef>& pir) {
150 lock_guard<mutex> lock(mMutex);
151 auto it = mActiveConfigsChangedReceivers.find(uid);
152 if (it != mActiveConfigsChangedReceivers.end() && it->second == pir) {
153 mActiveConfigsChangedReceivers.erase(uid);
154 }
155}
156
Joe Onoratoda8cca72017-10-15 20:08:52 -0700157void ConfigManager::RemoveConfig(const ConfigKey& key) {
David Chen687dbd12018-02-09 17:21:48 -0800158 vector<sp<ConfigListener>> broadcastList;
159 {
160 lock_guard <mutex> lock(mMutex);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700161
Tej Singha783d522019-01-29 17:06:54 -0800162 auto uid = key.GetUid();
163 auto uidIt = mConfigs.find(uid);
Yao Chen341db892018-03-27 10:59:45 -0700164 if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
David Chen687dbd12018-02-09 17:21:48 -0800165 // Remove from map
Yao Chen341db892018-03-27 10:59:45 -0700166 uidIt->second.erase(key);
Tej Singha783d522019-01-29 17:06:54 -0800167
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800168 for (const sp<ConfigListener>& listener : mListeners) {
David Chen687dbd12018-02-09 17:21:48 -0800169 broadcastList.push_back(listener);
170 }
Joe Onoratoda8cca72017-10-15 20:08:52 -0700171 }
David Chen687dbd12018-02-09 17:21:48 -0800172
David Chen687dbd12018-02-09 17:21:48 -0800173 // Remove from disk. There can still be a lingering file on disk so we check
174 // whether or not the config was on memory.
175 remove_saved_configs(key);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700176 }
yro9bb4f7d2017-11-19 14:33:56 -0800177
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800178 for (const sp<ConfigListener>& listener:broadcastList) {
David Chen687dbd12018-02-09 17:21:48 -0800179 listener->OnConfigRemoved(key);
180 }
Joe Onoratoda8cca72017-10-15 20:08:52 -0700181}
182
yrod3a24362017-11-14 21:31:43 -0800183void ConfigManager::remove_saved_configs(const ConfigKey& key) {
yro0bd9aa12018-02-13 22:06:34 -0800184 string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
yroa8c4ebf2018-01-22 18:37:27 -0800185 StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
yrod3a24362017-11-14 21:31:43 -0800186}
187
Joe Onoratoda8cca72017-10-15 20:08:52 -0700188void ConfigManager::RemoveConfigs(int uid) {
189 vector<ConfigKey> removed;
David Chen687dbd12018-02-09 17:21:48 -0800190 vector<sp<ConfigListener>> broadcastList;
191 {
192 lock_guard <mutex> lock(mMutex);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700193
Yao Chen341db892018-03-27 10:59:45 -0700194 auto uidIt = mConfigs.find(uid);
195 if (uidIt == mConfigs.end()) {
196 return;
197 }
198
199 for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
David Chen687dbd12018-02-09 17:21:48 -0800200 // Remove from map
David Chen687dbd12018-02-09 17:21:48 -0800201 remove_saved_configs(*it);
202 removed.push_back(*it);
Tej Singhfad59e32019-01-22 11:33:51 -0800203 }
204
Yao Chen341db892018-03-27 10:59:45 -0700205 mConfigs.erase(uidIt);
206
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800207 for (const sp<ConfigListener>& listener : mListeners) {
David Chen687dbd12018-02-09 17:21:48 -0800208 broadcastList.push_back(listener);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700209 }
210 }
211
212 // Remove separately so if they do anything in the callback they can't mess up our iteration.
213 for (auto& key : removed) {
214 // Tell everyone
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800215 for (const sp<ConfigListener>& listener:broadcastList) {
Joe Onoratoda8cca72017-10-15 20:08:52 -0700216 listener->OnConfigRemoved(key);
217 }
218 }
219}
220
yro11e2da52017-11-27 14:42:42 -0800221void ConfigManager::RemoveAllConfigs() {
222 vector<ConfigKey> removed;
David Chen687dbd12018-02-09 17:21:48 -0800223 vector<sp<ConfigListener>> broadcastList;
224 {
225 lock_guard <mutex> lock(mMutex);
yro11e2da52017-11-27 14:42:42 -0800226
Yao Chen341db892018-03-27 10:59:45 -0700227 for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
228 for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
229 // Remove from map
230 removed.push_back(*it);
231 it = uidIt->second.erase(it);
David Chen687dbd12018-02-09 17:21:48 -0800232 }
Yao Chen341db892018-03-27 10:59:45 -0700233 uidIt = mConfigs.erase(uidIt);
yro11e2da52017-11-27 14:42:42 -0800234 }
David Chen687dbd12018-02-09 17:21:48 -0800235
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800236 for (const sp<ConfigListener>& listener : mListeners) {
David Chen687dbd12018-02-09 17:21:48 -0800237 broadcastList.push_back(listener);
238 }
yro11e2da52017-11-27 14:42:42 -0800239 }
240
241 // Remove separately so if they do anything in the callback they can't mess up our iteration.
242 for (auto& key : removed) {
243 // Tell everyone
Chih-Hung Hsiehfa35ea82018-12-11 11:09:20 -0800244 for (const sp<ConfigListener>& listener:broadcastList) {
yro11e2da52017-11-27 14:42:42 -0800245 listener->OnConfigRemoved(key);
246 }
247 }
248}
249
Yangsterd1df8ed2017-11-22 14:24:24 -0800250vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
David Chen687dbd12018-02-09 17:21:48 -0800251 lock_guard<mutex> lock(mMutex);
252
David Chendd4e8032017-11-15 14:20:04 -0800253 vector<ConfigKey> ret;
Yao Chen341db892018-03-27 10:59:45 -0700254 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
255 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
256 ret.push_back(*it);
257 }
David Chendd4e8032017-11-15 14:20:04 -0800258 }
259 return ret;
260}
261
Ruchir Rastogid36dd0b2020-02-10 17:40:09 -0800262const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
David Chen687dbd12018-02-09 17:21:48 -0800263 lock_guard<mutex> lock(mMutex);
264
David Chendd4e8032017-11-15 14:20:04 -0800265 auto it = mConfigReceivers.find(key);
266 if (it == mConfigReceivers.end()) {
David Chen29ada1e2018-01-22 17:46:24 -0800267 return nullptr;
David Chendd4e8032017-11-15 14:20:04 -0800268 } else {
269 return it->second;
270 }
271}
272
Ruchir Rastogid36dd0b2020-02-10 17:40:09 -0800273const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
274 const {
Tej Singhfad59e32019-01-22 11:33:51 -0800275 lock_guard<mutex> lock(mMutex);
276
277 auto it = mActiveConfigsChangedReceivers.find(uid);
278 if (it == mActiveConfigsChangedReceivers.end()) {
279 return nullptr;
280 } else {
281 return it->second;
282 }
283}
284
Joe Onoratoda8cca72017-10-15 20:08:52 -0700285void ConfigManager::Dump(FILE* out) {
David Chen687dbd12018-02-09 17:21:48 -0800286 lock_guard<mutex> lock(mMutex);
287
Yao Chen341db892018-03-27 10:59:45 -0700288 fprintf(out, "CONFIGURATIONS\n");
Joe Onoratoda8cca72017-10-15 20:08:52 -0700289 fprintf(out, " uid name\n");
Yao Chen341db892018-03-27 10:59:45 -0700290 for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
291 for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
292 fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
293 auto receiverIt = mConfigReceivers.find(*it);
294 if (receiverIt != mConfigReceivers.end()) {
295 fprintf(out, " -> received by PendingIntent as binder\n");
296 }
David Chendd4e8032017-11-15 14:20:04 -0800297 }
Joe Onoratoda8cca72017-10-15 20:08:52 -0700298 }
299}
300
yro2918b552018-03-12 20:44:05 -0700301void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
302 const vector<uint8_t>& buffer,
303 const int numBytes) {
yro9bb4f7d2017-11-19 14:33:56 -0800304 // If there is a pre-existing config with same key we should first delete it.
305 remove_saved_configs(key);
306
307 // Then we save the latest config.
yro2918b552018-03-12 20:44:05 -0700308 string file_name =
309 StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
310 key.GetUid(), (long long)key.GetId());
yro1528e0f2017-11-15 22:50:23 -0800311 StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
Joe Onoratoda8cca72017-10-15 20:08:52 -0700312}
313
Joe Onoratoda8cca72017-10-15 20:08:52 -0700314} // namespace statsd
315} // namespace os
316} // namespace android