blob: b4021d1b2f7643502590068904b1f974fa043b9a [file] [log] [blame]
Joe Onorato1754d742016-11-21 17:51:35 -08001/*
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 */
Yi Jin4e843102018-02-14 15:36:18 -080016#define DEBUG false
Yi Jinb592e3b2018-02-01 15:17:04 -080017#include "Log.h"
Joe Onorato1754d742016-11-21 17:51:35 -080018
19#include "IncidentService.h"
20
Yi Jinb592e3b2018-02-01 15:17:04 -080021#include "FdBuffer.h"
Joe Onorato99598ee2019-02-11 15:55:13 +000022#include "PrivacyFilter.h"
Joe Onorato1754d742016-11-21 17:51:35 -080023#include "Reporter.h"
Yi Jinb592e3b2018-02-01 15:17:04 -080024#include "incidentd_util.h"
25#include "section_list.h"
Joe Onorato1754d742016-11-21 17:51:35 -080026
Mike Ma85434ec2018-11-27 10:32:31 -080027#include <android/os/IncidentReportArgs.h>
Joe Onorato1754d742016-11-21 17:51:35 -080028#include <binder/IPCThreadState.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080029#include <binder/IResultReceiver.h>
Joe Onorato1754d742016-11-21 17:51:35 -080030#include <binder/IServiceManager.h>
Yi Jinb592e3b2018-02-01 15:17:04 -080031#include <binder/IShellCallback.h>
Mike Ma35056662018-12-06 13:32:59 -080032#include <log/log.h>
Joe Onorato1754d742016-11-21 17:51:35 -080033#include <private/android_filesystem_config.h>
34#include <utils/Looper.h>
Yao Chencbafce92019-04-01 15:56:44 -070035#include <thread>
Joe Onorato1754d742016-11-21 17:51:35 -080036
37#include <unistd.h>
38
Joe Onorato99598ee2019-02-11 15:55:13 +000039enum {
40 WHAT_TAKE_REPORT = 1,
41 WHAT_SEND_BROADCASTS = 2
42};
Joe Onorato1754d742016-11-21 17:51:35 -080043
Joe Onorato99598ee2019-02-11 15:55:13 +000044#define DEFAULT_DELAY_NS (1000000000LL)
Joe Onorato1754d742016-11-21 17:51:35 -080045
Yi Jin4e843102018-02-14 15:36:18 -080046#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
47#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
48
Mike Ma28381692018-12-04 15:46:29 -080049// Skip these sections for dumpstate only. Dumpstate allows 10s max for each service to dump.
50// Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
51// Skip 3018 because it takes too long.
Mike Ma85434ec2018-11-27 10:32:31 -080052#define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
53 1200, 1201, 1202, /* Native, hal, java traces */ \
Mike Ma85434ec2018-11-27 10:32:31 -080054 3018 /* "meminfo -a --proto" */ }
55
Yi Jin6cacbcb2018-03-30 14:04:52 -070056namespace android {
57namespace os {
58namespace incidentd {
59
Joe Onorato99598ee2019-02-11 15:55:13 +000060String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS");
Joe Onorato1754d742016-11-21 17:51:35 -080061String16 const DUMP_PERMISSION("android.permission.DUMP");
62String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
63
Yi Jinb592e3b2018-02-01 15:17:04 -080064static Status checkIncidentPermissions(const IncidentReportArgs& args) {
Yi Jin437aa6e2018-01-10 11:34:26 -080065 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Yi Jinafb36062018-01-31 19:14:25 -080066 pid_t callingPid = IPCThreadState::self()->getCallingPid();
Yi Jin437aa6e2018-01-10 11:34:26 -080067 if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
Joe Onorato99598ee2019-02-11 15:55:13 +000068 // Root and shell are ok.
69 return Status::ok();
70 }
71
72 if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) {
73 // Permission controller (this is a singleton permission that is always granted
74 // exactly for PermissionController) is allowed to access incident reports
75 // so it can show the user info about what they are approving.
Yi Jin437aa6e2018-01-10 11:34:26 -080076 return Status::ok();
77 }
78
Yi Jin4bab3a12018-01-10 16:50:59 -080079 // checking calling permission.
Joe Onorato1754d742016-11-21 17:51:35 -080080 if (!checkCallingPermission(DUMP_PERMISSION)) {
81 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
Yi Jinb592e3b2018-02-01 15:17:04 -080082 callingPid, callingUid);
83 return Status::fromExceptionCode(
84 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080085 "Calling process does not have permission: android.permission.DUMP");
86 }
87 if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
88 ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
Yi Jinb592e3b2018-02-01 15:17:04 -080089 callingPid, callingUid);
90 return Status::fromExceptionCode(
91 Status::EX_SECURITY,
Joe Onorato1754d742016-11-21 17:51:35 -080092 "Calling process does not have permission: android.permission.USAGE_STATS");
93 }
Yi Jin4bab3a12018-01-10 16:50:59 -080094
95 // checking calling request uid permission.
Joe Onorato99598ee2019-02-11 15:55:13 +000096 switch (args.getPrivacyPolicy()) {
97 case PRIVACY_POLICY_LOCAL:
Yi Jinafb36062018-01-31 19:14:25 -080098 if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
99 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800100 callingPid, callingUid);
101 return Status::fromExceptionCode(
102 Status::EX_SECURITY,
103 "Calling process does not have permission to get local data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800104 }
Bookatzda9b8d02018-11-14 13:14:45 -0800105 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000106 case PRIVACY_POLICY_EXPLICIT:
Yi Jinb592e3b2018-02-01 15:17:04 -0800107 if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
Bookatzda9b8d02018-11-14 13:14:45 -0800108 callingUid != AID_SYSTEM) {
Yi Jinafb36062018-01-31 19:14:25 -0800109 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
Yi Jinb592e3b2018-02-01 15:17:04 -0800110 callingPid, callingUid);
111 return Status::fromExceptionCode(
112 Status::EX_SECURITY,
113 "Calling process does not have permission to get explicit data.");
Yi Jin4bab3a12018-01-10 16:50:59 -0800114 }
Bookatzda9b8d02018-11-14 13:14:45 -0800115 break;
Yi Jin4bab3a12018-01-10 16:50:59 -0800116 }
Joe Onorato1754d742016-11-21 17:51:35 -0800117 return Status::ok();
118}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700119
Joe Onorato99598ee2019-02-11 15:55:13 +0000120static string build_uri(const string& pkg, const string& cls, const string& id) {
Yao Chencbafce92019-04-01 15:56:44 -0700121 return "content://android.os.IncidentManager/pending?pkg="
122 + pkg + "&receiver=" + cls + "&r=" + id;
Joe Onorato1754d742016-11-21 17:51:35 -0800123}
124
Joe Onorato1754d742016-11-21 17:51:35 -0800125// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000126ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory,
127 const sp<Broadcaster>& broadcaster, const sp<Looper>& handlerLooper,
128 const sp<Throttler>& throttler)
129 :mLock(),
130 mWorkDirectory(workDirectory),
131 mBroadcaster(broadcaster),
132 mHandlerLooper(handlerLooper),
133 mBacklogDelay(DEFAULT_DELAY_NS),
134 mThrottler(throttler),
135 mBatch(new ReportBatch()) {
136}
Joe Onorato1754d742016-11-21 17:51:35 -0800137
Joe Onorato99598ee2019-02-11 15:55:13 +0000138ReportHandler::~ReportHandler() {
139}
Joe Onorato1754d742016-11-21 17:51:35 -0800140
Yi Jinb592e3b2018-02-01 15:17:04 -0800141void ReportHandler::handleMessage(const Message& message) {
Joe Onorato1754d742016-11-21 17:51:35 -0800142 switch (message.what) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000143 case WHAT_TAKE_REPORT:
144 take_report();
Joe Onorato1754d742016-11-21 17:51:35 -0800145 break;
Joe Onorato99598ee2019-02-11 15:55:13 +0000146 case WHAT_SEND_BROADCASTS:
147 send_broadcasts();
Joe Onorato1754d742016-11-21 17:51:35 -0800148 break;
149 }
150}
151
Joe Onorato99598ee2019-02-11 15:55:13 +0000152void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) {
153 mBatch->addPersistedReport(args);
154 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
155 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
Joe Onorato1754d742016-11-21 17:51:35 -0800156}
157
Joe Onorato99598ee2019-02-11 15:55:13 +0000158void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args,
159 const sp<IIncidentReportStatusListener>& listener, int streamFd) {
160 mBatch->addStreamingReport(args, listener, streamFd);
161 mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
162 mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
163}
164
165void ReportHandler::scheduleSendBacklog() {
Joe Onorato1754d742016-11-21 17:51:35 -0800166 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000167 mBacklogDelay = DEFAULT_DELAY_NS;
168 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800169}
170
Joe Onorato99598ee2019-02-11 15:55:13 +0000171void ReportHandler::schedule_send_broadcasts_locked() {
172 mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS);
173 mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS));
Joe Onorato1754d742016-11-21 17:51:35 -0800174}
175
Joe Onorato99598ee2019-02-11 15:55:13 +0000176void ReportHandler::take_report() {
177 // Cycle the batch
178 sp<ReportBatch> batch;
179 {
180 unique_lock<mutex> lock(mLock);
181 batch = mBatch;
182 mBatch = new ReportBatch();
Joe Onorato1754d742016-11-21 17:51:35 -0800183 }
184
Joe Onorato99598ee2019-02-11 15:55:13 +0000185 if (batch->empty()) {
186 // Nothing to do.
187 return;
188 }
189
190 sp<Reporter> reporter = new Reporter(mWorkDirectory, batch);
191
192 // TODO: Do we really want to clear the reports if we throttle? Should we only throttle
193 // requests going to dropbox? How do we reconcile throttling with testing?
Yi Jin4e843102018-02-14 15:36:18 -0800194 if (mThrottler->shouldThrottle()) {
195 ALOGW("RunReport got throttled.");
196 return;
197 }
198
Joe Onorato1754d742016-11-21 17:51:35 -0800199 // Take the report, which might take a while. More requests might queue
200 // up while we're doing this, and we'll handle them in their next batch.
201 // TODO: We should further rate-limit the reports to no more than N per time-period.
Joe Onorato99598ee2019-02-11 15:55:13 +0000202 // TODO: Move this inside reporter.
Yi Jin4e843102018-02-14 15:36:18 -0800203 size_t reportByteSize = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000204 reporter->runReport(&reportByteSize);
205
Yi Jin4e843102018-02-14 15:36:18 -0800206 mThrottler->addReportSize(reportByteSize);
Joe Onorato99598ee2019-02-11 15:55:13 +0000207
208 // Kick off the next steps, one of which is to send any new or otherwise remaining
209 // approvals, and one of which is to send any new or remaining broadcasts.
210 {
Joe Onorato1754d742016-11-21 17:51:35 -0800211 unique_lock<mutex> lock(mLock);
Joe Onorato99598ee2019-02-11 15:55:13 +0000212 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800213 }
214}
215
Joe Onorato99598ee2019-02-11 15:55:13 +0000216void ReportHandler::send_broadcasts() {
217 Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts();
218 if (result == Broadcaster::BROADCASTS_FINISHED) {
219 // We're done.
220 unique_lock<mutex> lock(mLock);
221 mBacklogDelay = DEFAULT_DELAY_NS;
222 } else if (result == Broadcaster::BROADCASTS_REPEAT) {
223 // It worked, but there are more.
224 unique_lock<mutex> lock(mLock);
225 mBacklogDelay = DEFAULT_DELAY_NS;
226 schedule_send_broadcasts_locked();
227 } else if (result == Broadcaster::BROADCASTS_BACKOFF) {
Joe Onorato1754d742016-11-21 17:51:35 -0800228 // There was a failure. Exponential backoff.
229 unique_lock<mutex> lock(mLock);
230 mBacklogDelay *= 2;
231 ALOGI("Error sending to dropbox. Trying again in %lld minutes",
Yi Jinb592e3b2018-02-01 15:17:04 -0800232 (mBacklogDelay / (1000000000LL * 60)));
Joe Onorato99598ee2019-02-11 15:55:13 +0000233 schedule_send_broadcasts_locked();
Joe Onorato1754d742016-11-21 17:51:35 -0800234 }
235}
236
237// ================================================================================
Joe Onorato99598ee2019-02-11 15:55:13 +0000238IncidentService::IncidentService(const sp<Looper>& handlerLooper) {
239 mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS);
240 mWorkDirectory = new WorkDirectory();
241 mBroadcaster = new Broadcaster(mWorkDirectory);
242 mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper,
243 mThrottler);
244 mBroadcaster->setHandler(mHandler);
Joe Onorato1754d742016-11-21 17:51:35 -0800245}
246
Yi Jinb592e3b2018-02-01 15:17:04 -0800247IncidentService::~IncidentService() {}
Joe Onorato1754d742016-11-21 17:51:35 -0800248
Yi Jinb592e3b2018-02-01 15:17:04 -0800249Status IncidentService::reportIncident(const IncidentReportArgs& args) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000250 // TODO: Validate that the privacy policy is one of the real ones.
251 // If it isn't, clamp it to the next more restrictive real one.
Joe Onorato1754d742016-11-21 17:51:35 -0800252
Joe Onorato99598ee2019-02-11 15:55:13 +0000253 // TODO: This function should reject the LOCAL privacy policy.
254 // Those have to stream.
255
256 // TODO: Check that the broadcast recevier has the proper permissions
257 // TODO: Maybe we should consider relaxing the permissions if it's going to
258 // dropbox, but definitely not if it's going to the broadcaster.
Yi Jin4bab3a12018-01-10 16:50:59 -0800259 Status status = checkIncidentPermissions(args);
Joe Onorato1754d742016-11-21 17:51:35 -0800260 if (!status.isOk()) {
261 return status;
262 }
263
Joe Onorato99598ee2019-02-11 15:55:13 +0000264 // If they didn't specify a component, use dropbox.
265 IncidentReportArgs argsCopy(args);
266 if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) {
267 argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName());
268 argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName());
269 }
270
271 mHandler->schedulePersistedReport(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800272
273 return Status::ok();
274}
275
Yi Jinb592e3b2018-02-01 15:17:04 -0800276Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
277 const sp<IIncidentReportStatusListener>& listener,
278 const unique_fd& stream) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000279 // TODO: Validate that the privacy policy is one of the real ones.
280 // If it isn't, clamp it to the next more restrictive real one.
Joe Onorato1754d742016-11-21 17:51:35 -0800281
Joe Onorato99598ee2019-02-11 15:55:13 +0000282 // TODO: Only shell should be able to do a LOCAL privacy policy report.
283
284 // Streaming reports can not also be broadcast.
285 IncidentReportArgs argsCopy(args);
286 argsCopy.setReceiverPkg("");
287 argsCopy.setReceiverCls("");
288
289 Status status = checkIncidentPermissions(argsCopy);
Joe Onorato1754d742016-11-21 17:51:35 -0800290 if (!status.isOk()) {
291 return status;
292 }
293
Joe Onorato99598ee2019-02-11 15:55:13 +0000294
295 // The ReportRequest takes ownership of the fd, so we need to dup it.
Joe Onorato1754d742016-11-21 17:51:35 -0800296 int fd = dup(stream.get());
297 if (fd < 0) {
298 return Status::fromStatusT(-errno);
299 }
300
Joe Onorato99598ee2019-02-11 15:55:13 +0000301 mHandler->scheduleStreamingReport(argsCopy, listener, fd);
Joe Onorato1754d742016-11-21 17:51:35 -0800302
303 return Status::ok();
304}
305
Yi Jinb592e3b2018-02-01 15:17:04 -0800306Status IncidentService::systemRunning() {
Joe Onorato1754d742016-11-21 17:51:35 -0800307 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
308 return Status::fromExceptionCode(Status::EX_SECURITY,
Yi Jinb592e3b2018-02-01 15:17:04 -0800309 "Only system uid can call systemRunning");
Joe Onorato1754d742016-11-21 17:51:35 -0800310 }
Yi Jinadd11e92017-07-30 16:10:07 -0700311
Joe Onorato1754d742016-11-21 17:51:35 -0800312 // When system_server is up and running, schedule the dropbox task to run.
Joe Onorato99598ee2019-02-11 15:55:13 +0000313 mBroadcaster->reset();
314 mHandler->scheduleSendBacklog();
315
316 return Status::ok();
317}
318
319Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16,
320 vector<String16>* result) {
321 status_t err;
322 const string pkg(String8(pkg16).string());
323 const string cls(String8(cls16).string());
324
325 // List the reports
326 vector<sp<ReportFile>> all;
327 err = mWorkDirectory->getReports(&all, 0);
328 if (err != NO_ERROR) {
329 return Status::fromStatusT(err);
330 }
331
332 // Find the ones that match pkg and cls.
333 for (sp<ReportFile>& file: all) {
334 err = file->loadEnvelope();
335 if (err != NO_ERROR) {
336 continue;
337 }
338 const ReportFileProto& envelope = file->getEnvelope();
339 size_t reportCount = envelope.report_size();
340 for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
341 const ReportFileProto_Report& report = envelope.report(reportIndex);
342 if (pkg == report.pkg() && cls == report.cls()) {
343 result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str()));
344 break;
345 }
346 }
347 }
348
349 return Status::ok();
350}
351
352Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16,
353 const String16& id16, IncidentManager::IncidentReport* result) {
354 status_t err;
355
356 const string pkg(String8(pkg16).string());
357 const string cls(String8(cls16).string());
358 const string id(String8(id16).string());
359
360 IncidentReportArgs args;
361 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args);
362 if (file != nullptr) {
Yao Chencbafce92019-04-01 15:56:44 -0700363 // Create pipe
364 int fds[2];
365 if (pipe(fds) != 0) {
366 ALOGW("Error opening pipe to filter incident report: %s",
367 file->getDataFileName().c_str());
Joe Onorato99598ee2019-02-11 15:55:13 +0000368 return Status::ok();
369 }
Joe Onorato99598ee2019-02-11 15:55:13 +0000370 result->setTimestampNs(file->getTimestampNs());
371 result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
Yao Chencbafce92019-04-01 15:56:44 -0700372 result->takeFileDescriptor(fds[0]);
373 int writeFd = fds[1];
374 // spawn a thread to write the data. Release the writeFd ownership to the thread.
375 thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
376
377 th.detach();
Joe Onorato99598ee2019-02-11 15:55:13 +0000378 }
379
380 return Status::ok();
381}
382
383Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16,
384 const String16& id16) {
385 const string pkg(String8(pkg16).string());
386 const string cls(String8(cls16).string());
387 const string id(String8(id16).string());
388
389 sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, nullptr);
390 if (file != nullptr) {
391 mWorkDirectory->commit(file, pkg, cls);
392 }
393 mBroadcaster->clearBroadcasts(pkg, cls, id);
394
395 return Status::ok();
396}
397
398Status IncidentService::deleteAllIncidentReports(const String16& pkg16) {
399 const string pkg(String8(pkg16).string());
400
401 mWorkDirectory->commitAll(pkg);
402 mBroadcaster->clearPackageBroadcasts(pkg);
Joe Onorato1754d742016-11-21 17:51:35 -0800403
404 return Status::ok();
405}
406
Yi Jinb592e3b2018-02-01 15:17:04 -0800407/**
408 * Implement our own because the default binder implementation isn't
409 * properly handling SHELL_COMMAND_TRANSACTION.
410 */
411status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
412 uint32_t flags) {
413 status_t err;
414
415 switch (code) {
416 case SHELL_COMMAND_TRANSACTION: {
417 int in = data.readFileDescriptor();
418 int out = data.readFileDescriptor();
419 int err = data.readFileDescriptor();
420 int argc = data.readInt32();
421 Vector<String8> args;
422 for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
423 args.add(String8(data.readString16()));
424 }
425 sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
426 sp<IResultReceiver> resultReceiver =
427 IResultReceiver::asInterface(data.readStrongBinder());
428
429 FILE* fin = fdopen(in, "r");
430 FILE* fout = fdopen(out, "w");
431 FILE* ferr = fdopen(err, "w");
432
433 if (fin == NULL || fout == NULL || ferr == NULL) {
434 resultReceiver->send(NO_MEMORY);
435 } else {
436 err = command(fin, fout, ferr, args);
437 resultReceiver->send(err);
438 }
439
440 if (fin != NULL) {
441 fflush(fin);
442 fclose(fin);
443 }
444 if (fout != NULL) {
445 fflush(fout);
446 fclose(fout);
447 }
448 if (fout != NULL) {
449 fflush(ferr);
450 fclose(ferr);
451 }
452
453 return NO_ERROR;
Bookatzda9b8d02018-11-14 13:14:45 -0800454 } break;
Yi Jinb592e3b2018-02-01 15:17:04 -0800455 default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
456 }
457}
458
459status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
460 const int argCount = args.size();
461
462 if (argCount >= 1) {
463 if (!args[0].compare(String8("privacy"))) {
464 return cmd_privacy(in, out, err, args);
465 }
Yi Jin4e843102018-02-14 15:36:18 -0800466 if (!args[0].compare(String8("throttler"))) {
467 mThrottler->dump(out);
468 return NO_ERROR;
469 }
Yi Jin908c02f2018-06-22 16:51:40 -0700470 if (!args[0].compare(String8("section"))) {
471 int id = atoi(args[1]);
472 int idx = 0;
473 while (SECTION_LIST[idx] != NULL) {
474 const Section* section = SECTION_LIST[idx];
475 if (section->id == id) {
476 fprintf(out, "Section[%d] %s\n", id, section->name.string());
477 break;
478 }
479 idx++;
480 }
481 return NO_ERROR;
482 }
Yi Jinb592e3b2018-02-01 15:17:04 -0800483 }
484 return cmd_help(out);
485}
486
487status_t IncidentService::cmd_help(FILE* out) {
488 fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
489 fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
Yi Jin908c02f2018-06-22 16:51:40 -0700490 fprintf(out, " Prints/parses for the section id.\n\n");
491 fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
492 fprintf(out, " Prints section id and its name.\n\n");
Yi Jin4e843102018-02-14 15:36:18 -0800493 fprintf(out, "usage: adb shell cmd incident throttler\n");
494 fprintf(out, " Prints the current throttler state\n");
Yi Jinb592e3b2018-02-01 15:17:04 -0800495 return NO_ERROR;
496}
497
498static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
499 if (p == NULL) return;
Joe Onorato99598ee2019-02-11 15:55:13 +0000500 fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800501 if (p->children == NULL) return;
502 for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
503 printPrivacy(p->children[i], out, indent + " ");
504 }
505}
506
507status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000508 (void)in;
509
Yi Jinb592e3b2018-02-01 15:17:04 -0800510 const int argCount = args.size();
511 if (argCount >= 3) {
512 String8 opt = args[1];
513 int sectionId = atoi(args[2].string());
514
515 const Privacy* p = get_privacy_of_section(sectionId);
516 if (p == NULL) {
517 fprintf(err, "Can't find section id %d\n", sectionId);
518 return NO_ERROR;
519 }
520 fprintf(err, "Get privacy for %d\n", sectionId);
521 if (opt == "print") {
522 printPrivacy(p, out, String8(""));
523 } else if (opt == "parse") {
Joe Onorato99598ee2019-02-11 15:55:13 +0000524 /*
Yi Jinb592e3b2018-02-01 15:17:04 -0800525 FdBuffer buf;
Yi Jine3dab2d2018-03-22 16:56:39 -0700526 status_t error = buf.read(fileno(in), 60000);
Yi Jinb592e3b2018-02-01 15:17:04 -0800527 if (error != NO_ERROR) {
528 fprintf(err, "Error reading from stdin\n");
529 return error;
530 }
531 fprintf(err, "Read %zu bytes\n", buf.size());
Joe Onorato99598ee2019-02-11 15:55:13 +0000532 PrivacyFilter pBuf(p, buf.data());
Yi Jinb592e3b2018-02-01 15:17:04 -0800533
534 PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
535 error = pBuf.strip(spec);
536 if (error != NO_ERROR) {
Joe Onorato99598ee2019-02-11 15:55:13 +0000537 fprintf(err, "Error strip pii fields with spec %d\n", spec.policy);
Yi Jinb592e3b2018-02-01 15:17:04 -0800538 return error;
539 }
540 return pBuf.flush(fileno(out));
Joe Onorato99598ee2019-02-11 15:55:13 +0000541 */
542 return -1;
Yi Jinb592e3b2018-02-01 15:17:04 -0800543 }
544 } else {
545 return cmd_help(out);
546 }
547 return NO_ERROR;
548}
Yi Jin6cacbcb2018-03-30 14:04:52 -0700549
Mike Ma85434ec2018-11-27 10:32:31 -0800550status_t IncidentService::dump(int fd, const Vector<String16>& args) {
551 if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) {
552 ALOGD("Skip dumping incident. Only proto format is supported.");
553 dprintf(fd, "Incident dump only supports proto version.\n");
554 return NO_ERROR;
555 }
556
557 ALOGD("Dump incident proto");
558 IncidentReportArgs incidentArgs;
Joe Onorato99598ee2019-02-11 15:55:13 +0000559 incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
Mike Ma85434ec2018-11-27 10:32:31 -0800560 int skipped[] = SKIPPED_SECTIONS;
561 for (const Section** section = SECTION_LIST; *section; section++) {
562 const int id = (*section)->id;
563 if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
564 incidentArgs.addSection(id);
565 }
566 }
567
568 if (!checkIncidentPermissions(incidentArgs).isOk()) {
569 return PERMISSION_DENIED;
570 }
571
Joe Onorato99598ee2019-02-11 15:55:13 +0000572 // The ReportRequest takes ownership of the fd, so we need to dup it.
Mike Ma85434ec2018-11-27 10:32:31 -0800573 int fd1 = dup(fd);
574 if (fd1 < 0) {
575 return -errno;
576 }
577
Joe Onorato99598ee2019-02-11 15:55:13 +0000578 // TODO: Remove this. Someone even dumpstate, wanting to get an incident report
579 // should use the API. That will take making dumpstated call the API, which is a
580 // good thing. It also means it won't be subject to the timeout.
581 mHandler->scheduleStreamingReport(incidentArgs, NULL, fd1);
Mike Ma85434ec2018-11-27 10:32:31 -0800582
583 return NO_ERROR;
584}
585
Yi Jin6cacbcb2018-03-30 14:04:52 -0700586} // namespace incidentd
587} // namespace os
588} // namespace android