11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/*
21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project
31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License.
61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at
71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software
111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and
141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License.
151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */
164e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin#define DEBUG false
17b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "Log.h"
181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "IncidentService.h"
201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
21b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "FdBuffer.h"
22b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "PrivacyBuffer.h"
231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "Reporter.h"
24b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "incidentd_util.h"
25b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "section_list.h"
261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <binder/IPCThreadState.h>
28b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include <binder/IResultReceiver.h>
291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <binder/IServiceManager.h>
30b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include <binder/IShellCallback.h>
311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <cutils/log.h>
321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <private/android_filesystem_config.h>
331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <utils/Looper.h>
341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <unistd.h>
361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
37b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinenum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
414e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024)        // 20MB
424e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
434e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin
446cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace android {
456cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace os {
466cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace incidentd {
476cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoString16 const DUMP_PERMISSION("android.permission.DUMP");
491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoString16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
51b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatic Status checkIncidentPermissions(const IncidentReportArgs& args) {
52437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin    uid_t callingUid = IPCThreadState::self()->getCallingUid();
53afb36062d5e6d36700147226b5776b4ca8abf922Yi Jin    pid_t callingPid = IPCThreadState::self()->getCallingPid();
54437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin    if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
55437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin        // root doesn't have permission.DUMP if don't do this!
56437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin        return Status::ok();
57437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin    }
58437aa6e8ad24489fcd8a7ab2c889874cfae12d0bYi Jin
594bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    // checking calling permission.
601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (!checkCallingPermission(DUMP_PERMISSION)) {
611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
62b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin              callingPid, callingUid);
63b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        return Status::fromExceptionCode(
64b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                Status::EX_SECURITY,
651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                "Calling process does not have permission: android.permission.DUMP");
661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
69b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin              callingPid, callingUid);
70b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        return Status::fromExceptionCode(
71b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                Status::EX_SECURITY,
721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                "Calling process does not have permission: android.permission.USAGE_STATS");
731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
744bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin
754bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    // checking calling request uid permission.
764bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    switch (args.dest()) {
774bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin        case DEST_LOCAL:
78afb36062d5e6d36700147226b5776b4ca8abf922Yi Jin            if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
79afb36062d5e6d36700147226b5776b4ca8abf922Yi Jin                ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
80b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                      callingPid, callingUid);
81b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                return Status::fromExceptionCode(
82b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                        Status::EX_SECURITY,
83b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                        "Calling process does not have permission to get local data.");
844bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin            }
854bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin        case DEST_EXPLICIT:
86b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
87b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                callingUid != AID_SYSTEM) {
88afb36062d5e6d36700147226b5776b4ca8abf922Yi Jin                ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
89b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                      callingPid, callingUid);
90b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                return Status::fromExceptionCode(
91b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                        Status::EX_SECURITY,
92b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                        "Calling process does not have permission to get explicit data.");
934bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin            }
944bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    }
951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return Status::ok();
961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
976cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================
99b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinReportRequestQueue::ReportRequestQueue() {}
1001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
101b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinReportRequestQueue::~ReportRequestQueue() {}
1021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
103b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
1041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    unique_lock<mutex> lock(mLock);
1051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mQueue.push_back(request);
1061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
108b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinsp<ReportRequest> ReportRequestQueue::getNextRequest() {
1091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    unique_lock<mutex> lock(mLock);
1101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (mQueue.empty()) {
1111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return NULL;
1121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    } else {
1131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        sp<ReportRequest> front(mQueue.front());
1141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        mQueue.pop_front();
1151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return front;
1161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================
1204e843106a6f510a7d77fedfbeaec8e95b57905b7Yi JinReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
1214e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin                             const sp<Throttler>& throttler)
1224e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
1234e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin      mHandlerLooper(handlerLooper),
1244e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin      mQueue(queue),
1254e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin      mThrottler(throttler) {}
1261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
127b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinReportHandler::~ReportHandler() {}
1281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
129b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::handleMessage(const Message& message) {
1301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    switch (message.what) {
1311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        case WHAT_RUN_REPORT:
1321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            run_report();
1331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
1341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        case WHAT_SEND_BACKLOG_TO_DROPBOX:
1351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            send_backlog_to_dropbox();
1361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
1371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
140b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
1411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mQueue->addRequest(request);
1421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
1431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
1441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
146b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::scheduleSendBacklogToDropbox() {
1471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    unique_lock<mutex> lock(mLock);
1481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
1491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    schedule_send_backlog_to_dropbox_locked();
1501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
152b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::schedule_send_backlog_to_dropbox_locked() {
1531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
154b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
1551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
157b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::run_report() {
1581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    sp<Reporter> reporter = new Reporter();
1591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // Merge all of the requests into one that has all of the
1611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // requested fields.
1621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    while (true) {
1631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        sp<ReportRequest> request = mQueue->getNextRequest();
1641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (request == NULL) {
1651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
1661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
1671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        reporter->batch.add(request);
1681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1704e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    if (mThrottler->shouldThrottle()) {
1714e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin        ALOGW("RunReport got throttled.");
1724e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin        return;
1734e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    }
1744e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin
1751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // Take the report, which might take a while. More requests might queue
1761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // up while we're doing this, and we'll handle them in their next batch.
1771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // TODO: We should further rate-limit the reports to no more than N per time-period.
1784e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    size_t reportByteSize = 0;
1794e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
1804e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    mThrottler->addReportSize(reportByteSize);
1811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
1821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        unique_lock<mutex> lock(mLock);
1831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        schedule_send_backlog_to_dropbox_locked();
1841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
187b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinvoid ReportHandler::send_backlog_to_dropbox() {
1881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
1891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        // There was a failure. Exponential backoff.
1901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        unique_lock<mutex> lock(mLock);
1911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        mBacklogDelay *= 2;
1921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        ALOGI("Error sending to dropbox. Trying again in %lld minutes",
193b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin              (mBacklogDelay / (1000000000LL * 60)));
1941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        schedule_send_backlog_to_dropbox_locked();
1951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    } else {
1961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
1971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================
2011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoIncidentService::IncidentService(const sp<Looper>& handlerLooper)
2024e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    : mQueue(new ReportRequestQueue()),
2034e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin      mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
2044e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
2051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
207b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinIncidentService::~IncidentService() {}
2081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
209b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinStatus IncidentService::reportIncident(const IncidentReportArgs& args) {
2101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    ALOGI("reportIncident");
2111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2124bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    Status status = checkIncidentPermissions(args);
2131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (!status.isOk()) {
2141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return status;
2151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
2161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
2181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return Status::ok();
2201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
222b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinStatus IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
223b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                                               const sp<IIncidentReportStatusListener>& listener,
224b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                                               const unique_fd& stream) {
2251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    ALOGI("reportIncidentToStream");
2261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2274bab3a191a70cbefac07c8fac90ec29081d91f89Yi Jin    Status status = checkIncidentPermissions(args);
2281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (!status.isOk()) {
2291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return status;
2301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
2311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    int fd = dup(stream.get());
2331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (fd < 0) {
2341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return Status::fromStatusT(-errno);
2351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
2361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
2381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return Status::ok();
2401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
242b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinStatus IncidentService::systemRunning() {
2431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
2441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        return Status::fromExceptionCode(Status::EX_SECURITY,
245b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                                         "Only system uid can call systemRunning");
2461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
247add11e9176f2a5a2e5193726b863d03c281a4eddYi Jin
2481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    // When system_server is up and running, schedule the dropbox task to run.
2491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mHandler->scheduleSendBacklogToDropbox();
2501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return Status::ok();
2521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
254b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin/**
255b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * Implement our own because the default binder implementation isn't
256b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * properly handling SHELL_COMMAND_TRANSACTION.
257b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin */
258b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatus_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
259b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                                     uint32_t flags) {
260b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    status_t err;
261b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
262b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    switch (code) {
263b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        case SHELL_COMMAND_TRANSACTION: {
264b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            int in = data.readFileDescriptor();
265b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            int out = data.readFileDescriptor();
266b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            int err = data.readFileDescriptor();
267b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            int argc = data.readInt32();
268b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            Vector<String8> args;
269b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
270b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                args.add(String8(data.readString16()));
271b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
272b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
273b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            sp<IResultReceiver> resultReceiver =
274b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                    IResultReceiver::asInterface(data.readStrongBinder());
275b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
276b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            FILE* fin = fdopen(in, "r");
277b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            FILE* fout = fdopen(out, "w");
278b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            FILE* ferr = fdopen(err, "w");
279b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
280b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (fin == NULL || fout == NULL || ferr == NULL) {
281b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                resultReceiver->send(NO_MEMORY);
282b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            } else {
283b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                err = command(fin, fout, ferr, args);
284b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                resultReceiver->send(err);
285b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
286b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
287b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (fin != NULL) {
288b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fflush(fin);
289b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fclose(fin);
290b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
291b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (fout != NULL) {
292b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fflush(fout);
293b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fclose(fout);
294b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
295b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (fout != NULL) {
296b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fflush(ferr);
297b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fclose(ferr);
298b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
299b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
300b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            return NO_ERROR;
301b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        }
302b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
303b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    }
304b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
305b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
306b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatus_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
307b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    const int argCount = args.size();
308b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
309b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    if (argCount >= 1) {
310b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        if (!args[0].compare(String8("privacy"))) {
311b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            return cmd_privacy(in, out, err, args);
312b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        }
3134e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin        if (!args[0].compare(String8("throttler"))) {
3144e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin            mThrottler->dump(out);
3154e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin            return NO_ERROR;
3164e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin        }
317b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    }
318b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    return cmd_help(out);
319b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
320b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
321b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatus_t IncidentService::cmd_help(FILE* out) {
322b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
323b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
324b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    fprintf(out, "    Prints/parses for the section id.\n");
3254e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    fprintf(out, "\n");
3264e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    fprintf(out, "usage: adb shell cmd incident throttler\n");
3274e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin    fprintf(out, "    Prints the current throttler state\n");
328b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    return NO_ERROR;
329b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
330b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
331b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatic void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
332b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    if (p == NULL) return;
333b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
334b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    if (p->children == NULL) return;
335b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    for (int i = 0; p->children[i] != NULL; i++) {  // NULL-terminated.
336b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        printPrivacy(p->children[i], out, indent + "  ");
337b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    }
338b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
339b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
340b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinstatus_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
341b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    const int argCount = args.size();
342b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    if (argCount >= 3) {
343b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        String8 opt = args[1];
344b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        int sectionId = atoi(args[2].string());
345b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
346b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        const Privacy* p = get_privacy_of_section(sectionId);
347b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        if (p == NULL) {
348b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            fprintf(err, "Can't find section id %d\n", sectionId);
349b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            return NO_ERROR;
350b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        }
351b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        fprintf(err, "Get privacy for %d\n", sectionId);
352b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        if (opt == "print") {
353b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            printPrivacy(p, out, String8(""));
354b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        } else if (opt == "parse") {
355b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            FdBuffer buf;
356e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            status_t error = buf.read(fileno(in), 60000);
357b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (error != NO_ERROR) {
358b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fprintf(err, "Error reading from stdin\n");
359b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                return error;
360b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
361b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            fprintf(err, "Read %zu bytes\n", buf.size());
36286dce413f808ca9ef160e8762f74deaafd7c23aeYi Jin            PrivacyBuffer pBuf(p, buf.data());
363b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
364b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
365b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            error = pBuf.strip(spec);
366b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            if (error != NO_ERROR) {
367b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
368b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                return error;
369b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }
370b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            return pBuf.flush(fileno(out));
371b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        }
372b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    } else {
373b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        return cmd_help(out);
374b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    }
375b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    return NO_ERROR;
376b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
3776cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
3786cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace incidentd
3796cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace os
3806cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace android
381