blob: 1faeee0a65541993e2ea1baf42c65c67ad01e6ae [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();
71 mProcessor = new StatsLogProcessor(mUidMap);
72
73 mConfigManager->AddListener(mProcessor);
74
75 init_system_properties();
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070076}
77
Yao Chenef99c4f2017-09-22 16:26:54 -070078StatsService::~StatsService() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070079}
80
Joe Onorato9fc9edf2017-10-15 20:08:52 -070081void StatsService::init_system_properties() {
82 mEngBuild = false;
83 const prop_info* buildType = __system_property_find("ro.build.type");
84 if (buildType != NULL) {
85 __system_property_read_callback(buildType, init_build_type_callback, this);
86 }
David Chen0656b7a2017-09-13 15:53:39 -070087}
88
Joe Onorato9fc9edf2017-10-15 20:08:52 -070089void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
90 uint32_t serial) {
Yao Chen729093d2017-10-16 10:33:26 -070091 if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -070092 reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
93 }
94}
95
96/**
97 * Implement our own because the default binder implementation isn't
98 * properly handling SHELL_COMMAND_TRANSACTION.
99 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700100status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
101 uint32_t flags) {
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700102 status_t err;
103
104 switch (code) {
105 case SHELL_COMMAND_TRANSACTION: {
106 int in = data.readFileDescriptor();
107 int out = data.readFileDescriptor();
108 int err = data.readFileDescriptor();
109 int argc = data.readInt32();
110 Vector<String8> args;
111 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
112 args.add(String8(data.readString16()));
113 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700114 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
115 sp<IResultReceiver> resultReceiver =
116 IResultReceiver::asInterface(data.readStrongBinder());
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700117
118 FILE* fin = fdopen(in, "r");
119 FILE* fout = fdopen(out, "w");
120 FILE* ferr = fdopen(err, "w");
121
122 if (fin == NULL || fout == NULL || ferr == NULL) {
123 resultReceiver->send(NO_MEMORY);
124 } else {
125 err = command(fin, fout, ferr, args);
126 resultReceiver->send(err);
127 }
128
129 if (fin != NULL) {
130 fflush(fin);
131 fclose(fin);
132 }
133 if (fout != NULL) {
134 fflush(fout);
135 fclose(fout);
136 }
137 if (fout != NULL) {
138 fflush(ferr);
139 fclose(ferr);
140 }
141
142 return NO_ERROR;
143 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700144 default: { return BnStatsManager::onTransact(code, data, reply, flags); }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700145 }
146}
147
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700148/**
149 * Write debugging data about statsd.
150 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700151status_t StatsService::dump(int fd, const Vector<String16>& args) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700152 FILE* out = fdopen(fd, "w");
153 if (out == NULL) {
154 return NO_MEMORY; // the fd is already open
155 }
156
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700157 // TODO: Proto format for incident reports
158 dump_impl(out);
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700159
160 fclose(out);
161 return NO_ERROR;
162}
163
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700164/**
165 * Write debugging data about statsd in text format.
166 */
167void StatsService::dump_impl(FILE* out) {
168 mConfigManager->Dump(out);
169}
170
171/**
172 * Implementation of the adb shell cmd stats command.
173 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700174status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700175 // TODO: Permission check
176
177 const int argCount = args.size();
178 if (argCount >= 1) {
179 // adb shell cmd stats config ...
David Chen0656b7a2017-09-13 15:53:39 -0700180 if (!args[0].compare(String8("config"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700181 return cmd_config(in, out, err, args);
David Chen0656b7a2017-09-13 15:53:39 -0700182 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700183
184 // adb shell cmd stats print-stats-log
185 if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) {
186 return cmd_print_stats_log(out, args);
187 }
188
David Chende701692017-10-05 13:16:02 -0700189 if (!args[0].compare(String8("print-uid-map"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700190 return cmd_print_uid_map(out);
David Chende701692017-10-05 13:16:02 -0700191 }
Yao Chen729093d2017-10-16 10:33:26 -0700192
193 if (!args[0].compare(String8("dump-report"))) {
194 return cmd_dump_report(out, err, args);
195 }
David Chen1481fe12017-10-16 13:16:34 -0700196
197 if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
198 return cmd_print_pulled_metrics(out, args);
199 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700200 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700201
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700202 print_cmd_help(out);
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700203 return NO_ERROR;
204}
205
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700206void StatsService::print_cmd_help(FILE* out) {
207 fprintf(out,
208 "usage: adb shell cmd stats print-stats-log [tag_required] "
209 "[timestamp_nsec_optional]\n");
210 fprintf(out, "\n");
211 fprintf(out, "\n");
212 fprintf(out, "usage: adb shell cmd stats print-uid-map \n");
213 fprintf(out, "\n");
214 fprintf(out, " Prints the UID, app name, version mapping.\n");
215 fprintf(out, "\n");
216 fprintf(out, "\n");
David Chen1481fe12017-10-16 13:16:34 -0700217 fprintf(out, "usage: adb shell cmds stats pull-source [int] \n");
218 fprintf(out, "\n");
219 fprintf(out, " Prints the output of a pulled metrics source (int indicates source)\n");
220 fprintf(out, "\n");
221 fprintf(out, "\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700222 fprintf(out, "usage: adb shell cmd stats config remove [UID] NAME\n");
223 fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
224 fprintf(out, "\n");
225 fprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
226 fprintf(out, " wire-encoded protobuf format and passed via stdin.\n");
227 fprintf(out, "\n");
228 fprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
229 fprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
230 fprintf(out, " uid is used.\n");
231 fprintf(out, " NAME The per-uid name to use\n");
232}
233
234status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
235 const int argCount = args.size();
236 if (argCount >= 2) {
237 if (args[1] == "update" || args[1] == "remove") {
238 bool good = false;
239 int uid = -1;
240 string name;
241
242 if (argCount == 3) {
243 // Automatically pick the UID
244 uid = IPCThreadState::self()->getCallingUid();
245 // TODO: What if this isn't a binder call? Should we fail?
246 name.assign(args[2].c_str(), args[2].size());
247 good = true;
248 } else if (argCount == 4) {
249 // If it's a userdebug or eng build, then the shell user can
250 // impersonate other uids.
251 if (mEngBuild) {
252 const char* s = args[2].c_str();
253 if (*s != '\0') {
254 char* end = NULL;
255 uid = strtol(s, &end, 0);
256 if (*end == '\0') {
257 name.assign(args[3].c_str(), args[3].size());
258 good = true;
259 }
260 }
261 } else {
Yao Chen729093d2017-10-16 10:33:26 -0700262 fprintf(err,
263 "The config can only be set for other UIDs on eng or userdebug "
264 "builds.\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700265 }
266 }
267
268 if (!good) {
269 // If arg parsing failed, print the help text and return an error.
270 print_cmd_help(out);
271 return UNKNOWN_ERROR;
272 }
273
274 if (args[1] == "update") {
275 // Read stream into buffer.
276 string buffer;
277 if (!android::base::ReadFdToString(fileno(in), &buffer)) {
278 fprintf(err, "Error reading stream for StatsConfig.\n");
279 return UNKNOWN_ERROR;
280 }
281
282 // Parse buffer.
283 StatsdConfig config;
284 if (!config.ParseFromString(buffer)) {
285 fprintf(err, "Error parsing proto stream for StatsConfig.\n");
286 return UNKNOWN_ERROR;
287 }
288
289 // Add / update the config.
290 mConfigManager->UpdateConfig(ConfigKey(uid, name), config);
291 } else {
292 // Remove the config.
293 mConfigManager->RemoveConfig(ConfigKey(uid, name));
294 }
295
296 return NO_ERROR;
297 }
David Chen0656b7a2017-09-13 15:53:39 -0700298 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700299 print_cmd_help(out);
300 return UNKNOWN_ERROR;
301}
302
Yao Chen729093d2017-10-16 10:33:26 -0700303status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
304 if (mProcessor != nullptr) {
305 const int argCount = args.size();
306 bool good = false;
307 int uid;
308 string name;
309 if (argCount == 2) {
310 // Automatically pick the UID
311 uid = IPCThreadState::self()->getCallingUid();
312 // TODO: What if this isn't a binder call? Should we fail?
313 name.assign(args[2].c_str(), args[2].size());
314 good = true;
315 } else if (argCount == 3) {
316 // If it's a userdebug or eng build, then the shell user can
317 // impersonate other uids.
318 if (mEngBuild) {
319 const char* s = args[1].c_str();
320 if (*s != '\0') {
321 char* end = NULL;
322 uid = strtol(s, &end, 0);
323 if (*end == '\0') {
324 name.assign(args[2].c_str(), args[2].size());
325 good = true;
326 }
327 }
328 } else {
329 fprintf(out,
330 "The metrics can only be dumped for other UIDs on eng or userdebug "
331 "builds.\n");
332 }
333 }
334 if (good) {
335 mProcessor->onDumpReport(ConfigKey(uid, name));
336 // TODO: print the returned StatsLogReport to file instead of printing to logcat.
337 fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
338 fprintf(out, "See the StatsLogReport in logcat...\n");
339 return android::OK;
340 } else {
341 // If arg parsing failed, print the help text and return an error.
342 print_cmd_help(out);
343 return UNKNOWN_ERROR;
344 }
345 } else {
346 fprintf(out, "Log processor does not exist...\n");
347 return UNKNOWN_ERROR;
348 }
349}
350
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700351status_t StatsService::cmd_print_stats_log(FILE* out, const Vector<String8>& args) {
352 long msec = 0;
353
354 if (args.size() > 2) {
355 msec = strtol(args[2].string(), NULL, 10);
David Chen0656b7a2017-09-13 15:53:39 -0700356 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700357 return DropboxReader::readStatsLogs(out, args[1].string(), msec);
358}
359
360status_t StatsService::cmd_print_uid_map(FILE* out) {
361 mUidMap->printUidMap(out);
362 return NO_ERROR;
David Chen0656b7a2017-09-13 15:53:39 -0700363}
364
David Chen1481fe12017-10-16 13:16:34 -0700365status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
366 int s = atoi(args[1].c_str());
367 auto stats = mStatsPullerManager->Pull(s);
368 for (const auto& it : stats) {
369 fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
370 }
371 fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
372 return NO_ERROR;
373}
374
David Chende701692017-10-05 13:16:02 -0700375Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
376 const vector<String16>& app) {
377 if (DEBUG) ALOGD("StatsService::informAllUidData was called");
378
379 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
380 return Status::fromExceptionCode(Status::EX_SECURITY,
381 "Only system uid can call informAllUidData");
382 }
383
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700384 mUidMap->updateMap(uid, version, app);
David Chende701692017-10-05 13:16:02 -0700385 if (DEBUG) ALOGD("StatsService::informAllUidData succeeded");
386
387 return Status::ok();
388}
389
390Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t version) {
391 if (DEBUG) ALOGD("StatsService::informOnePackage was called");
392
393 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
394 return Status::fromExceptionCode(Status::EX_SECURITY,
395 "Only system uid can call informOnePackage");
396 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700397 mUidMap->updateApp(app, uid, version);
David Chende701692017-10-05 13:16:02 -0700398 return Status::ok();
399}
400
401Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
402 if (DEBUG) ALOGD("StatsService::informOnePackageRemoved was called");
403
404 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
405 return Status::fromExceptionCode(Status::EX_SECURITY,
406 "Only system uid can call informOnePackageRemoved");
407 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700408 mUidMap->removeApp(app, uid);
David Chende701692017-10-05 13:16:02 -0700409 return Status::ok();
410}
411
Yao Chenef99c4f2017-09-22 16:26:54 -0700412Status StatsService::informAnomalyAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700413 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700414
415 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
416 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700417 "Only system uid can call informAnomalyAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700418 }
419
Bookatzb487b552017-09-18 11:26:01 -0700420 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700421 // TODO: check through all counters/timers and see if an anomaly has indeed occurred.
422
423 return Status::ok();
424}
425
Yao Chenef99c4f2017-09-22 16:26:54 -0700426Status StatsService::informPollAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700427 if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700428
429 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
430 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700431 "Only system uid can call informPollAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700432 }
433
Bookatzb487b552017-09-18 11:26:01 -0700434 if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700435 // TODO: determine what services to poll and poll (or ask StatsCompanionService to poll) them.
436
437 return Status::ok();
438}
439
Yao Chenef99c4f2017-09-22 16:26:54 -0700440Status StatsService::systemRunning() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700441 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
442 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700443 "Only system uid can call systemRunning");
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700444 }
445
446 // When system_server is up and running, schedule the dropbox task to run.
447 ALOGD("StatsService::systemRunning");
448
Bookatzb487b552017-09-18 11:26:01 -0700449 sayHiToStatsCompanion();
450
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700451 return Status::ok();
452}
453
Yao Chenef99c4f2017-09-22 16:26:54 -0700454void StatsService::sayHiToStatsCompanion() {
455 // TODO: This method needs to be private. It is temporarily public and unsecured for testing
456 // purposes.
Bookatzb487b552017-09-18 11:26:01 -0700457 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
458 if (statsCompanion != nullptr) {
459 if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
460 statsCompanion->statsdReady();
461 } else {
462 if (DEBUG) ALOGD("Could not access statsCompanion");
463 }
464}
465
Yao Chenef99c4f2017-09-22 16:26:54 -0700466sp<IStatsCompanionService> StatsService::getStatsCompanionService() {
Bookatz906a35c2017-09-20 15:26:44 -0700467 sp<IStatsCompanionService> statsCompanion = nullptr;
468 // Get statscompanion service from service manager
469 const sp<IServiceManager> sm(defaultServiceManager());
470 if (sm != nullptr) {
471 const String16 name("statscompanion");
472 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
473 if (statsCompanion == nullptr) {
474 ALOGW("statscompanion service unavailable!");
475 return nullptr;
476 }
477 }
478 return statsCompanion;
479}
480
Yao Chenef99c4f2017-09-22 16:26:54 -0700481Status StatsService::statsCompanionReady() {
Bookatzb487b552017-09-18 11:26:01 -0700482 if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");
483
484 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
485 return Status::fromExceptionCode(Status::EX_SECURITY,
486 "Only system uid can call statsCompanionReady");
487 }
488
489 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
490 if (statsCompanion == nullptr) {
Yao Chenef99c4f2017-09-22 16:26:54 -0700491 return Status::fromExceptionCode(
492 Status::EX_NULL_POINTER,
493 "statscompanion unavailable despite it contacting statsd!");
Bookatzb487b552017-09-18 11:26:01 -0700494 }
495 if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700496 IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor));
Bookatzb487b552017-09-18 11:26:01 -0700497 mAnomalyMonitor->setStatsCompanionService(statsCompanion);
498
499 return Status::ok();
500}
501
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700502void StatsService::Startup() {
503 mConfigManager->Startup();
Bookatz906a35c2017-09-20 15:26:44 -0700504}
505
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700506void StatsService::OnLogEvent(const LogEvent& event) {
507 mProcessor->OnLogEvent(event);
Bookatz906a35c2017-09-20 15:26:44 -0700508}
509
Yao Chenef99c4f2017-09-22 16:26:54 -0700510} // namespace statsd
511} // namespace os
512} // namespace android