summaryrefslogtreecommitdiff
path: root/cmds/dumpstate/DumpstateService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/dumpstate/DumpstateService.cpp')
-rw-r--r--cmds/dumpstate/DumpstateService.cpp72
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) {