diff options
author | Mike Ma <yanmin@google.com> | 2019-12-17 10:56:17 -0800 |
---|---|---|
committer | Mike Ma <yanmin@google.com> | 2020-01-14 16:45:33 -0800 |
commit | 643de9238b140ccaa0d7e65c878b5e65f4c3acfe (patch) | |
tree | 647c094d184e60e6a3c50b258128e17811911a45 /cmds/incidentd/src/IncidentService.cpp | |
parent | a4d4f94e21757148153711a2defe21bd45dc3337 (diff) |
Incident Report Extension API
Add an API for priv and system app to register a dump callback with
Incident Service.
Bug: 145924375
Test: Register a callback dumping a string. Capture an incident report
and verify that the customized section exist.
Change-Id: I6fff6c1ee97e25963068d284ba37adce1bb5ec31
Diffstat (limited to 'cmds/incidentd/src/IncidentService.cpp')
-rw-r--r-- | cmds/incidentd/src/IncidentService.cpp | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp index cfd77c2357cd..62312d1cccaa 100644 --- a/cmds/incidentd/src/IncidentService.cpp +++ b/cmds/incidentd/src/IncidentService.cpp @@ -123,14 +123,17 @@ static string build_uri(const string& pkg, const string& cls, const string& id) // ================================================================================ ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory, - const sp<Broadcaster>& broadcaster, const sp<Looper>& handlerLooper, - const sp<Throttler>& throttler) + const sp<Broadcaster>& broadcaster, + const sp<Looper>& handlerLooper, + const sp<Throttler>& throttler, + const vector<BringYourOwnSection*>& registeredSections) :mLock(), mWorkDirectory(workDirectory), mBroadcaster(broadcaster), mHandlerLooper(handlerLooper), mBacklogDelay(DEFAULT_DELAY_NS), mThrottler(throttler), + mRegisteredSections(registeredSections), mBatch(new ReportBatch()) { } @@ -185,7 +188,7 @@ void ReportHandler::take_report() { return; } - sp<Reporter> reporter = new Reporter(mWorkDirectory, batch); + sp<Reporter> reporter = new Reporter(mWorkDirectory, batch, mRegisteredSections); // Take the report, which might take a while. More requests might queue // up while we're doing this, and we'll handle them in their next batch. @@ -237,7 +240,7 @@ IncidentService::IncidentService(const sp<Looper>& handlerLooper) { mWorkDirectory = new WorkDirectory(); mBroadcaster = new Broadcaster(mWorkDirectory); mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper, - mThrottler); + mThrottler, mRegisteredSections); mBroadcaster->setHandler(mHandler); } @@ -327,6 +330,11 @@ Status IncidentService::reportIncidentToDumpstate(unique_fd stream, incidentArgs.addSection(id); } } + for (const Section* section : mRegisteredSections) { + if (!section_requires_specific_mention(section->id)) { + incidentArgs.addSection(section->id); + } + } // The ReportRequest takes ownership of the fd, so we need to dup it. int fd = dup(stream.get()); @@ -339,6 +347,45 @@ Status IncidentService::reportIncidentToDumpstate(unique_fd stream, return Status::ok(); } +Status IncidentService::registerSection(const int id, const String16& name16, + const sp<IIncidentDumpCallback>& callback) { + const char* name = String8(name16).c_str(); + ALOGI("Register section %d: %s", id, name); + if (callback == nullptr) { + return Status::fromExceptionCode(Status::EX_NULL_POINTER); + } + const uid_t callingUid = IPCThreadState::self()->getCallingUid(); + for (int i = 0; i < mRegisteredSections.size(); i++) { + if (mRegisteredSections.at(i)->id == id) { + if (mRegisteredSections.at(i)->uid != callingUid) { + ALOGW("Error registering section %d: calling uid does not match", id); + return Status::fromExceptionCode(Status::EX_SECURITY); + } + mRegisteredSections.at(i) = new BringYourOwnSection(id, name, callingUid, callback); + return Status::ok(); + } + } + mRegisteredSections.push_back(new BringYourOwnSection(id, name, callingUid, callback)); + return Status::ok(); +} + +Status IncidentService::unregisterSection(const int id) { + ALOGI("Unregister section %d", id); + uid_t callingUid = IPCThreadState::self()->getCallingUid(); + for (auto it = mRegisteredSections.begin(); it != mRegisteredSections.end(); it++) { + if ((*it)->id == id) { + if ((*it)->uid != callingUid) { + ALOGW("Error unregistering section %d: calling uid does not match", id); + return Status::fromExceptionCode(Status::EX_SECURITY); + } + mRegisteredSections.erase(it); + return Status::ok(); + } + } + ALOGW("Section %d not found", id); + return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); +} + Status IncidentService::systemRunning() { if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) { return Status::fromExceptionCode(Status::EX_SECURITY, |