blob: 9baeebbd554fbfb8225a7a82527bcef4af4ca053 [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
17#define LOG_TAG "statsd"
Bookatzb487b552017-09-18 11:26:01 -070018#define DEBUG true
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070019
20#include "StatsService.h"
Yao Chen482d2722017-09-12 13:25:43 -070021#include "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>
26#include <cutils/log.h>
David Chen0656b7a2017-09-13 15:53:39 -070027#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070028#include <private/android_filesystem_config.h>
29#include <utils/Looper.h>
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070030#include <utils/String16.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070031
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070032#include <stdio.h>
Yao Chen482d2722017-09-12 13:25:43 -070033#include <stdlib.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 Onorato5dcbc6c2017-08-29 15:13:58 -070042StatsService::StatsService(const sp<Looper>& handlerLooper)
Chenjie Yu1a317ba2017-10-05 16:05:32 -070043 : mAnomalyMonitor(new AnomalyMonitor(2)), mStatsPullerManager() // TODO: Change this based on the config
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070044{
45 ALOGD("stats service constructed");
46}
47
Yao Chenef99c4f2017-09-22 16:26:54 -070048StatsService::~StatsService() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070049}
50
Yao Chenef99c4f2017-09-22 16:26:54 -070051status_t StatsService::setProcessor(const sp<StatsLogProcessor>& main_processor) {
David Chen0656b7a2017-09-13 15:53:39 -070052 m_processor = main_processor;
53 ALOGD("stats service set to processor %p", m_processor.get());
54 return NO_ERROR;
55}
56
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070057// Implement our own because the default binder implementation isn't
58// properly handling SHELL_COMMAND_TRANSACTION
Yao Chenef99c4f2017-09-22 16:26:54 -070059status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
60 uint32_t flags) {
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070061 status_t err;
62
63 switch (code) {
64 case SHELL_COMMAND_TRANSACTION: {
65 int in = data.readFileDescriptor();
66 int out = data.readFileDescriptor();
67 int err = data.readFileDescriptor();
68 int argc = data.readInt32();
69 Vector<String8> args;
70 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
71 args.add(String8(data.readString16()));
72 }
Yao Chenef99c4f2017-09-22 16:26:54 -070073 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
74 sp<IResultReceiver> resultReceiver =
75 IResultReceiver::asInterface(data.readStrongBinder());
Joe Onorato2cbc2cc2017-08-30 17:03:23 -070076
77 FILE* fin = fdopen(in, "r");
78 FILE* fout = fdopen(out, "w");
79 FILE* ferr = fdopen(err, "w");
80
81 if (fin == NULL || fout == NULL || ferr == NULL) {
82 resultReceiver->send(NO_MEMORY);
83 } else {
84 err = command(fin, fout, ferr, args);
85 resultReceiver->send(err);
86 }
87
88 if (fin != NULL) {
89 fflush(fin);
90 fclose(fin);
91 }
92 if (fout != NULL) {
93 fflush(fout);
94 fclose(fout);
95 }
96 if (fout != NULL) {
97 fflush(ferr);
98 fclose(ferr);
99 }
100
101 return NO_ERROR;
102 }
Yao Chenef99c4f2017-09-22 16:26:54 -0700103 default: { return BnStatsManager::onTransact(code, data, reply, flags); }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700104 }
105}
106
Yao Chenef99c4f2017-09-22 16:26:54 -0700107status_t StatsService::dump(int fd, const Vector<String16>& args) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700108 FILE* out = fdopen(fd, "w");
109 if (out == NULL) {
110 return NO_MEMORY; // the fd is already open
111 }
112
113 fprintf(out, "StatsService::dump:");
114 ALOGD("StatsService::dump:");
115 const int N = args.size();
Yao Chenef99c4f2017-09-22 16:26:54 -0700116 for (int i = 0; i < N; i++) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700117 fprintf(out, " %s", String8(args[i]).string());
118 ALOGD(" %s", String8(args[i]).string());
119 }
120 fprintf(out, "\n");
121
122 fclose(out);
123 return NO_ERROR;
124}
125
Yao Chenef99c4f2017-09-22 16:26:54 -0700126status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Yao Chen482d2722017-09-12 13:25:43 -0700127 if (args.size() > 0) {
128 if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) {
129 return doPrintStatsLog(out, args);
130 }
David Chen0656b7a2017-09-13 15:53:39 -0700131 if (!args[0].compare(String8("config"))) {
132 return doLoadConfig(in);
133 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700134 }
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700135
Yao Chen482d2722017-09-12 13:25:43 -0700136 printCmdHelp(out);
Joe Onorato2cbc2cc2017-08-30 17:03:23 -0700137 return NO_ERROR;
138}
139
Yao Chenef99c4f2017-09-22 16:26:54 -0700140status_t StatsService::doLoadConfig(FILE* in) {
David Chen0656b7a2017-09-13 15:53:39 -0700141 string content;
142 if (!android::base::ReadFdToString(fileno(in), &content)) {
143 return UNKNOWN_ERROR;
144 }
145 StatsdConfig config;
146 if (config.ParseFromString(content)) {
147 ALOGD("Config parsed from command line: %s", config.SerializeAsString().c_str());
148 m_processor->UpdateConfig(0, config);
149 return NO_ERROR;
150 } else {
151 ALOGD("Config failed to be parsed");
152 return UNKNOWN_ERROR;
153 }
154}
155
Yao Chenef99c4f2017-09-22 16:26:54 -0700156Status StatsService::informAnomalyAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700157 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700158
159 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
160 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700161 "Only system uid can call informAnomalyAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700162 }
163
Bookatzb487b552017-09-18 11:26:01 -0700164 if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700165 // TODO: check through all counters/timers and see if an anomaly has indeed occurred.
166
167 return Status::ok();
168}
169
Yao Chenef99c4f2017-09-22 16:26:54 -0700170Status StatsService::informPollAlarmFired() {
Bookatzb487b552017-09-18 11:26:01 -0700171 if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");
Bookatz1b0b1142017-09-08 11:58:42 -0700172
173 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
174 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700175 "Only system uid can call informPollAlarmFired");
Bookatz1b0b1142017-09-08 11:58:42 -0700176 }
177
Bookatzb487b552017-09-18 11:26:01 -0700178 if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
Bookatz1b0b1142017-09-08 11:58:42 -0700179 // TODO: determine what services to poll and poll (or ask StatsCompanionService to poll) them.
Chenjie Yu1a317ba2017-10-05 16:05:32 -0700180 String16 output = mStatsPullerManager.pull(StatsPullerManager::KERNEL_WAKELOCKS);
Bookatzc68a9d22017-09-27 14:09:55 -0700181 // TODO: do something useful with the output instead of writing a string to screen.
182 ALOGD("%s", String8(output).string());
Chenjie Yu1a317ba2017-10-05 16:05:32 -0700183 ALOGD("%d", int(output.size()));
Bookatz1b0b1142017-09-08 11:58:42 -0700184
185 return Status::ok();
186}
187
Yao Chenef99c4f2017-09-22 16:26:54 -0700188Status StatsService::systemRunning() {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700189 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
190 return Status::fromExceptionCode(Status::EX_SECURITY,
Yao Chenef99c4f2017-09-22 16:26:54 -0700191 "Only system uid can call systemRunning");
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700192 }
193
194 // When system_server is up and running, schedule the dropbox task to run.
195 ALOGD("StatsService::systemRunning");
196
Bookatzb487b552017-09-18 11:26:01 -0700197 sayHiToStatsCompanion();
198
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700199 return Status::ok();
200}
201
Yao Chenef99c4f2017-09-22 16:26:54 -0700202void StatsService::sayHiToStatsCompanion() {
203 // TODO: This method needs to be private. It is temporarily public and unsecured for testing
204 // purposes.
Bookatzb487b552017-09-18 11:26:01 -0700205 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
206 if (statsCompanion != nullptr) {
207 if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
208 statsCompanion->statsdReady();
209 } else {
210 if (DEBUG) ALOGD("Could not access statsCompanion");
211 }
212}
213
Yao Chenef99c4f2017-09-22 16:26:54 -0700214sp<IStatsCompanionService> StatsService::getStatsCompanionService() {
Bookatz906a35c2017-09-20 15:26:44 -0700215 sp<IStatsCompanionService> statsCompanion = nullptr;
216 // Get statscompanion service from service manager
217 const sp<IServiceManager> sm(defaultServiceManager());
218 if (sm != nullptr) {
219 const String16 name("statscompanion");
220 statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
221 if (statsCompanion == nullptr) {
222 ALOGW("statscompanion service unavailable!");
223 return nullptr;
224 }
225 }
226 return statsCompanion;
227}
228
Yao Chenef99c4f2017-09-22 16:26:54 -0700229Status StatsService::statsCompanionReady() {
Bookatzb487b552017-09-18 11:26:01 -0700230 if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");
231
232 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
233 return Status::fromExceptionCode(Status::EX_SECURITY,
234 "Only system uid can call statsCompanionReady");
235 }
236
237 sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
238 if (statsCompanion == nullptr) {
Yao Chenef99c4f2017-09-22 16:26:54 -0700239 return Status::fromExceptionCode(
240 Status::EX_NULL_POINTER,
241 "statscompanion unavailable despite it contacting statsd!");
Bookatzb487b552017-09-18 11:26:01 -0700242 }
243 if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
244 IInterface::asBinder(statsCompanion)->linkToDeath(new StatsdDeathRecipient(mAnomalyMonitor));
245 mAnomalyMonitor->setStatsCompanionService(statsCompanion);
246
247 return Status::ok();
248}
249
Yao Chenef99c4f2017-09-22 16:26:54 -0700250void StatsdDeathRecipient::binderDied(const wp<IBinder>& who) {
Bookatzb487b552017-09-18 11:26:01 -0700251 ALOGW("statscompanion service died");
252 mAnmlyMntr->setStatsCompanionService(nullptr);
Bookatz906a35c2017-09-20 15:26:44 -0700253}
254
Yao Chenef99c4f2017-09-22 16:26:54 -0700255status_t StatsService::doPrintStatsLog(FILE* out, const Vector<String8>& args) {
Bookatz906a35c2017-09-20 15:26:44 -0700256 long msec = 0;
257
258 if (args.size() > 2) {
259 msec = strtol(args[2].string(), NULL, 10);
260 }
261 return DropboxReader::readStatsLogs(out, args[1].string(), msec);
262}
263
Yao Chenef99c4f2017-09-22 16:26:54 -0700264void StatsService::printCmdHelp(FILE* out) {
Bookatz906a35c2017-09-20 15:26:44 -0700265 fprintf(out, "Usage:\n");
266 fprintf(out, "\t print-stats-log [tag_required] [timestamp_nsec_optional]\n");
Yao Chenef99c4f2017-09-22 16:26:54 -0700267 fprintf(out,
268 "\t config\t Loads a new config from command-line (must be proto in wire-encoded "
269 "format).\n");
Bookatz906a35c2017-09-20 15:26:44 -0700270}
271
Yao Chenef99c4f2017-09-22 16:26:54 -0700272} // namespace statsd
273} // namespace os
274} // namespace android