blob: 604753ef54a002cd3ecbb9b97714d1214fdeedd3 [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"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070021#include "storage/DropboxReader.h"
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070022
David Chen0656b7a2017-09-13 15:53:39 -070023#include <android-base/file.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070024#include <binder/IPCThreadState.h>
25#include <binder/IServiceManager.h>
David Chen0656b7a2017-09-13 15:53:39 -070026#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070027#include <private/android_filesystem_config.h>
28#include <utils/Looper.h>
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070029#include <utils/String16.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070030
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070031#include <stdio.h>
Yao Chen482d2722017-09-12 13:25:43 -070032#include <stdlib.h>
Joe Onorato9fc9edf2017-10-15 20:08:52 -070033#include <sys/system_properties.h>
Yao Chenef99c4f2017-09-22 16:26:54 -070034#include <unistd.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070035
36using namespace android;
37
Bookatz906a35c2017-09-20 15:26:44 -070038namespace android {
39namespace os {
40namespace statsd {
41
Joe Onorato9fc9edf2017-10-15 20:08:52 -070042// ======================================================================
43/**
44 * Watches for the death of the stats companion (system process).
45 */
46class CompanionDeathRecipient : public IBinder::DeathRecipient {
47public:
48 CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor);
49 virtual void binderDied(const wp<IBinder>& who);
50
51private:
52 const sp<AnomalyMonitor> mAnomalyMonitor;
53};
54
55CompanionDeathRecipient::CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor)
56 : mAnomalyMonitor(anomalyMonitor) {
57}
58
59void CompanionDeathRecipient::binderDied(const wp<IBinder>& who) {
60 ALOGW("statscompanion service died");
61 mAnomalyMonitor->setStatsCompanionService(nullptr);
62}
63
64// ======================================================================
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070065StatsService::StatsService(const sp<Looper>& handlerLooper)
David Chen1481fe12017-10-16 13:16:34 -070066 : mAnomalyMonitor(new AnomalyMonitor(2)) // TODO: Put this comment somewhere better
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070067{
David Chen1481fe12017-10-16 13:16:34 -070068 mStatsPullerManager = new StatsPullerManager();
Joe Onorato9fc9edf2017-10-15 20:08:52 -070069 mUidMap = new UidMap();
70 mConfigManager = new ConfigManager();
yro31eb67b2017-10-24 13:33:21 -070071 mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) {
72 pushLog(log);
73 });
Joe Onorato9fc9edf2017-10-15 20:08:52 -070074
75 mConfigManager->AddListener(mProcessor);
76
77 init_system_properties();
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070078}
79
Yao Chenef99c4f2017-09-22 16:26:54 -070080StatsService::~StatsService() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070081}
82
Joe Onorato9fc9edf2017-10-15 20:08:52 -070083void StatsService::init_system_properties() {
84 mEngBuild = false;
85 const prop_info* buildType = __system_property_find("ro.build.type");
86 if (buildType != NULL) {
87 __system_property_read_callback(buildType, init_build_type_callback, this);
88 }
David Chen0656b7a2017-09-13 15:53:39 -070089}
90
Joe Onorato9fc9edf2017-10-15 20:08:52 -070091void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
92 uint32_t serial) {
Yao Chen729093d2017-10-16 10:33:26 -070093 if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -070094 reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
95 }
96}
97
98/**
99 * Implement our own because the default binder implementation isn't
100 * properly handling SHELL_COMMAND_TRANSACTION.
101 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700102status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
103 uint32_t flags) {
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700104 status_t err;
105
106 switch (code) {
107 case SHELL_COMMAND_TRANSACTION: {
108 int in = data.readFileDescriptor();
109 int out = data.readFileDescriptor();
110 int err = data.readFileDescriptor();
111 int argc = data.readInt32();
112 Vector<String8> args;
113 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
114 args.add(String8(data.readString16()));
115 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700116 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
117 sp<IResultReceiver> resultReceiver =
118 IResultReceiver::asInterface(data.readStrongBinder());
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700119
120 FILE* fin = fdopen(in, "r");
121 FILE* fout = fdopen(out, "w");
122 FILE* ferr = fdopen(err, "w");
123
124 if (fin == NULL || fout == NULL || ferr == NULL) {
125 resultReceiver->send(NO_MEMORY);
126 } else {
127 err = command(fin, fout, ferr, args);
128 resultReceiver->send(err);
129 }
130
131 if (fin != NULL) {
132 fflush(fin);
133 fclose(fin);
134 }
135 if (fout != NULL) {
136 fflush(fout);
137 fclose(fout);
138 }
139 if (fout != NULL) {
140 fflush(ferr);
141 fclose(ferr);
142 }
143
144 return NO_ERROR;
145 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700146 default: { return BnStatsManager::onTransact(code, data, reply, flags); }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700147 }
148}
149
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700150/**
151 * Write debugging data about statsd.
152 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700153status_t StatsService::dump(int fd, const Vector<String16>& args) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700154 FILE* out = fdopen(fd, "w");
155 if (out == NULL) {
156 return NO_MEMORY; // the fd is already open
157 }
158
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700159 // TODO: Proto format for incident reports
160 dump_impl(out);
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700161
162 fclose(out);
163 return NO_ERROR;
164}
165
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700166/**
167 * Write debugging data about statsd in text format.
168 */
169void StatsService::dump_impl(FILE* out) {
170 mConfigManager->Dump(out);
171}
172
173/**
174 * Implementation of the adb shell cmd stats command.
175 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700176status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700177 // TODO: Permission check
178
179 const int argCount = args.size();
180 if (argCount >= 1) {
181 // adb shell cmd stats config ...
David Chen0656b7a2017-09-13 15:53:39 -0700182 if (!args[0].compare(String8("config"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700183 return cmd_config(in, out, err, args);
David Chen0656b7a2017-09-13 15:53:39 -0700184 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700185
186 // adb shell cmd stats print-stats-log
187 if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) {
188 return cmd_print_stats_log(out, args);
189 }
190
David Chende701692017-10-05 13:16:02 -0700191 if (!args[0].compare(String8("print-uid-map"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700192 return cmd_print_uid_map(out);
David Chende701692017-10-05 13:16:02 -0700193 }
Yao Chen729093d2017-10-16 10:33:26 -0700194
195 if (!args[0].compare(String8("dump-report"))) {
196 return cmd_dump_report(out, err, args);
197 }
David Chen1481fe12017-10-16 13:16:34 -0700198
199 if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
200 return cmd_print_pulled_metrics(out, args);
201 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700202 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700203
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700204 print_cmd_help(out);
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700205 return NO_ERROR;
206}
207
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700208void StatsService::print_cmd_help(FILE* out) {
209 fprintf(out,
210 "usage: adb shell cmd stats print-stats-log [tag_required] "
211 "[timestamp_nsec_optional]\n");
212 fprintf(out, "\n");
213 fprintf(out, "\n");
214 fprintf(out, "usage: adb shell cmd stats print-uid-map \n");
215 fprintf(out, "\n");
216 fprintf(out, " Prints the UID, app name, version mapping.\n");
217 fprintf(out, "\n");
218 fprintf(out, "\n");
David Chen1481fe12017-10-16 13:16:34 -0700219 fprintf(out, "usage: adb shell cmds stats pull-source [int] \n");
220 fprintf(out, "\n");
221 fprintf(out, " Prints the output of a pulled metrics source (int indicates source)\n");
222 fprintf(out, "\n");
223 fprintf(out, "\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700224 fprintf(out, "usage: adb shell cmd stats config remove [UID] NAME\n");
225 fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
226 fprintf(out, "\n");
227 fprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
228 fprintf(out, " wire-encoded protobuf format and passed via stdin.\n");
229 fprintf(out, "\n");
230 fprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
231 fprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
232 fprintf(out, " uid is used.\n");
233 fprintf(out, " NAME The per-uid name to use\n");
234}
235
236status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
237 const int argCount = args.size();
238 if (argCount >= 2) {
239 if (args[1] == "update" || args[1] == "remove") {
240 bool good = false;
241 int uid = -1;
242 string name;
243
244 if (argCount == 3) {
245 // Automatically pick the UID
246 uid = IPCThreadState::self()->getCallingUid();
247 // TODO: What if this isn't a binder call? Should we fail?
248 name.assign(args[2].c_str(), args[2].size());
249 good = true;
250 } else if (argCount == 4) {
251 // If it's a userdebug or eng build, then the shell user can
252 // impersonate other uids.
253 if (mEngBuild) {
254 const char* s = args[2].c_str();
255 if (*s != '\0') {
256 char* end = NULL;
257 uid = strtol(s, &end, 0);
258 if (*end == '\0') {
259 name.assign(args[3].c_str(), args[3].size());
260 good = true;
261 }
262 }
263 } else {
Yao Chen729093d2017-10-16 10:33:26 -0700264 fprintf(err,
265 "The config can only be set for other UIDs on eng or userdebug "
266 "builds.\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700267 }
268 }
269
270 if (!good) {
271 // If arg parsing failed, print the help text and return an error.
272 print_cmd_help(out);
273 return UNKNOWN_ERROR;
274 }
275
276 if (args[1] == "update") {
277 // Read stream into buffer.
278 string buffer;
279 if (!android::base::ReadFdToString(fileno(in), &buffer)) {
280 fprintf(err, "Error reading stream for StatsConfig.\n");
281 return UNKNOWN_ERROR;
282 }
283
284 // Parse buffer.
285 StatsdConfig config;
286 if (!config.ParseFromString(buffer)) {
287 fprintf(err, "Error parsing proto stream for StatsConfig.\n");
288 return UNKNOWN_ERROR;
289 }
290
291 // Add / update the config.
292 mConfigManager->UpdateConfig(ConfigKey(uid, name), config);
293 } else {
294 // Remove the config.
295 mConfigManager->RemoveConfig(ConfigKey(uid, name));
296 }
297
298 return NO_ERROR;
299 }
David Chen0656b7a2017-09-13 15:53:39 -0700300 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700301 print_cmd_help(out);
302 return UNKNOWN_ERROR;
303}
304
Yao Chen729093d2017-10-16 10:33:26 -0700305status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
306 if (mProcessor != nullptr) {
307 const int argCount = args.size();
308 bool good = false;
309 int uid;
310 string name;
311 if (argCount == 2) {
312 // Automatically pick the UID
313 uid = IPCThreadState::self()->getCallingUid();
314 // TODO: What if this isn't a binder call? Should we fail?
315 name.assign(args[2].c_str(), args[2].size());
316 good = true;
317 } else if (argCount == 3) {
318 // If it's a userdebug or eng build, then the shell user can
319 // impersonate other uids.
320 if (mEngBuild) {
321 const char* s = args[1].c_str();
322 if (*s != '\0') {
323 char* end = NULL;
324 uid = strtol(s, &end, 0);
325 if (*end == '\0') {
326 name.assign(args[2].c_str(), args[2].size());
327 good = true;
328 }
329 }
330 } else {
331 fprintf(out,
332 "The metrics can only be dumped for other UIDs on eng or userdebug "
333 "builds.\n");
334 }
335 }
336 if (good) {
337 mProcessor->onDumpReport(ConfigKey(uid, name));
338 // TODO: print the returned StatsLogReport to file instead of printing to logcat.
339 fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
340 fprintf(out, "See the StatsLogReport in logcat...\n");
341 return android::OK;
342 } else {
343 // If arg parsing failed, print the help text and return an error.
344 print_cmd_help(out);
345 return UNKNOWN_ERROR;
346 }
347 } else {
348 fprintf(out, "Log processor does not exist...\n");
349 return UNKNOWN_ERROR;
350 }
351}
352
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700353status_t StatsService::cmd_print_stats_log(FILE* out, const Vector<String8>& args) {
354 long msec = 0;
355
356 if (args.size() > 2) {
357 msec = strtol(args[2].string(), NULL, 10);
David Chen0656b7a2017-09-13 15:53:39 -0700358 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700359 return DropboxReader::readStatsLogs(out, args[1].string(), msec);
360}
361
362status_t StatsService::cmd_print_uid_map(FILE* out) {
363 mUidMap->printUidMap(out);
364 return NO_ERROR;
David Chen0656b7a2017-09-13 15:53:39 -0700365}
366
David Chen1481fe12017-10-16 13:16:34 -0700367status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
368 int s = atoi(args[1].c_str());
369 auto stats = mStatsPullerManager->Pull(s);
370 for (const auto& it : stats) {
371 fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
372 }
373 fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
374 return NO_ERROR;
375}
376
David Chende701692017-10-05 13:16:02 -0700377Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
378 const vector<String16>& app) {
379 if (DEBUG) ALOGD("StatsService::informAllUidData was called");
380
381 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
382 return Status::fromExceptionCode(Status::EX_SECURITY,
383 "Only system uid can call informAllUidData");
384 }
385
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700386 mUidMap->updateMap(uid, version, app);
David Chende701692017-10-05 13:16:02 -0700387 if (DEBUG) ALOGD("StatsService::informAllUidData succeeded");
388
389 return Status::ok();
390}
391
392Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t version) {
393 if (DEBUG) ALOGD("StatsService::informOnePackage was called");
394
395 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
396 return Status::fromExceptionCode(Status::EX_SECURITY,
397 "Only system uid can call informOnePackage");
398 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700399 mUidMap->updateApp(app, uid, version);
David Chende701692017-10-05 13:16:02 -0700400 return Status::ok();
401}
402
403Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
404 if (DEBUG) ALOGD("StatsService::informOnePackageRemoved was called");
405
406 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
407 return Status::fromExceptionCode(Status::EX_SECURITY,
408 "Only system uid can call informOnePackageRemoved");
409 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700410 mUidMap->removeApp(app, uid);
David Chende701692017-10-05 13:16:02 -0700411 return Status::ok();
412}
413
Yao Chenef99c4f2017-09-22 16:26:54 -0700414Status StatsService::informAnomalyAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700415 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700416
417 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
418 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700419 "Only system uid can call informAnomalyAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700420 }
421
Bookatzb487b552017-09-18 11:26:01 -0700422 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700423 // TODO: check through all counters/timers and see if an anomaly has indeed occurred.
424
425 return Status::ok();
426}
427
Yao Chenef99c4f2017-09-22 16:26:54 -0700428Status StatsService::informPollAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700429 if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700430
431 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
432 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700433 "Only system uid can call informPollAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700434 }
435
Bookatzb487b552017-09-18 11:26:01 -0700436 if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700437 // TODO: determine what services to poll and poll (or ask StatsCompanionService to poll) them.
438
439 return Status::ok();
440}
441
Yao Chenef99c4f2017-09-22 16:26:54 -0700442Status StatsService::systemRunning() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700443 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
444 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700445 "Only system uid can call systemRunning");
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700446 }
447
448 // When system_server is up and running, schedule the dropbox task to run.
449 ALOGD("StatsService::systemRunning");
450
Bookatzb487b552017-09-18 11:26:01 -0700451 sayHiToStatsCompanion();
452
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700453 return Status::ok();
454}
455
Yao Chenef99c4f2017-09-22 16:26:54 -0700456void StatsService::sayHiToStatsCompanion() {
457 // TODO: This method needs to be private. It is temporarily public and unsecured for testing
458 // purposes.
Bookatzb487b552017-09-18 11:26:01 -0700459 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
460 if (statsCompanion != nullptr) {
461 if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
462 statsCompanion->statsdReady();
463 } else {
464 if (DEBUG) ALOGD("Could not access statsCompanion");
465 }
466}
467
Yao Chenef99c4f2017-09-22 16:26:54 -0700468sp<IStatsCompanionService> StatsService::getStatsCompanionService() {
Bookatz906a35c2017-09-20 15:26:44 -0700469 sp<IStatsCompanionService> statsCompanion = nullptr;
470 // Get statscompanion service from service manager
471 const sp<IServiceManager> sm(defaultServiceManager());
472 if (sm != nullptr) {
473 const String16 name("statscompanion");
474 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
475 if (statsCompanion == nullptr) {
476 ALOGW("statscompanion service unavailable!");
477 return nullptr;
478 }
479 }
480 return statsCompanion;
481}
482
Yao Chenef99c4f2017-09-22 16:26:54 -0700483Status StatsService::statsCompanionReady() {
Bookatzb487b552017-09-18 11:26:01 -0700484 if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");
485
486 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
487 return Status::fromExceptionCode(Status::EX_SECURITY,
488 "Only system uid can call statsCompanionReady");
489 }
490
491 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
492 if (statsCompanion == nullptr) {
Yao Chenef99c4f2017-09-22 16:26:54 -0700493 return Status::fromExceptionCode(
494 Status::EX_NULL_POINTER,
495 "statscompanion unavailable despite it contacting statsd!");
Bookatzb487b552017-09-18 11:26:01 -0700496 }
497 if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700498 IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor));
Bookatzb487b552017-09-18 11:26:01 -0700499 mAnomalyMonitor->setStatsCompanionService(statsCompanion);
500
501 return Status::ok();
502}
503
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700504void StatsService::Startup() {
505 mConfigManager->Startup();
Bookatz906a35c2017-09-20 15:26:44 -0700506}
507
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700508void StatsService::OnLogEvent(const LogEvent& event) {
509 mProcessor->OnLogEvent(event);
Bookatz906a35c2017-09-20 15:26:44 -0700510}
511
yro31eb67b2017-10-24 13:33:21 -0700512Status StatsService::requestPush() {
513 mProcessor->flush();
514 return Status::ok();
515}
516
517Status StatsService::pushLog(const vector<uint8_t>& log) {
518 std::lock_guard<std::mutex> lock(mLock);
519 for (size_t i = 0; i < mCallbacks.size(); i++) {
520 mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log);
521 }
522 return Status::ok();
523}
524
525Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) {
526 std::lock_guard<std::mutex> lock(mLock);
527 for (size_t i = 0; i < mCallbacks.size(); i++) {
528 if (mCallbacks[i] == callback) {
529 return Status::fromStatusT(-errno);
530 }
531 }
532 mCallbacks.add(callback);
533 IInterface::asBinder(callback)->linkToDeath(this);
534 return Status::ok();
535}
536
537void StatsService::binderDied(const wp<IBinder>& who) {
538 for (size_t i = 0; i < mCallbacks.size(); i++) {
539 if (IInterface::asBinder(mCallbacks[i]) == who) {
540 mCallbacks.removeAt(i);
541 break;
542 }
543 }
544}
545
Yao Chenef99c4f2017-09-22 16:26:54 -0700546} // namespace statsd
547} // namespace os
548} // namespace android