Loading cmds/dumpstate/dumpstate.cpp +31 −54 Original line number Diff line number Diff line Loading @@ -1089,8 +1089,14 @@ static void MaybeAddSystemTraceToZip() { // This function copies into the .zip the system trace that was snapshotted // by the early call to MaybeSnapshotSystemTrace(), if any background // tracing was happening. if (!ds.has_system_trace_) { // No background trace was happening at the time dumpstate was invoked. bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; if (!system_trace_exists) { // No background trace was happening at the time MaybeSnapshotSystemTrace() was invoked. if (!PropertiesHelper::IsUserBuild()) { MYLOGI( "No system traces found. Check for previously uploaded traces by looking for " "go/trace-uuid in logcat") } return; } ds.AddZipEntry( Loading Loading @@ -1650,8 +1656,6 @@ Dumpstate::RunStatus Dumpstate::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 @@ -1861,12 +1865,6 @@ Dumpstate::RunStatus Dumpstate::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 @@ -3078,6 +3076,7 @@ void Dumpstate::Cancel() { } void Dumpstate::PreDumpUiData() { MaybeSnapshotSystemTrace(); MaybeSnapshotUiTraces(); } Loading Loading @@ -3264,25 +3263,23 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // duration is logged into MYLOG instead. PrintHeader(); bool is_dumpstate_restricted = options_->telephony_only || options_->wifi_only || options_->limited_only; if (!is_dumpstate_restricted) { // Invoke critical dumpsys first to preserve system state, before doing anything else. RunDumpsysCritical(); } MaybeTakeEarlyScreenshot(); bool is_dumpstate_restricted = options_->telephony_only || options_->wifi_only || options_->limited_only; if (!is_dumpstate_restricted) { // Snapshot the system trace now (if running) to avoid that dumpstate's // own activity pushes out interesting data from the trace ring buffer. // The trace file is added to the zip by MaybeAddSystemTraceToZip(). MaybeSnapshotSystemTrace(); // Invoke critical dumpsys to preserve system state, before doing anything else. RunDumpsysCritical(); // Snapshot the UI traces now (if running). // The trace files will be added to bugreport later. MaybeSnapshotUiTraces(); } MaybeTakeEarlyScreenshot(); onUiIntensiveBugreportDumpsFinished(calling_uid); MaybeCheckUserConsent(calling_uid, calling_package); if (options_->telephony_only) { Loading Loading @@ -3379,6 +3376,19 @@ void Dumpstate::MaybeTakeEarlyScreenshot() { } void Dumpstate::MaybeSnapshotSystemTrace() { // When capturing traces via bugreport handler (BH), this function will be invoked twice: // 1) When BH invokes IDumpstate::PreDumpUiData() // 2) When BH invokes IDumpstate::startBugreport(flags = BUGREPORT_USE_PREDUMPED_UI_DATA) // In this case we don't want to re-invoke perfetto in step 2. // In all other standard invocation states, this function is invoked once // without the flag BUGREPORT_USE_PREDUMPED_UI_DATA. if (options_->use_predumped_ui_data) { return; } // If a stale file exists already, remove it. unlink(SYSTEM_TRACE_SNAPSHOT); // If a background system trace is happening and is marked as "suitable for // bugreport" (i.e. bugreport_score > 0 in the trace config), this command // will stop it and serialize into SYSTEM_TRACE_SNAPSHOT. In the (likely) Loading @@ -3386,14 +3396,8 @@ void Dumpstate::MaybeSnapshotSystemTrace() { // Note: this should not be enqueued as we need to freeze the trace before // dumpstate starts. Otherwise the trace ring buffers will contain mostly // the dumpstate's own activity which is irrelevant. int res = RunCommand( "SERIALIZE PERFETTO TRACE", {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10) .DropRoot() .CloseAllFileDescriptorsOnExec() .Build()); has_system_trace_ = res == 0; RunCommand("SERIALIZE PERFETTO TRACE", {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10).DropRoot().CloseAllFileDescriptorsOnExec().Build()); // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip // file in the later stages. } Loading @@ -3420,33 +3424,6 @@ void Dumpstate::MaybeSnapshotUiTraces() { "", command, CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); } // This command needs to be run as root 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() { Loading cmds/dumpstate/dumpstate.h +0 −6 Original line number Diff line number Diff line Loading @@ -476,11 +476,6 @@ class Dumpstate { // Whether it should take an screenshot earlier in the process. bool do_early_screenshot_ = false; // This is set to true when the trace snapshot request in the early call to // MaybeSnapshotSystemTrace(). When this is true, the later stages of // dumpstate will append the trace to the zip archive. bool has_system_trace_ = false; std::unique_ptr<Progress> progress_; // When set, defines a socket file-descriptor use to report progress to bugreportz Loading Loading @@ -574,7 +569,6 @@ class Dumpstate { void MaybeTakeEarlyScreenshot(); void MaybeSnapshotSystemTrace(); void MaybeSnapshotUiTraces(); void MaybePostProcessUiTraces(); void MaybeAddUiTracesToZip(); void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid); Loading cmds/dumpstate/tests/dumpstate_test.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -1000,7 +1000,6 @@ TEST_F(DumpstateTest, DumpPool_withParallelRunDisabled_isNull) { TEST_F(DumpstateTest, PreDumpUiData) { // These traces are always enabled, i.e. they are always pre-dumped const std::vector<std::filesystem::path> uiTraces = { std::filesystem::path{"/data/misc/wmtrace/transactions_trace.winscope"}, std::filesystem::path{"/data/misc/wmtrace/wm_transition_trace.winscope"}, std::filesystem::path{"/data/misc/wmtrace/shell_transition_trace.winscope"}, }; Loading services/surfaceflinger/Tracing/LayerDataSource.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -51,8 +51,9 @@ void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) { if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) { mMode = static_cast<LayerTracing::Mode>(config.mode()); } else { mMode = LayerTracing::Mode::MODE_GENERATED; ALOGD("Received config with unspecified 'mode'. Using 'GENERATED' as default"); mMode = LayerTracing::Mode::MODE_GENERATED_BUGREPORT_ONLY; ALOGD("Received config with unspecified 'mode'." " Using 'MODE_GENERATED_BUGREPORT_ONLY' as default"); } mFlags = 0; Loading @@ -68,10 +69,16 @@ void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) { } } void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs&) { ALOGD("Received OnFlush event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags); void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs& args) { ALOGD("Received OnFlush event" " (mode = 0x%02x, flags = 0x%02x, reason = 0x%" PRIx64 ", clone_target = 0x%0" PRIx64 ")", mMode, mFlags, args.flush_flags.reason(), args.flush_flags.clone_target()); bool isBugreport = args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone && args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport; if (auto* p = mLayerTracing.load()) { p->onFlush(mMode, mFlags); p->onFlush(mMode, mFlags, isBugreport); } } Loading services/surfaceflinger/Tracing/LayerTracing.cpp +42 −7 Original line number Diff line number Diff line Loading @@ -67,9 +67,27 @@ void LayerTracing::onStart(Mode mode, uint32_t flags) { break; } case Mode::MODE_GENERATED: { // This tracing mode processes the buffer of transactions (owned by TransactionTracing), // generates layers snapshots and writes them to perfetto. This happens every time an // OnFlush event is received. ALOGD("Started generated tracing (waiting for OnFlush event to generated layers)"); break; } case Mode::MODE_GENERATED_BUGREPORT_ONLY: { // Same as MODE_GENERATED, but only when the received OnFlush event is due to a // bugreport being taken. This mode exists because the generated layers trace is very // large (hundreds of MB), hence we want to include it only in bugreports and not in // field uploads. // // Note that perfetto communicates only whether the OnFlush event is due to a bugreport // or not, hence we need an additional "bugreport only" tracing mode. // If perfetto had communicated when the OnFlush is due to a field upload, then we could // have had a single "generated" tracing mode that would have been a noop in case of // field uploads. ALOGD("Started 'generated bugreport only' tracing" " (waiting for bugreport's OnFlush event to generate layers)"); break; } case Mode::MODE_DUMP: { auto snapshot = mTakeLayersSnapshotProto(flags); addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP); Loading @@ -82,10 +100,18 @@ void LayerTracing::onStart(Mode mode, uint32_t flags) { } } void LayerTracing::onFlush(Mode mode, uint32_t flags) { void LayerTracing::onFlush(Mode mode, uint32_t flags, bool isBugreport) { // In "generated" mode process the buffer of transactions (owned by TransactionTracing), // generate a sequence of layers snapshots and write them to perfetto. if (mode != Mode::MODE_GENERATED) { // generate layers snapshots and write them to perfetto. if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { ALOGD("Skipping layers trace generation (not a 'generated' tracing session)"); return; } // In "generated bugreport only" mode skip the layers snapshot generation // if the perfetto's OnFlush event is not due to a bugreport being taken. if (mode == Mode::MODE_GENERATED_BUGREPORT_ONLY && !isBugreport) { ALOGD("Skipping layers trace generation (not a bugreport OnFlush event)"); return; } Loading Loading @@ -147,14 +173,23 @@ void LayerTracing::writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& } void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot, Mode mode) { Mode srcMode) { const auto snapshotBytes = snapshot.SerializeAsString(); LayerDataSource::Trace([&](LayerDataSource::TraceContext context) { if (mode != context.GetCustomTlsState()->mMode) { auto dstMode = context.GetCustomTlsState()->mMode; if (srcMode == Mode::MODE_GENERATED) { // Layers snapshots produced by LayerTraceGenerator have srcMode == MODE_GENERATED // and should be written to tracing sessions with MODE_GENERATED // or MODE_GENERATED_BUGREPORT_ONLY. if (dstMode != Mode::MODE_GENERATED && dstMode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { return; } } else if (srcMode != dstMode) { return; } if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) { if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(srcMode, snapshot.vsync_id())) { return; } { Loading @@ -176,7 +211,7 @@ bool LayerTracing::checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::in // In some situations (e.g. two bugreports taken shortly one after the other) the generated // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make // sure that in generated tracing mode a given snapshot is written only once to perfetto. if (mode != Mode::MODE_GENERATED) { if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { return true; } Loading Loading
cmds/dumpstate/dumpstate.cpp +31 −54 Original line number Diff line number Diff line Loading @@ -1089,8 +1089,14 @@ static void MaybeAddSystemTraceToZip() { // This function copies into the .zip the system trace that was snapshotted // by the early call to MaybeSnapshotSystemTrace(), if any background // tracing was happening. if (!ds.has_system_trace_) { // No background trace was happening at the time dumpstate was invoked. bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; if (!system_trace_exists) { // No background trace was happening at the time MaybeSnapshotSystemTrace() was invoked. if (!PropertiesHelper::IsUserBuild()) { MYLOGI( "No system traces found. Check for previously uploaded traces by looking for " "go/trace-uuid in logcat") } return; } ds.AddZipEntry( Loading Loading @@ -1650,8 +1656,6 @@ Dumpstate::RunStatus Dumpstate::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 @@ -1861,12 +1865,6 @@ Dumpstate::RunStatus Dumpstate::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 @@ -3078,6 +3076,7 @@ void Dumpstate::Cancel() { } void Dumpstate::PreDumpUiData() { MaybeSnapshotSystemTrace(); MaybeSnapshotUiTraces(); } Loading Loading @@ -3264,25 +3263,23 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // duration is logged into MYLOG instead. PrintHeader(); bool is_dumpstate_restricted = options_->telephony_only || options_->wifi_only || options_->limited_only; if (!is_dumpstate_restricted) { // Invoke critical dumpsys first to preserve system state, before doing anything else. RunDumpsysCritical(); } MaybeTakeEarlyScreenshot(); bool is_dumpstate_restricted = options_->telephony_only || options_->wifi_only || options_->limited_only; if (!is_dumpstate_restricted) { // Snapshot the system trace now (if running) to avoid that dumpstate's // own activity pushes out interesting data from the trace ring buffer. // The trace file is added to the zip by MaybeAddSystemTraceToZip(). MaybeSnapshotSystemTrace(); // Invoke critical dumpsys to preserve system state, before doing anything else. RunDumpsysCritical(); // Snapshot the UI traces now (if running). // The trace files will be added to bugreport later. MaybeSnapshotUiTraces(); } MaybeTakeEarlyScreenshot(); onUiIntensiveBugreportDumpsFinished(calling_uid); MaybeCheckUserConsent(calling_uid, calling_package); if (options_->telephony_only) { Loading Loading @@ -3379,6 +3376,19 @@ void Dumpstate::MaybeTakeEarlyScreenshot() { } void Dumpstate::MaybeSnapshotSystemTrace() { // When capturing traces via bugreport handler (BH), this function will be invoked twice: // 1) When BH invokes IDumpstate::PreDumpUiData() // 2) When BH invokes IDumpstate::startBugreport(flags = BUGREPORT_USE_PREDUMPED_UI_DATA) // In this case we don't want to re-invoke perfetto in step 2. // In all other standard invocation states, this function is invoked once // without the flag BUGREPORT_USE_PREDUMPED_UI_DATA. if (options_->use_predumped_ui_data) { return; } // If a stale file exists already, remove it. unlink(SYSTEM_TRACE_SNAPSHOT); // If a background system trace is happening and is marked as "suitable for // bugreport" (i.e. bugreport_score > 0 in the trace config), this command // will stop it and serialize into SYSTEM_TRACE_SNAPSHOT. In the (likely) Loading @@ -3386,14 +3396,8 @@ void Dumpstate::MaybeSnapshotSystemTrace() { // Note: this should not be enqueued as we need to freeze the trace before // dumpstate starts. Otherwise the trace ring buffers will contain mostly // the dumpstate's own activity which is irrelevant. int res = RunCommand( "SERIALIZE PERFETTO TRACE", {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10) .DropRoot() .CloseAllFileDescriptorsOnExec() .Build()); has_system_trace_ = res == 0; RunCommand("SERIALIZE PERFETTO TRACE", {"perfetto", "--save-for-bugreport"}, CommandOptions::WithTimeout(10).DropRoot().CloseAllFileDescriptorsOnExec().Build()); // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip // file in the later stages. } Loading @@ -3420,33 +3424,6 @@ void Dumpstate::MaybeSnapshotUiTraces() { "", command, CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); } // This command needs to be run as root 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() { Loading
cmds/dumpstate/dumpstate.h +0 −6 Original line number Diff line number Diff line Loading @@ -476,11 +476,6 @@ class Dumpstate { // Whether it should take an screenshot earlier in the process. bool do_early_screenshot_ = false; // This is set to true when the trace snapshot request in the early call to // MaybeSnapshotSystemTrace(). When this is true, the later stages of // dumpstate will append the trace to the zip archive. bool has_system_trace_ = false; std::unique_ptr<Progress> progress_; // When set, defines a socket file-descriptor use to report progress to bugreportz Loading Loading @@ -574,7 +569,6 @@ class Dumpstate { void MaybeTakeEarlyScreenshot(); void MaybeSnapshotSystemTrace(); void MaybeSnapshotUiTraces(); void MaybePostProcessUiTraces(); void MaybeAddUiTracesToZip(); void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid); Loading
cmds/dumpstate/tests/dumpstate_test.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -1000,7 +1000,6 @@ TEST_F(DumpstateTest, DumpPool_withParallelRunDisabled_isNull) { TEST_F(DumpstateTest, PreDumpUiData) { // These traces are always enabled, i.e. they are always pre-dumped const std::vector<std::filesystem::path> uiTraces = { std::filesystem::path{"/data/misc/wmtrace/transactions_trace.winscope"}, std::filesystem::path{"/data/misc/wmtrace/wm_transition_trace.winscope"}, std::filesystem::path{"/data/misc/wmtrace/shell_transition_trace.winscope"}, }; Loading
services/surfaceflinger/Tracing/LayerDataSource.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -51,8 +51,9 @@ void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) { if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) { mMode = static_cast<LayerTracing::Mode>(config.mode()); } else { mMode = LayerTracing::Mode::MODE_GENERATED; ALOGD("Received config with unspecified 'mode'. Using 'GENERATED' as default"); mMode = LayerTracing::Mode::MODE_GENERATED_BUGREPORT_ONLY; ALOGD("Received config with unspecified 'mode'." " Using 'MODE_GENERATED_BUGREPORT_ONLY' as default"); } mFlags = 0; Loading @@ -68,10 +69,16 @@ void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) { } } void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs&) { ALOGD("Received OnFlush event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags); void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs& args) { ALOGD("Received OnFlush event" " (mode = 0x%02x, flags = 0x%02x, reason = 0x%" PRIx64 ", clone_target = 0x%0" PRIx64 ")", mMode, mFlags, args.flush_flags.reason(), args.flush_flags.clone_target()); bool isBugreport = args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone && args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport; if (auto* p = mLayerTracing.load()) { p->onFlush(mMode, mFlags); p->onFlush(mMode, mFlags, isBugreport); } } Loading
services/surfaceflinger/Tracing/LayerTracing.cpp +42 −7 Original line number Diff line number Diff line Loading @@ -67,9 +67,27 @@ void LayerTracing::onStart(Mode mode, uint32_t flags) { break; } case Mode::MODE_GENERATED: { // This tracing mode processes the buffer of transactions (owned by TransactionTracing), // generates layers snapshots and writes them to perfetto. This happens every time an // OnFlush event is received. ALOGD("Started generated tracing (waiting for OnFlush event to generated layers)"); break; } case Mode::MODE_GENERATED_BUGREPORT_ONLY: { // Same as MODE_GENERATED, but only when the received OnFlush event is due to a // bugreport being taken. This mode exists because the generated layers trace is very // large (hundreds of MB), hence we want to include it only in bugreports and not in // field uploads. // // Note that perfetto communicates only whether the OnFlush event is due to a bugreport // or not, hence we need an additional "bugreport only" tracing mode. // If perfetto had communicated when the OnFlush is due to a field upload, then we could // have had a single "generated" tracing mode that would have been a noop in case of // field uploads. ALOGD("Started 'generated bugreport only' tracing" " (waiting for bugreport's OnFlush event to generate layers)"); break; } case Mode::MODE_DUMP: { auto snapshot = mTakeLayersSnapshotProto(flags); addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP); Loading @@ -82,10 +100,18 @@ void LayerTracing::onStart(Mode mode, uint32_t flags) { } } void LayerTracing::onFlush(Mode mode, uint32_t flags) { void LayerTracing::onFlush(Mode mode, uint32_t flags, bool isBugreport) { // In "generated" mode process the buffer of transactions (owned by TransactionTracing), // generate a sequence of layers snapshots and write them to perfetto. if (mode != Mode::MODE_GENERATED) { // generate layers snapshots and write them to perfetto. if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { ALOGD("Skipping layers trace generation (not a 'generated' tracing session)"); return; } // In "generated bugreport only" mode skip the layers snapshot generation // if the perfetto's OnFlush event is not due to a bugreport being taken. if (mode == Mode::MODE_GENERATED_BUGREPORT_ONLY && !isBugreport) { ALOGD("Skipping layers trace generation (not a bugreport OnFlush event)"); return; } Loading Loading @@ -147,14 +173,23 @@ void LayerTracing::writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& } void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot, Mode mode) { Mode srcMode) { const auto snapshotBytes = snapshot.SerializeAsString(); LayerDataSource::Trace([&](LayerDataSource::TraceContext context) { if (mode != context.GetCustomTlsState()->mMode) { auto dstMode = context.GetCustomTlsState()->mMode; if (srcMode == Mode::MODE_GENERATED) { // Layers snapshots produced by LayerTraceGenerator have srcMode == MODE_GENERATED // and should be written to tracing sessions with MODE_GENERATED // or MODE_GENERATED_BUGREPORT_ONLY. if (dstMode != Mode::MODE_GENERATED && dstMode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { return; } } else if (srcMode != dstMode) { return; } if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) { if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(srcMode, snapshot.vsync_id())) { return; } { Loading @@ -176,7 +211,7 @@ bool LayerTracing::checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::in // In some situations (e.g. two bugreports taken shortly one after the other) the generated // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make // sure that in generated tracing mode a given snapshot is written only once to perfetto. if (mode != Mode::MODE_GENERATED) { if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) { return true; } Loading