blob: 07b1c5c06d04b959f9424058a903bb9b52d241a4 [file] [log] [blame]
Joe Onorato5dcbc6c2017-08-29 15:13:58 -07001/*
2 * Copyright (C) 2016 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
Bookatzb487b552017-09-18 11:26:01 -070017#define DEBUG true
Joe Onorato9fc9edf2017-10-15 20:08:52 -070018#include "Log.h"
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070019
20#include "StatsService.h"
David Chenadaf8b32017-11-03 15:42:08 -070021#include "config/ConfigKey.h"
22#include "config/ConfigManager.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070023#include "storage/DropboxReader.h"
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070024
David Chen0656b7a2017-09-13 15:53:39 -070025#include <android-base/file.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070026#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
David Chen0656b7a2017-09-13 15:53:39 -070028#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070029#include <private/android_filesystem_config.h>
30#include <utils/Looper.h>
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070031#include <utils/String16.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070032
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070033#include <stdio.h>
Yao Chen482d2722017-09-12 13:25:43 -070034#include <stdlib.h>
Joe Onorato9fc9edf2017-10-15 20:08:52 -070035#include <sys/system_properties.h>
Yao Chenef99c4f2017-09-22 16:26:54 -070036#include <unistd.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070037
38using namespace android;
39
Bookatz906a35c2017-09-20 15:26:44 -070040namespace android {
41namespace os {
42namespace statsd {
43
David Chenadaf8b32017-11-03 15:42:08 -070044constexpr const char* kPermissionDump = "android.permission.DUMP";
45
Joe Onorato9fc9edf2017-10-15 20:08:52 -070046// ======================================================================
47/**
48 * Watches for the death of the stats companion (system process).
49 */
50class CompanionDeathRecipient : public IBinder::DeathRecipient {
51public:
52 CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor);
53 virtual void binderDied(const wp<IBinder>& who);
54
55private:
56 const sp<AnomalyMonitor> mAnomalyMonitor;
57};
58
59CompanionDeathRecipient::CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor)
60 : mAnomalyMonitor(anomalyMonitor) {
61}
62
63void CompanionDeathRecipient::binderDied(const wp<IBinder>& who) {
64 ALOGW("statscompanion service died");
65 mAnomalyMonitor->setStatsCompanionService(nullptr);
66}
67
68// ======================================================================
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070069StatsService::StatsService(const sp<Looper>& handlerLooper)
David Chen1481fe12017-10-16 13:16:34 -070070 : mAnomalyMonitor(new AnomalyMonitor(2)) // TODO: Put this comment somewhere better
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070071{
Joe Onorato9fc9edf2017-10-15 20:08:52 -070072 mUidMap = new UidMap();
73 mConfigManager = new ConfigManager();
David Chenadaf8b32017-11-03 15:42:08 -070074 mProcessor = new StatsLogProcessor(mUidMap, [](const vector<uint8_t>& log) {
75 // TODO: Update how we send data out of StatsD.
yro31eb67b2017-10-24 13:33:21 -070076 });
Joe Onorato9fc9edf2017-10-15 20:08:52 -070077
78 mConfigManager->AddListener(mProcessor);
79
80 init_system_properties();
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070081}
82
Yao Chenef99c4f2017-09-22 16:26:54 -070083StatsService::~StatsService() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070084}
85
Joe Onorato9fc9edf2017-10-15 20:08:52 -070086void StatsService::init_system_properties() {
87 mEngBuild = false;
88 const prop_info* buildType = __system_property_find("ro.build.type");
89 if (buildType != NULL) {
90 __system_property_read_callback(buildType, init_build_type_callback, this);
91 }
David Chen0656b7a2017-09-13 15:53:39 -070092}
93
Joe Onorato9fc9edf2017-10-15 20:08:52 -070094void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
95 uint32_t serial) {
Yao Chen729093d2017-10-16 10:33:26 -070096 if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -070097 reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
98 }
99}
100
101/**
102 * Implement our own because the default binder implementation isn't
103 * properly handling SHELL_COMMAND_TRANSACTION.
104 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700105status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
106 uint32_t flags) {
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700107 status_t err;
108
109 switch (code) {
110 case SHELL_COMMAND_TRANSACTION: {
111 int in = data.readFileDescriptor();
112 int out = data.readFileDescriptor();
113 int err = data.readFileDescriptor();
114 int argc = data.readInt32();
115 Vector<String8> args;
116 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
117 args.add(String8(data.readString16()));
118 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700119 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
120 sp<IResultReceiver> resultReceiver =
121 IResultReceiver::asInterface(data.readStrongBinder());
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700122
123 FILE* fin = fdopen(in, "r");
124 FILE* fout = fdopen(out, "w");
125 FILE* ferr = fdopen(err, "w");
126
127 if (fin == NULL || fout == NULL || ferr == NULL) {
128 resultReceiver->send(NO_MEMORY);
129 } else {
130 err = command(fin, fout, ferr, args);
131 resultReceiver->send(err);
132 }
133
134 if (fin != NULL) {
135 fflush(fin);
136 fclose(fin);
137 }
138 if (fout != NULL) {
139 fflush(fout);
140 fclose(fout);
141 }
142 if (fout != NULL) {
143 fflush(ferr);
144 fclose(ferr);
145 }
146
147 return NO_ERROR;
148 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700149 default: { return BnStatsManager::onTransact(code, data, reply, flags); }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700150 }
151}
152
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700153/**
154 * Write debugging data about statsd.
155 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700156status_t StatsService::dump(int fd, const Vector<String16>& args) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700157 FILE* out = fdopen(fd, "w");
158 if (out == NULL) {
159 return NO_MEMORY; // the fd is already open
160 }
161
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700162 // TODO: Proto format for incident reports
163 dump_impl(out);
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700164
165 fclose(out);
166 return NO_ERROR;
167}
168
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700169/**
170 * Write debugging data about statsd in text format.
171 */
172void StatsService::dump_impl(FILE* out) {
173 mConfigManager->Dump(out);
174}
175
176/**
177 * Implementation of the adb shell cmd stats command.
178 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700179status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700180 // TODO: Permission check
181
182 const int argCount = args.size();
183 if (argCount >= 1) {
184 // adb shell cmd stats config ...
David Chen0656b7a2017-09-13 15:53:39 -0700185 if (!args[0].compare(String8("config"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700186 return cmd_config(in, out, err, args);
David Chen0656b7a2017-09-13 15:53:39 -0700187 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700188
189 // adb shell cmd stats print-stats-log
190 if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) {
191 return cmd_print_stats_log(out, args);
192 }
193
David Chende701692017-10-05 13:16:02 -0700194 if (!args[0].compare(String8("print-uid-map"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700195 return cmd_print_uid_map(out);
David Chende701692017-10-05 13:16:02 -0700196 }
Yao Chen729093d2017-10-16 10:33:26 -0700197
198 if (!args[0].compare(String8("dump-report"))) {
199 return cmd_dump_report(out, err, args);
200 }
David Chen1481fe12017-10-16 13:16:34 -0700201
202 if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
203 return cmd_print_pulled_metrics(out, args);
204 }
David Chenadaf8b32017-11-03 15:42:08 -0700205
206 if (!args[0].compare(String8("send-broadcast"))) {
207 return cmd_trigger_broadcast(args);
208 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700209 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700210
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700211 print_cmd_help(out);
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700212 return NO_ERROR;
213}
214
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700215void StatsService::print_cmd_help(FILE* out) {
216 fprintf(out,
217 "usage: adb shell cmd stats print-stats-log [tag_required] "
218 "[timestamp_nsec_optional]\n");
219 fprintf(out, "\n");
220 fprintf(out, "\n");
221 fprintf(out, "usage: adb shell cmd stats print-uid-map \n");
222 fprintf(out, "\n");
223 fprintf(out, " Prints the UID, app name, version mapping.\n");
224 fprintf(out, "\n");
225 fprintf(out, "\n");
David Chen1481fe12017-10-16 13:16:34 -0700226 fprintf(out, "usage: adb shell cmds stats pull-source [int] \n");
227 fprintf(out, "\n");
228 fprintf(out, " Prints the output of a pulled metrics source (int indicates source)\n");
229 fprintf(out, "\n");
230 fprintf(out, "\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700231 fprintf(out, "usage: adb shell cmd stats config remove [UID] NAME\n");
232 fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
233 fprintf(out, "\n");
234 fprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
235 fprintf(out, " wire-encoded protobuf format and passed via stdin.\n");
236 fprintf(out, "\n");
237 fprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
238 fprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
239 fprintf(out, " uid is used.\n");
240 fprintf(out, " NAME The per-uid name to use\n");
Yao Chen5154a372017-10-30 22:57:06 -0700241 fprintf(out, "\n");
242 fprintf(out, "\n");
243 fprintf(out, "usage: adb shell cmd stats dump-report [UID] NAME\n");
244 fprintf(out, " Dump all metric data for a configuration.\n");
245 fprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
246 fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
247 fprintf(out, " calling uid is used.\n");
248 fprintf(out, " NAME The name of the configuration\n");
David Chenadaf8b32017-11-03 15:42:08 -0700249 fprintf(out, "\n");
250 fprintf(out, "\n");
251 fprintf(out, "usage: adb shell cmd stats send-broadcast PACKAGE CLASS\n");
252 fprintf(out, " Send a broadcast that triggers one subscriber to fetch metrics.\n");
253 fprintf(out, " PACKAGE The name of the package to receive the broadcast.\n");
254 fprintf(out, " CLASS The name of the class to receive the broadcast.\n");
255}
256
257status_t StatsService::cmd_trigger_broadcast(Vector<String8>& args) {
258 auto sc = getStatsCompanionService();
259 sc->sendBroadcast(String16(args[1]), String16(args[2]));
260 ALOGD("StatsService::trigger broadcast succeeded");
261 return NO_ERROR;
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700262}
263
264status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
265 const int argCount = args.size();
266 if (argCount >= 2) {
267 if (args[1] == "update" || args[1] == "remove") {
268 bool good = false;
269 int uid = -1;
270 string name;
271
272 if (argCount == 3) {
273 // Automatically pick the UID
274 uid = IPCThreadState::self()->getCallingUid();
275 // TODO: What if this isn't a binder call? Should we fail?
276 name.assign(args[2].c_str(), args[2].size());
277 good = true;
278 } else if (argCount == 4) {
279 // If it's a userdebug or eng build, then the shell user can
280 // impersonate other uids.
281 if (mEngBuild) {
282 const char* s = args[2].c_str();
283 if (*s != '\0') {
284 char* end = NULL;
285 uid = strtol(s, &end, 0);
286 if (*end == '\0') {
287 name.assign(args[3].c_str(), args[3].size());
288 good = true;
289 }
290 }
291 } else {
Yao Chen729093d2017-10-16 10:33:26 -0700292 fprintf(err,
293 "The config can only be set for other UIDs on eng or userdebug "
294 "builds.\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700295 }
296 }
297
298 if (!good) {
299 // If arg parsing failed, print the help text and return an error.
300 print_cmd_help(out);
301 return UNKNOWN_ERROR;
302 }
303
304 if (args[1] == "update") {
305 // Read stream into buffer.
306 string buffer;
307 if (!android::base::ReadFdToString(fileno(in), &buffer)) {
308 fprintf(err, "Error reading stream for StatsConfig.\n");
309 return UNKNOWN_ERROR;
310 }
311
312 // Parse buffer.
313 StatsdConfig config;
314 if (!config.ParseFromString(buffer)) {
315 fprintf(err, "Error parsing proto stream for StatsConfig.\n");
316 return UNKNOWN_ERROR;
317 }
318
319 // Add / update the config.
320 mConfigManager->UpdateConfig(ConfigKey(uid, name), config);
321 } else {
322 // Remove the config.
323 mConfigManager->RemoveConfig(ConfigKey(uid, name));
324 }
325
326 return NO_ERROR;
327 }
David Chen0656b7a2017-09-13 15:53:39 -0700328 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700329 print_cmd_help(out);
330 return UNKNOWN_ERROR;
331}
332
Yao Chen729093d2017-10-16 10:33:26 -0700333status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
334 if (mProcessor != nullptr) {
335 const int argCount = args.size();
336 bool good = false;
337 int uid;
338 string name;
339 if (argCount == 2) {
340 // Automatically pick the UID
341 uid = IPCThreadState::self()->getCallingUid();
342 // TODO: What if this isn't a binder call? Should we fail?
Yao Chen5154a372017-10-30 22:57:06 -0700343 name.assign(args[1].c_str(), args[1].size());
Yao Chen729093d2017-10-16 10:33:26 -0700344 good = true;
345 } else if (argCount == 3) {
346 // If it's a userdebug or eng build, then the shell user can
347 // impersonate other uids.
348 if (mEngBuild) {
349 const char* s = args[1].c_str();
350 if (*s != '\0') {
351 char* end = NULL;
352 uid = strtol(s, &end, 0);
353 if (*end == '\0') {
354 name.assign(args[2].c_str(), args[2].size());
355 good = true;
356 }
357 }
358 } else {
359 fprintf(out,
360 "The metrics can only be dumped for other UIDs on eng or userdebug "
361 "builds.\n");
362 }
363 }
364 if (good) {
365 mProcessor->onDumpReport(ConfigKey(uid, name));
366 // TODO: print the returned StatsLogReport to file instead of printing to logcat.
367 fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
368 fprintf(out, "See the StatsLogReport in logcat...\n");
369 return android::OK;
370 } else {
371 // If arg parsing failed, print the help text and return an error.
372 print_cmd_help(out);
373 return UNKNOWN_ERROR;
374 }
375 } else {
376 fprintf(out, "Log processor does not exist...\n");
377 return UNKNOWN_ERROR;
378 }
379}
380
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700381status_t StatsService::cmd_print_stats_log(FILE* out, const Vector<String8>& args) {
382 long msec = 0;
383
384 if (args.size() > 2) {
385 msec = strtol(args[2].string(), NULL, 10);
David Chen0656b7a2017-09-13 15:53:39 -0700386 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700387 return DropboxReader::readStatsLogs(out, args[1].string(), msec);
388}
389
390status_t StatsService::cmd_print_uid_map(FILE* out) {
391 mUidMap->printUidMap(out);
392 return NO_ERROR;
David Chen0656b7a2017-09-13 15:53:39 -0700393}
394
David Chen1481fe12017-10-16 13:16:34 -0700395status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
396 int s = atoi(args[1].c_str());
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700397 vector<shared_ptr<LogEvent> > stats;
398 if (mStatsPullerManager.Pull(s, &stats)) {
399 for (const auto& it : stats) {
400 fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
401 }
402 fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
403 return NO_ERROR;
David Chen1481fe12017-10-16 13:16:34 -0700404 }
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700405 return UNKNOWN_ERROR;
David Chen1481fe12017-10-16 13:16:34 -0700406}
407
David Chende701692017-10-05 13:16:02 -0700408Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
409 const vector<String16>& app) {
410 if (DEBUG) ALOGD("StatsService::informAllUidData was called");
411
412 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
413 return Status::fromExceptionCode(Status::EX_SECURITY,
414 "Only system uid can call informAllUidData");
415 }
416
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700417 mUidMap->updateMap(uid, version, app);
David Chende701692017-10-05 13:16:02 -0700418 if (DEBUG) ALOGD("StatsService::informAllUidData succeeded");
419
420 return Status::ok();
421}
422
423Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t version) {
424 if (DEBUG) ALOGD("StatsService::informOnePackage was called");
425
426 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
427 return Status::fromExceptionCode(Status::EX_SECURITY,
428 "Only system uid can call informOnePackage");
429 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700430 mUidMap->updateApp(app, uid, version);
David Chende701692017-10-05 13:16:02 -0700431 return Status::ok();
432}
433
434Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
435 if (DEBUG) ALOGD("StatsService::informOnePackageRemoved was called");
436
437 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
438 return Status::fromExceptionCode(Status::EX_SECURITY,
439 "Only system uid can call informOnePackageRemoved");
440 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700441 mUidMap->removeApp(app, uid);
David Chende701692017-10-05 13:16:02 -0700442 return Status::ok();
443}
444
Yao Chenef99c4f2017-09-22 16:26:54 -0700445Status StatsService::informAnomalyAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700446 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700447
448 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
449 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700450 "Only system uid can call informAnomalyAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700451 }
452
Bookatzb487b552017-09-18 11:26:01 -0700453 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700454 // TODO: check through all counters/timers and see if an anomaly has indeed occurred.
455
456 return Status::ok();
457}
458
Yao Chenef99c4f2017-09-22 16:26:54 -0700459Status StatsService::informPollAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700460 if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700461
462 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
463 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700464 "Only system uid can call informPollAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700465 }
466
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700467 mStatsPullerManager.OnAlarmFired();
Chenjie Yub3dda412017-10-24 13:41:59 -0700468
Bookatzb487b552017-09-18 11:26:01 -0700469 if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700470
471 return Status::ok();
472}
473
Yao Chenef99c4f2017-09-22 16:26:54 -0700474Status StatsService::systemRunning() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700475 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
476 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700477 "Only system uid can call systemRunning");
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700478 }
479
480 // When system_server is up and running, schedule the dropbox task to run.
481 ALOGD("StatsService::systemRunning");
482
Bookatzb487b552017-09-18 11:26:01 -0700483 sayHiToStatsCompanion();
484
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700485 return Status::ok();
486}
487
Yao Chenef99c4f2017-09-22 16:26:54 -0700488void StatsService::sayHiToStatsCompanion() {
489 // TODO: This method needs to be private. It is temporarily public and unsecured for testing
490 // purposes.
Bookatzb487b552017-09-18 11:26:01 -0700491 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
492 if (statsCompanion != nullptr) {
493 if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
494 statsCompanion->statsdReady();
495 } else {
496 if (DEBUG) ALOGD("Could not access statsCompanion");
497 }
498}
499
Yao Chenef99c4f2017-09-22 16:26:54 -0700500sp<IStatsCompanionService> StatsService::getStatsCompanionService() {
Bookatz906a35c2017-09-20 15:26:44 -0700501 sp<IStatsCompanionService> statsCompanion = nullptr;
502 // Get statscompanion service from service manager
503 const sp<IServiceManager> sm(defaultServiceManager());
504 if (sm != nullptr) {
505 const String16 name("statscompanion");
506 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
507 if (statsCompanion == nullptr) {
508 ALOGW("statscompanion service unavailable!");
509 return nullptr;
510 }
511 }
512 return statsCompanion;
513}
514
Yao Chenef99c4f2017-09-22 16:26:54 -0700515Status StatsService::statsCompanionReady() {
Bookatzb487b552017-09-18 11:26:01 -0700516 if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");
517
518 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
519 return Status::fromExceptionCode(Status::EX_SECURITY,
520 "Only system uid can call statsCompanionReady");
521 }
522
523 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
524 if (statsCompanion == nullptr) {
Yao Chenef99c4f2017-09-22 16:26:54 -0700525 return Status::fromExceptionCode(
526 Status::EX_NULL_POINTER,
527 "statscompanion unavailable despite it contacting statsd!");
Bookatzb487b552017-09-18 11:26:01 -0700528 }
529 if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700530 IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor));
Bookatzb487b552017-09-18 11:26:01 -0700531 mAnomalyMonitor->setStatsCompanionService(statsCompanion);
532
533 return Status::ok();
534}
535
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700536void StatsService::Startup() {
537 mConfigManager->Startup();
Bookatz906a35c2017-09-20 15:26:44 -0700538}
539
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700540void StatsService::OnLogEvent(const LogEvent& event) {
541 mProcessor->OnLogEvent(event);
Bookatz906a35c2017-09-20 15:26:44 -0700542}
543
David Chenadaf8b32017-11-03 15:42:08 -0700544Status StatsService::getData(const String16& key, vector<uint8_t>* output) {
545 IPCThreadState* ipc = IPCThreadState::self();
546 if (checkCallingPermission(String16(kPermissionDump),
547 reinterpret_cast<int32_t*>(ipc->getCallingPid()),
548 reinterpret_cast<int32_t*>(ipc->getCallingUid()))) {
549 // TODO: Implement this.
550 return Status::ok();
551 } else {
552 return Status::fromExceptionCode(binder::Status::EX_SECURITY);
553 }
yro31eb67b2017-10-24 13:33:21 -0700554}
555
David Chenadaf8b32017-11-03 15:42:08 -0700556Status StatsService::addConfiguration(const String16& key,
557 const vector <uint8_t>& config,
558 const String16& package, const String16& cls,
559 bool* success) {
560 IPCThreadState* ipc = IPCThreadState::self();
561 int32_t* uid = reinterpret_cast<int32_t*>(ipc->getCallingUid());
562 if (checkCallingPermission(String16(kPermissionDump),
563 reinterpret_cast<int32_t*>(ipc->getCallingPid()), uid)) {
564 string keyString = string(String8(key).string());
565 ConfigKey configKey(*uid, keyString);
566 StatsdConfig cfg;
567 cfg.ParseFromArray(&config[0], config.size());
568 mConfigManager->UpdateConfig(configKey, cfg);
569 mConfigManager->SetConfigReceiver(configKey, string(String8(package).string()),
570 string(String8(cls).string()));
571 *success = true;
572 return Status::ok();
573 } else {
574 return Status::fromExceptionCode(binder::Status::EX_SECURITY);
yro31eb67b2017-10-24 13:33:21 -0700575 }
yro31eb67b2017-10-24 13:33:21 -0700576}
577
David Chenadaf8b32017-11-03 15:42:08 -0700578Status StatsService::removeConfiguration(const String16& key, bool* success) {
579 IPCThreadState* ipc = IPCThreadState::self();
580 if (checkCallingPermission(String16(kPermissionDump),
581 reinterpret_cast<int32_t*>(ipc->getCallingPid()),
582 reinterpret_cast<int32_t*>(ipc->getCallingUid()))) {
583 // TODO: Implement this.
584 return Status::ok();
585 } else {
586 *success = false;
587 return Status::fromExceptionCode(binder::Status::EX_SECURITY);
yro31eb67b2017-10-24 13:33:21 -0700588 }
yro31eb67b2017-10-24 13:33:21 -0700589}
590
591void StatsService::binderDied(const wp<IBinder>& who) {
592 for (size_t i = 0; i < mCallbacks.size(); i++) {
593 if (IInterface::asBinder(mCallbacks[i]) == who) {
594 mCallbacks.removeAt(i);
595 break;
596 }
597 }
598}
599
Yao Chenef99c4f2017-09-22 16:26:54 -0700600} // namespace statsd
601} // namespace os
602} // namespace android