Loading cmds/dumpstate/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -155,7 +155,10 @@ cc_test { "dumpstate.cpp", "tests/dumpstate_test.cpp", ], static_libs: ["libgmock"], static_libs: [ "libc++fs", "libgmock", ], test_config: "dumpstate_test.xml", data: [ ":dumpstate_test_fixture", Loading cmds/dumpstate/DumpstateService.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ 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"); Loading Loading @@ -84,11 +84,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); Loading @@ -96,12 +113,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 Loading @@ -123,8 +140,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"); Loading @@ -148,10 +165,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); } Loading cmds/dumpstate/DumpstateService.h +5 −2 Original line number Diff line number Diff line Loading @@ -38,13 +38,16 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst status_t dump(int fd, const Vector<String16>& args) override; binder::Status preDumpUiData(const std::string& callingPackage) override; binder::Status 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, const sp<IDumpstateListener>& listener, int bugreport_flags, const sp<IDumpstateListener>& listener, bool is_screenshot_requested) override; binder::Status cancelBugreport(int32_t calling_uid, const std::string& calling_package); binder::Status cancelBugreport(int32_t calling_uid, const std::string& calling_package) override; private: // Dumpstate object which contains all the bugreporting logic. Loading cmds/dumpstate/binder/android/os/IDumpstate.aidl +20 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,23 @@ interface IDumpstate { // Default mode. const int BUGREPORT_MODE_DEFAULT = 6; // Use pre-dumped data. const int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 1; /** * Speculatively pre-dumps UI data for a bugreport request that might come later. * * <p>Triggers the dump of certain critical UI data, e.g. traces stored in short * ring buffers that might get lost by the time the actual bugreport is requested. * * <p>{@code startBugreport} will then pick the pre-dumped data if: * - {@link BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA} is specified. * - {@code preDumpUiData} and {@code startBugreport} were called by the same UID. * * @param callingPackage package of the original application that requested the report. */ void preDumpUiData(@utf8InCpp String callingPackage); /** * Starts a bugreport in the background. * Loading @@ -63,13 +80,14 @@ interface IDumpstate { * @param bugreportFd the file to which the zipped bugreport should be written * @param screenshotFd the file to which screenshot should be written * @param bugreportMode the mode that specifies other run time options; must be one of above * @param bugreportFlags flags to customize the bugreport generation * @param listener callback for updates; optional * @param isScreenshotRequested indicates screenshot is requested or not */ void startBugreport(int callingUid, @utf8InCpp String callingPackage, FileDescriptor bugreportFd, FileDescriptor screenshotFd, int bugreportMode, IDumpstateListener listener, boolean isScreenshotRequested); int bugreportMode, int bugreportFlags, IDumpstateListener listener, boolean isScreenshotRequested); /** * Cancels the bugreport currently in progress. Loading cmds/dumpstate/dumpstate.cpp +64 −14 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ static const std::string DUMP_NETSTATS_PROTO_TASK = "DUMP NETSTATS PROTO"; static const std::string DUMP_HALS_TASK = "DUMP HALS"; static const std::string DUMP_BOARD_TASK = "dumpstate_board()"; static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS"; static const std::string POST_PROCESS_UI_TRACES_TASK = "POST-PROCESS UI TRACES"; namespace android { namespace os { Loading Loading @@ -1593,16 +1594,16 @@ static void DumpAppInfos(int out_fd = STDOUT_FILENO) { // via the consent they are shown. Ignores other errors that occur while running various // commands. The consent checking is currently done around long running tasks, which happen to // be distributed fairly evenly throughout the function. static Dumpstate::RunStatus dumpstate() { Dumpstate::RunStatus Dumpstate::dumpstate() { DurationReporter duration_reporter("DUMPSTATE"); // Enqueue slow functions into the thread pool, if the parallel run is enabled. std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins, dump_netstats_report; dump_netstats_report, post_process_ui_traces; if (ds.dump_pool_) { // Pool was shutdown in DumpstateDefaultAfterCritical method in order to // drop root user. Restarts it with two threads for the parallel run. ds.dump_pool_->start(/* thread_counts = */2); // drop root user. Restarts it. ds.dump_pool_->start(/* thread_counts = */3); dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1); dump_incident_report = ds.dump_pool_->enqueueTask( Loading @@ -1612,6 +1613,8 @@ static Dumpstate::RunStatus dumpstate() { dump_board = ds.dump_pool_->enqueueTaskWithFd( DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1); dump_checkins = ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1); post_process_ui_traces = ds.dump_pool_->enqueueTask( POST_PROCESS_UI_TRACES_TASK, &Dumpstate::MaybePostProcessUiTraces, &ds); } // Dump various things. Note that anything that takes "long" (i.e. several seconds) should Loading Loading @@ -1732,11 +1735,6 @@ static Dumpstate::RunStatus dumpstate() { DumpFile("BINDER STATS", binder_logs_dir + "/stats"); DumpFile("BINDER STATE", binder_logs_dir + "/state"); /* Add window and surface trace files. */ if (!PropertiesHelper::IsUserBuild()) { ds.AddDir(WMTRACE_DATA_DIR, false); } ds.AddDir(SNAPSHOTCTL_LOG_DIR, false); if (ds.dump_pool_) { Loading Loading @@ -1816,6 +1814,14 @@ static Dumpstate::RunStatus dumpstate() { DumpIncidentReport); } if (ds.dump_pool_) { WaitForTask(std::move(post_process_ui_traces)); } else { RUN_SLOW_FUNCTION_AND_LOG(POST_PROCESS_UI_TRACES_TASK, MaybePostProcessUiTraces); } MaybeAddUiTracesToZip(); return Dumpstate::RunStatus::OK; } Loading Loading @@ -2787,9 +2793,11 @@ static void LogDumpOptions(const Dumpstate::DumpOptions& options) { } void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode, int bugreport_flags, const android::base::unique_fd& bugreport_fd_in, const android::base::unique_fd& screenshot_fd_in, bool is_screenshot_requested) { this->use_predumped_ui_data = bugreport_flags & BugreportFlag::BUGREPORT_USE_PREDUMPED_UI_DATA; // Duplicate the fds because the passed in fds don't outlive the binder transaction. bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0)); screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0)); Loading Loading @@ -2916,6 +2924,10 @@ void Dumpstate::Cancel() { } } void Dumpstate::PreDumpUiData() { MaybeSnapshotUiTraces(); } /* * Dumps relevant information to a bugreport based on the given options. * Loading Loading @@ -3107,9 +3119,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // The trace file is added to the zip by MaybeAddSystemTraceToZip(). MaybeSnapshotSystemTrace(); // If a winscope trace is running, snapshot it now. It will be pulled into bugreport later // from WMTRACE_DATA_DIR. MaybeSnapshotWinTrace(); // Snapshot the UI traces now (if running). // The trace files will be added to bugreport later. MaybeSnapshotUiTraces(); } onUiIntensiveBugreportDumpsFinished(calling_uid); MaybeCheckUserConsent(calling_uid, calling_package); Loading Loading @@ -3223,15 +3235,53 @@ void Dumpstate::MaybeSnapshotSystemTrace() { // file in the later stages. } void Dumpstate::MaybeSnapshotWinTrace() { void Dumpstate::MaybeSnapshotUiTraces() { if (PropertiesHelper::IsUserBuild() || options_->use_predumped_ui_data) { return; } // Currently WindowManagerService and InputMethodManagerSerivice support WinScope protocol. for (const auto& service : {"window", "input_method"}) { for (const auto& service : {"input_method", "window"}) { RunCommand( // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. "", {"cmd", service, "tracing", "save-for-bugreport"}, CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); } static const auto SURFACEFLINGER_COMMAND_SAVE_ALL_TRACES = std::vector<std::string> { "service", "call", "SurfaceFlinger", "1042" }; // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. RunCommand( "", SURFACEFLINGER_COMMAND_SAVE_ALL_TRACES, CommandOptions::WithTimeout(10).Always().AsRoot().RedirectStderr().Build()); } void Dumpstate::MaybePostProcessUiTraces() { if (PropertiesHelper::IsUserBuild()) { return; } RunCommand( // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. "", { "/system/xbin/su", "system", "/system/bin/layertracegenerator", "/data/misc/wmtrace/transactions_trace.winscope", "/data/misc/wmtrace/layers_trace_from_transactions.winscope" }, CommandOptions::WithTimeout(120).Always().RedirectStderr().Build()); } void Dumpstate::MaybeAddUiTracesToZip() { if (PropertiesHelper::IsUserBuild()) { return; } ds.AddDir(WMTRACE_DATA_DIR, false); } void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid) { Loading Loading
cmds/dumpstate/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -155,7 +155,10 @@ cc_test { "dumpstate.cpp", "tests/dumpstate_test.cpp", ], static_libs: ["libgmock"], static_libs: [ "libc++fs", "libgmock", ], test_config: "dumpstate_test.xml", data: [ ":dumpstate_test_fixture", Loading
cmds/dumpstate/DumpstateService.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ 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"); Loading Loading @@ -84,11 +84,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); Loading @@ -96,12 +113,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 Loading @@ -123,8 +140,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"); Loading @@ -148,10 +165,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); } Loading
cmds/dumpstate/DumpstateService.h +5 −2 Original line number Diff line number Diff line Loading @@ -38,13 +38,16 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst status_t dump(int fd, const Vector<String16>& args) override; binder::Status preDumpUiData(const std::string& callingPackage) override; binder::Status 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, const sp<IDumpstateListener>& listener, int bugreport_flags, const sp<IDumpstateListener>& listener, bool is_screenshot_requested) override; binder::Status cancelBugreport(int32_t calling_uid, const std::string& calling_package); binder::Status cancelBugreport(int32_t calling_uid, const std::string& calling_package) override; private: // Dumpstate object which contains all the bugreporting logic. Loading
cmds/dumpstate/binder/android/os/IDumpstate.aidl +20 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,23 @@ interface IDumpstate { // Default mode. const int BUGREPORT_MODE_DEFAULT = 6; // Use pre-dumped data. const int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 1; /** * Speculatively pre-dumps UI data for a bugreport request that might come later. * * <p>Triggers the dump of certain critical UI data, e.g. traces stored in short * ring buffers that might get lost by the time the actual bugreport is requested. * * <p>{@code startBugreport} will then pick the pre-dumped data if: * - {@link BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA} is specified. * - {@code preDumpUiData} and {@code startBugreport} were called by the same UID. * * @param callingPackage package of the original application that requested the report. */ void preDumpUiData(@utf8InCpp String callingPackage); /** * Starts a bugreport in the background. * Loading @@ -63,13 +80,14 @@ interface IDumpstate { * @param bugreportFd the file to which the zipped bugreport should be written * @param screenshotFd the file to which screenshot should be written * @param bugreportMode the mode that specifies other run time options; must be one of above * @param bugreportFlags flags to customize the bugreport generation * @param listener callback for updates; optional * @param isScreenshotRequested indicates screenshot is requested or not */ void startBugreport(int callingUid, @utf8InCpp String callingPackage, FileDescriptor bugreportFd, FileDescriptor screenshotFd, int bugreportMode, IDumpstateListener listener, boolean isScreenshotRequested); int bugreportMode, int bugreportFlags, IDumpstateListener listener, boolean isScreenshotRequested); /** * Cancels the bugreport currently in progress. Loading
cmds/dumpstate/dumpstate.cpp +64 −14 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ static const std::string DUMP_NETSTATS_PROTO_TASK = "DUMP NETSTATS PROTO"; static const std::string DUMP_HALS_TASK = "DUMP HALS"; static const std::string DUMP_BOARD_TASK = "dumpstate_board()"; static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS"; static const std::string POST_PROCESS_UI_TRACES_TASK = "POST-PROCESS UI TRACES"; namespace android { namespace os { Loading Loading @@ -1593,16 +1594,16 @@ static void DumpAppInfos(int out_fd = STDOUT_FILENO) { // via the consent they are shown. Ignores other errors that occur while running various // commands. The consent checking is currently done around long running tasks, which happen to // be distributed fairly evenly throughout the function. static Dumpstate::RunStatus dumpstate() { Dumpstate::RunStatus Dumpstate::dumpstate() { DurationReporter duration_reporter("DUMPSTATE"); // Enqueue slow functions into the thread pool, if the parallel run is enabled. std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins, dump_netstats_report; dump_netstats_report, post_process_ui_traces; if (ds.dump_pool_) { // Pool was shutdown in DumpstateDefaultAfterCritical method in order to // drop root user. Restarts it with two threads for the parallel run. ds.dump_pool_->start(/* thread_counts = */2); // drop root user. Restarts it. ds.dump_pool_->start(/* thread_counts = */3); dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1); dump_incident_report = ds.dump_pool_->enqueueTask( Loading @@ -1612,6 +1613,8 @@ static Dumpstate::RunStatus dumpstate() { dump_board = ds.dump_pool_->enqueueTaskWithFd( DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1); dump_checkins = ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1); post_process_ui_traces = ds.dump_pool_->enqueueTask( POST_PROCESS_UI_TRACES_TASK, &Dumpstate::MaybePostProcessUiTraces, &ds); } // Dump various things. Note that anything that takes "long" (i.e. several seconds) should Loading Loading @@ -1732,11 +1735,6 @@ static Dumpstate::RunStatus dumpstate() { DumpFile("BINDER STATS", binder_logs_dir + "/stats"); DumpFile("BINDER STATE", binder_logs_dir + "/state"); /* Add window and surface trace files. */ if (!PropertiesHelper::IsUserBuild()) { ds.AddDir(WMTRACE_DATA_DIR, false); } ds.AddDir(SNAPSHOTCTL_LOG_DIR, false); if (ds.dump_pool_) { Loading Loading @@ -1816,6 +1814,14 @@ static Dumpstate::RunStatus dumpstate() { DumpIncidentReport); } if (ds.dump_pool_) { WaitForTask(std::move(post_process_ui_traces)); } else { RUN_SLOW_FUNCTION_AND_LOG(POST_PROCESS_UI_TRACES_TASK, MaybePostProcessUiTraces); } MaybeAddUiTracesToZip(); return Dumpstate::RunStatus::OK; } Loading Loading @@ -2787,9 +2793,11 @@ static void LogDumpOptions(const Dumpstate::DumpOptions& options) { } void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode, int bugreport_flags, const android::base::unique_fd& bugreport_fd_in, const android::base::unique_fd& screenshot_fd_in, bool is_screenshot_requested) { this->use_predumped_ui_data = bugreport_flags & BugreportFlag::BUGREPORT_USE_PREDUMPED_UI_DATA; // Duplicate the fds because the passed in fds don't outlive the binder transaction. bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0)); screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0)); Loading Loading @@ -2916,6 +2924,10 @@ void Dumpstate::Cancel() { } } void Dumpstate::PreDumpUiData() { MaybeSnapshotUiTraces(); } /* * Dumps relevant information to a bugreport based on the given options. * Loading Loading @@ -3107,9 +3119,9 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // The trace file is added to the zip by MaybeAddSystemTraceToZip(). MaybeSnapshotSystemTrace(); // If a winscope trace is running, snapshot it now. It will be pulled into bugreport later // from WMTRACE_DATA_DIR. MaybeSnapshotWinTrace(); // Snapshot the UI traces now (if running). // The trace files will be added to bugreport later. MaybeSnapshotUiTraces(); } onUiIntensiveBugreportDumpsFinished(calling_uid); MaybeCheckUserConsent(calling_uid, calling_package); Loading Loading @@ -3223,15 +3235,53 @@ void Dumpstate::MaybeSnapshotSystemTrace() { // file in the later stages. } void Dumpstate::MaybeSnapshotWinTrace() { void Dumpstate::MaybeSnapshotUiTraces() { if (PropertiesHelper::IsUserBuild() || options_->use_predumped_ui_data) { return; } // Currently WindowManagerService and InputMethodManagerSerivice support WinScope protocol. for (const auto& service : {"window", "input_method"}) { for (const auto& service : {"input_method", "window"}) { RunCommand( // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. "", {"cmd", service, "tracing", "save-for-bugreport"}, CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); } static const auto SURFACEFLINGER_COMMAND_SAVE_ALL_TRACES = std::vector<std::string> { "service", "call", "SurfaceFlinger", "1042" }; // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. RunCommand( "", SURFACEFLINGER_COMMAND_SAVE_ALL_TRACES, CommandOptions::WithTimeout(10).Always().AsRoot().RedirectStderr().Build()); } void Dumpstate::MaybePostProcessUiTraces() { if (PropertiesHelper::IsUserBuild()) { return; } RunCommand( // Empty name because it's not intended to be classified as a bugreport section. // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. "", { "/system/xbin/su", "system", "/system/bin/layertracegenerator", "/data/misc/wmtrace/transactions_trace.winscope", "/data/misc/wmtrace/layers_trace_from_transactions.winscope" }, CommandOptions::WithTimeout(120).Always().RedirectStderr().Build()); } void Dumpstate::MaybeAddUiTracesToZip() { if (PropertiesHelper::IsUserBuild()) { return; } ds.AddDir(WMTRACE_DATA_DIR, false); } void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid) { Loading