blob: edb1a0f94e2b45c889fd9ce7bb51597bc6841b93 [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{
Joe Onorato9fc9edf2017-10-15 20:08:52 -070068 mUidMap = new UidMap();
69 mConfigManager = new ConfigManager();
yro31eb67b2017-10-24 13:33:21 -070070 mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) {
71 pushLog(log);
72 });
Joe Onorato9fc9edf2017-10-15 20:08:52 -070073
74 mConfigManager->AddListener(mProcessor);
75
76 init_system_properties();
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070077}
78
Yao Chenef99c4f2017-09-22 16:26:54 -070079StatsService::~StatsService() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070080}
81
Joe Onorato9fc9edf2017-10-15 20:08:52 -070082void StatsService::init_system_properties() {
83 mEngBuild = false;
84 const prop_info* buildType = __system_property_find("ro.build.type");
85 if (buildType != NULL) {
86 __system_property_read_callback(buildType, init_build_type_callback, this);
87 }
David Chen0656b7a2017-09-13 15:53:39 -070088}
89
Joe Onorato9fc9edf2017-10-15 20:08:52 -070090void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
91 uint32_t serial) {
Yao Chen729093d2017-10-16 10:33:26 -070092 if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -070093 reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
94 }
95}
96
97/**
98 * Implement our own because the default binder implementation isn't
99 * properly handling SHELL_COMMAND_TRANSACTION.
100 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700101status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
102 uint32_t flags) {
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700103 status_t err;
104
105 switch (code) {
106 case SHELL_COMMAND_TRANSACTION: {
107 int in = data.readFileDescriptor();
108 int out = data.readFileDescriptor();
109 int err = data.readFileDescriptor();
110 int argc = data.readInt32();
111 Vector<String8> args;
112 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
113 args.add(String8(data.readString16()));
114 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700115 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
116 sp<IResultReceiver> resultReceiver =
117 IResultReceiver::asInterface(data.readStrongBinder());
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700118
119 FILE* fin = fdopen(in, "r");
120 FILE* fout = fdopen(out, "w");
121 FILE* ferr = fdopen(err, "w");
122
123 if (fin == NULL || fout == NULL || ferr == NULL) {
124 resultReceiver->send(NO_MEMORY);
125 } else {
126 err = command(fin, fout, ferr, args);
127 resultReceiver->send(err);
128 }
129
130 if (fin != NULL) {
131 fflush(fin);
132 fclose(fin);
133 }
134 if (fout != NULL) {
135 fflush(fout);
136 fclose(fout);
137 }
138 if (fout != NULL) {
139 fflush(ferr);
140 fclose(ferr);
141 }
142
143 return NO_ERROR;
144 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700145 default: { return BnStatsManager::onTransact(code, data, reply, flags); }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700146 }
147}
148
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700149/**
150 * Write debugging data about statsd.
151 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700152status_t StatsService::dump(int fd, const Vector<String16>& args) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700153 FILE* out = fdopen(fd, "w");
154 if (out == NULL) {
155 return NO_MEMORY; // the fd is already open
156 }
157
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700158 // TODO: Proto format for incident reports
159 dump_impl(out);
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700160
161 fclose(out);
162 return NO_ERROR;
163}
164
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700165/**
166 * Write debugging data about statsd in text format.
167 */
168void StatsService::dump_impl(FILE* out) {
169 mConfigManager->Dump(out);
170}
171
172/**
173 * Implementation of the adb shell cmd stats command.
174 */
Yao Chenef99c4f2017-09-22 16:26:54 -0700175status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700176 // TODO: Permission check
177
178 const int argCount = args.size();
179 if (argCount >= 1) {
180 // adb shell cmd stats config ...
David Chen0656b7a2017-09-13 15:53:39 -0700181 if (!args[0].compare(String8("config"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700182 return cmd_config(in, out, err, args);
David Chen0656b7a2017-09-13 15:53:39 -0700183 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700184
185 // adb shell cmd stats print-stats-log
186 if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) {
187 return cmd_print_stats_log(out, args);
188 }
189
David Chende701692017-10-05 13:16:02 -0700190 if (!args[0].compare(String8("print-uid-map"))) {
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700191 return cmd_print_uid_map(out);
David Chende701692017-10-05 13:16:02 -0700192 }
Yao Chen729093d2017-10-16 10:33:26 -0700193
194 if (!args[0].compare(String8("dump-report"))) {
195 return cmd_dump_report(out, err, args);
196 }
David Chen1481fe12017-10-16 13:16:34 -0700197
198 if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
199 return cmd_print_pulled_metrics(out, args);
200 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700201 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700202
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700203 print_cmd_help(out);
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700204 return NO_ERROR;
205}
206
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700207void StatsService::print_cmd_help(FILE* out) {
208 fprintf(out,
209 "usage: adb shell cmd stats print-stats-log [tag_required] "
210 "[timestamp_nsec_optional]\n");
211 fprintf(out, "\n");
212 fprintf(out, "\n");
213 fprintf(out, "usage: adb shell cmd stats print-uid-map \n");
214 fprintf(out, "\n");
215 fprintf(out, " Prints the UID, app name, version mapping.\n");
216 fprintf(out, "\n");
217 fprintf(out, "\n");
David Chen1481fe12017-10-16 13:16:34 -0700218 fprintf(out, "usage: adb shell cmds stats pull-source [int] \n");
219 fprintf(out, "\n");
220 fprintf(out, " Prints the output of a pulled metrics source (int indicates source)\n");
221 fprintf(out, "\n");
222 fprintf(out, "\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700223 fprintf(out, "usage: adb shell cmd stats config remove [UID] NAME\n");
224 fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
225 fprintf(out, "\n");
226 fprintf(out, " Adds, updates or removes a configuration. The proto should be in\n");
227 fprintf(out, " wire-encoded protobuf format and passed via stdin.\n");
228 fprintf(out, "\n");
229 fprintf(out, " UID The uid to use. It is only possible to pass the UID\n");
230 fprintf(out, " parameter on eng builds. If UID is omitted the calling\n");
231 fprintf(out, " uid is used.\n");
232 fprintf(out, " NAME The per-uid name to use\n");
Yao Chen5154a372017-10-30 22:57:06 -0700233 fprintf(out, "\n");
234 fprintf(out, "\n");
235 fprintf(out, "usage: adb shell cmd stats dump-report [UID] NAME\n");
236 fprintf(out, " Dump all metric data for a configuration.\n");
237 fprintf(out, " UID The uid of the configuration. It is only possible to pass\n");
238 fprintf(out, " the UID parameter on eng builds. If UID is omitted the\n");
239 fprintf(out, " calling uid is used.\n");
240 fprintf(out, " NAME The name of the configuration\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700241}
242
243status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
244 const int argCount = args.size();
245 if (argCount >= 2) {
246 if (args[1] == "update" || args[1] == "remove") {
247 bool good = false;
248 int uid = -1;
249 string name;
250
251 if (argCount == 3) {
252 // Automatically pick the UID
253 uid = IPCThreadState::self()->getCallingUid();
254 // TODO: What if this isn't a binder call? Should we fail?
255 name.assign(args[2].c_str(), args[2].size());
256 good = true;
257 } else if (argCount == 4) {
258 // If it's a userdebug or eng build, then the shell user can
259 // impersonate other uids.
260 if (mEngBuild) {
261 const char* s = args[2].c_str();
262 if (*s != '\0') {
263 char* end = NULL;
264 uid = strtol(s, &end, 0);
265 if (*end == '\0') {
266 name.assign(args[3].c_str(), args[3].size());
267 good = true;
268 }
269 }
270 } else {
Yao Chen729093d2017-10-16 10:33:26 -0700271 fprintf(err,
272 "The config can only be set for other UIDs on eng or userdebug "
273 "builds.\n");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700274 }
275 }
276
277 if (!good) {
278 // If arg parsing failed, print the help text and return an error.
279 print_cmd_help(out);
280 return UNKNOWN_ERROR;
281 }
282
283 if (args[1] == "update") {
284 // Read stream into buffer.
285 string buffer;
286 if (!android::base::ReadFdToString(fileno(in), &buffer)) {
287 fprintf(err, "Error reading stream for StatsConfig.\n");
288 return UNKNOWN_ERROR;
289 }
290
291 // Parse buffer.
292 StatsdConfig config;
293 if (!config.ParseFromString(buffer)) {
294 fprintf(err, "Error parsing proto stream for StatsConfig.\n");
295 return UNKNOWN_ERROR;
296 }
297
298 // Add / update the config.
299 mConfigManager->UpdateConfig(ConfigKey(uid, name), config);
300 } else {
301 // Remove the config.
302 mConfigManager->RemoveConfig(ConfigKey(uid, name));
303 }
304
305 return NO_ERROR;
306 }
David Chen0656b7a2017-09-13 15:53:39 -0700307 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700308 print_cmd_help(out);
309 return UNKNOWN_ERROR;
310}
311
Yao Chen729093d2017-10-16 10:33:26 -0700312status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String8>& args) {
313 if (mProcessor != nullptr) {
314 const int argCount = args.size();
315 bool good = false;
316 int uid;
317 string name;
318 if (argCount == 2) {
319 // Automatically pick the UID
320 uid = IPCThreadState::self()->getCallingUid();
321 // TODO: What if this isn't a binder call? Should we fail?
Yao Chen5154a372017-10-30 22:57:06 -0700322 name.assign(args[1].c_str(), args[1].size());
Yao Chen729093d2017-10-16 10:33:26 -0700323 good = true;
324 } else if (argCount == 3) {
325 // If it's a userdebug or eng build, then the shell user can
326 // impersonate other uids.
327 if (mEngBuild) {
328 const char* s = args[1].c_str();
329 if (*s != '\0') {
330 char* end = NULL;
331 uid = strtol(s, &end, 0);
332 if (*end == '\0') {
333 name.assign(args[2].c_str(), args[2].size());
334 good = true;
335 }
336 }
337 } else {
338 fprintf(out,
339 "The metrics can only be dumped for other UIDs on eng or userdebug "
340 "builds.\n");
341 }
342 }
343 if (good) {
344 mProcessor->onDumpReport(ConfigKey(uid, name));
345 // TODO: print the returned StatsLogReport to file instead of printing to logcat.
346 fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
347 fprintf(out, "See the StatsLogReport in logcat...\n");
348 return android::OK;
349 } else {
350 // If arg parsing failed, print the help text and return an error.
351 print_cmd_help(out);
352 return UNKNOWN_ERROR;
353 }
354 } else {
355 fprintf(out, "Log processor does not exist...\n");
356 return UNKNOWN_ERROR;
357 }
358}
359
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700360status_t StatsService::cmd_print_stats_log(FILE* out, const Vector<String8>& args) {
361 long msec = 0;
362
363 if (args.size() > 2) {
364 msec = strtol(args[2].string(), NULL, 10);
David Chen0656b7a2017-09-13 15:53:39 -0700365 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700366 return DropboxReader::readStatsLogs(out, args[1].string(), msec);
367}
368
369status_t StatsService::cmd_print_uid_map(FILE* out) {
370 mUidMap->printUidMap(out);
371 return NO_ERROR;
David Chen0656b7a2017-09-13 15:53:39 -0700372}
373
David Chen1481fe12017-10-16 13:16:34 -0700374status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) {
375 int s = atoi(args[1].c_str());
Chenjie Yub3dda412017-10-24 13:41:59 -0700376 auto stats = m_stats_puller_manager.Pull(s, time(nullptr));
David Chen1481fe12017-10-16 13:16:34 -0700377 for (const auto& it : stats) {
378 fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
379 }
380 fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
381 return NO_ERROR;
382}
383
David Chende701692017-10-05 13:16:02 -0700384Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int32_t>& version,
385 const vector<String16>& app) {
386 if (DEBUG) ALOGD("StatsService::informAllUidData was called");
387
388 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
389 return Status::fromExceptionCode(Status::EX_SECURITY,
390 "Only system uid can call informAllUidData");
391 }
392
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700393 mUidMap->updateMap(uid, version, app);
David Chende701692017-10-05 13:16:02 -0700394 if (DEBUG) ALOGD("StatsService::informAllUidData succeeded");
395
396 return Status::ok();
397}
398
399Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t version) {
400 if (DEBUG) ALOGD("StatsService::informOnePackage was called");
401
402 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
403 return Status::fromExceptionCode(Status::EX_SECURITY,
404 "Only system uid can call informOnePackage");
405 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700406 mUidMap->updateApp(app, uid, version);
David Chende701692017-10-05 13:16:02 -0700407 return Status::ok();
408}
409
410Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
411 if (DEBUG) ALOGD("StatsService::informOnePackageRemoved was called");
412
413 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
414 return Status::fromExceptionCode(Status::EX_SECURITY,
415 "Only system uid can call informOnePackageRemoved");
416 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700417 mUidMap->removeApp(app, uid);
David Chende701692017-10-05 13:16:02 -0700418 return Status::ok();
419}
420
Yao Chenef99c4f2017-09-22 16:26:54 -0700421Status StatsService::informAnomalyAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700422 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700423
424 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
425 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700426 "Only system uid can call informAnomalyAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700427 }
428
Bookatzb487b552017-09-18 11:26:01 -0700429 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700430 // TODO: check through all counters/timers and see if an anomaly has indeed occurred.
431
432 return Status::ok();
433}
434
Yao Chenef99c4f2017-09-22 16:26:54 -0700435Status StatsService::informPollAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700436 if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700437
438 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
439 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700440 "Only system uid can call informPollAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700441 }
442
Chenjie Yub3dda412017-10-24 13:41:59 -0700443 m_stats_puller_manager.OnAlarmFired();
444
Bookatzb487b552017-09-18 11:26:01 -0700445 if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700446
447 return Status::ok();
448}
449
Yao Chenef99c4f2017-09-22 16:26:54 -0700450Status StatsService::systemRunning() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700451 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
452 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700453 "Only system uid can call systemRunning");
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700454 }
455
456 // When system_server is up and running, schedule the dropbox task to run.
457 ALOGD("StatsService::systemRunning");
458
Bookatzb487b552017-09-18 11:26:01 -0700459 sayHiToStatsCompanion();
460
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700461 return Status::ok();
462}
463
Yao Chenef99c4f2017-09-22 16:26:54 -0700464void StatsService::sayHiToStatsCompanion() {
465 // TODO: This method needs to be private. It is temporarily public and unsecured for testing
466 // purposes.
Bookatzb487b552017-09-18 11:26:01 -0700467 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
468 if (statsCompanion != nullptr) {
469 if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
470 statsCompanion->statsdReady();
471 } else {
472 if (DEBUG) ALOGD("Could not access statsCompanion");
473 }
474}
475
Yao Chenef99c4f2017-09-22 16:26:54 -0700476sp<IStatsCompanionService> StatsService::getStatsCompanionService() {
Bookatz906a35c2017-09-20 15:26:44 -0700477 sp<IStatsCompanionService> statsCompanion = nullptr;
478 // Get statscompanion service from service manager
479 const sp<IServiceManager> sm(defaultServiceManager());
480 if (sm != nullptr) {
481 const String16 name("statscompanion");
482 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
483 if (statsCompanion == nullptr) {
484 ALOGW("statscompanion service unavailable!");
485 return nullptr;
486 }
487 }
488 return statsCompanion;
489}
490
Yao Chenef99c4f2017-09-22 16:26:54 -0700491Status StatsService::statsCompanionReady() {
Bookatzb487b552017-09-18 11:26:01 -0700492 if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");
493
494 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
495 return Status::fromExceptionCode(Status::EX_SECURITY,
496 "Only system uid can call statsCompanionReady");
497 }
498
499 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
500 if (statsCompanion == nullptr) {
Yao Chenef99c4f2017-09-22 16:26:54 -0700501 return Status::fromExceptionCode(
502 Status::EX_NULL_POINTER,
503 "statscompanion unavailable despite it contacting statsd!");
Bookatzb487b552017-09-18 11:26:01 -0700504 }
505 if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700506 IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor));
Bookatzb487b552017-09-18 11:26:01 -0700507 mAnomalyMonitor->setStatsCompanionService(statsCompanion);
508
509 return Status::ok();
510}
511
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700512void StatsService::Startup() {
513 mConfigManager->Startup();
Bookatz906a35c2017-09-20 15:26:44 -0700514}
515
Joe Onoratoc4dfae52017-10-17 23:38:21 -0700516void StatsService::OnLogEvent(const LogEvent& event) {
517 mProcessor->OnLogEvent(event);
Bookatz906a35c2017-09-20 15:26:44 -0700518}
519
yro31eb67b2017-10-24 13:33:21 -0700520Status StatsService::requestPush() {
521 mProcessor->flush();
522 return Status::ok();
523}
524
525Status StatsService::pushLog(const vector<uint8_t>& log) {
526 std::lock_guard<std::mutex> lock(mLock);
527 for (size_t i = 0; i < mCallbacks.size(); i++) {
528 mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log);
529 }
530 return Status::ok();
531}
532
533Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) {
534 std::lock_guard<std::mutex> lock(mLock);
535 for (size_t i = 0; i < mCallbacks.size(); i++) {
536 if (mCallbacks[i] == callback) {
537 return Status::fromStatusT(-errno);
538 }
539 }
540 mCallbacks.add(callback);
541 IInterface::asBinder(callback)->linkToDeath(this);
542 return Status::ok();
543}
544
545void StatsService::binderDied(const wp<IBinder>& who) {
546 for (size_t i = 0; i < mCallbacks.size(); i++) {
547 if (IInterface::asBinder(mCallbacks[i]) == who) {
548 mCallbacks.removeAt(i);
549 break;
550 }
551 }
552}
553
Yao Chenef99c4f2017-09-22 16:26:54 -0700554} // namespace statsd
555} // namespace os
556} // namespace android