diff options
Diffstat (limited to 'cmds/dumpstate/DumpstateService.cpp')
-rw-r--r-- | cmds/dumpstate/DumpstateService.cpp | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp index e42ee0540b..a7bc018ff6 100644 --- a/cmds/dumpstate/DumpstateService.cpp +++ b/cmds/dumpstate/DumpstateService.cpp @@ -51,13 +51,20 @@ static binder::Status exception(uint32_t code, const std::string& msg, // Creates a bugreport and exits, thus preserving the oneshot nature of the service. // Note: takes ownership of data. -[[noreturn]] static void* dumpstate_thread_main(void* data) { +[[noreturn]] static void* dumpstate_thread_bugreport(void* data) { std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data)); ds_info->ds->Run(ds_info->calling_uid, ds_info->calling_package); MYLOGD("Finished taking a bugreport. Exiting.\n"); exit(0); } +[[noreturn]] static void* dumpstate_thread_retrieve(void* data) { + std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data)); + ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package); + MYLOGD("Finished retrieving a bugreport. Exiting.\n"); + exit(0); +} + [[noreturn]] static void signalErrorAndExit(sp<IDumpstateListener> listener, int error_code) { listener->onError(error_code); exit(0); @@ -84,11 +91,28 @@ status_t DumpstateService::Start() { return android::OK; } +binder::Status DumpstateService::preDumpUiData(const std::string&) { + std::lock_guard<std::mutex> lock(lock_); + MYLOGI("preDumpUiData()"); + + if (ds_ != nullptr) { + MYLOGE("Error! DumpstateService is currently already being used. Returning."); + return exception(binder::Status::EX_SERVICE_SPECIFIC, + "DumpstateService is already being used"); + } + + ds_ = &(Dumpstate::GetInstance()); + ds_->PreDumpUiData(); + + return binder::Status::ok(); +} + binder::Status DumpstateService::startBugreport(int32_t calling_uid, const std::string& calling_package, android::base::unique_fd bugreport_fd, android::base::unique_fd screenshot_fd, int bugreport_mode, + int bugreport_flags, const sp<IDumpstateListener>& listener, bool is_screenshot_requested) { MYLOGI("startBugreport() with mode: %d\n", bugreport_mode); @@ -96,12 +120,12 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid, // Ensure there is only one bugreport in progress at a time. std::lock_guard<std::mutex> lock(lock_); if (ds_ != nullptr) { - MYLOGE("Error! There is already a bugreport in progress. Returning."); + MYLOGE("Error! DumpstateService is currently already being used. Returning."); if (listener != nullptr) { listener->onError(IDumpstateListener::BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS); } return exception(binder::Status::EX_SERVICE_SPECIFIC, - "There is already a bugreport in progress"); + "DumpstateService is already being used"); } // From here on, all conditions that indicate we are done with this incoming request should @@ -123,8 +147,8 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid, } std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>(); - options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode), bugreport_fd, - screenshot_fd, is_screenshot_requested); + options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode), bugreport_flags, + bugreport_fd, screenshot_fd, is_screenshot_requested); if (bugreport_fd.get() == -1 || (options->do_screenshot && screenshot_fd.get() == -1)) { MYLOGE("Invalid filedescriptor"); @@ -148,10 +172,9 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid, pthread_t thread; // Initialize dumpstate ds_->Initialize(); - status_t err = pthread_create(&thread, nullptr, dumpstate_thread_main, ds_info); + status_t err = pthread_create(&thread, nullptr, dumpstate_thread_bugreport, ds_info); if (err != 0) { delete ds_info; - ds_info = nullptr; MYLOGE("Could not create a thread"); signalErrorAndExit(listener, IDumpstateListener::BUGREPORT_ERROR_RUNTIME_ERROR); } @@ -176,6 +199,41 @@ binder::Status DumpstateService::cancelBugreport(int32_t calling_uid, return binder::Status::ok(); } +binder::Status DumpstateService::retrieveBugreport( + int32_t calling_uid, const std::string& calling_package, + android::base::unique_fd bugreport_fd, + const std::string& bugreport_file, + const sp<IDumpstateListener>& listener) { + + ds_ = &(Dumpstate::GetInstance()); + DumpstateInfo* ds_info = new DumpstateInfo(); + ds_info->ds = ds_; + ds_info->calling_uid = calling_uid; + ds_info->calling_package = calling_package; + ds_->listener_ = listener; + std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>(); + // Use a /dev/null FD when initializing options since none is provided. + android::base::unique_fd devnull_fd( + TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC))); + + options->Initialize(Dumpstate::BugreportMode::BUGREPORT_DEFAULT, + 0, bugreport_fd, devnull_fd, false); + + if (bugreport_fd.get() == -1) { + MYLOGE("Invalid filedescriptor"); + signalErrorAndExit(listener, IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT); + } + ds_->SetOptions(std::move(options)); + ds_->path_ = bugreport_file; + pthread_t thread; + status_t err = pthread_create(&thread, nullptr, dumpstate_thread_retrieve, ds_info); + if (err != 0) { + MYLOGE("Could not create a thread"); + signalErrorAndExit(listener, IDumpstateListener::BUGREPORT_ERROR_RUNTIME_ERROR); + } + return binder::Status::ok(); +} + status_t DumpstateService::dump(int fd, const Vector<String16>&) { std::lock_guard<std::mutex> lock(lock_); if (ds_ == nullptr) { |