diff options
Diffstat (limited to 'chromium/content/browser/tracing')
16 files changed, 421 insertions, 123 deletions
diff --git a/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.cc b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.cc new file mode 100644 index 00000000000..a3c2857c3f8 --- /dev/null +++ b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.cc @@ -0,0 +1,101 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/tracing/background_reached_code_tracing_observer_android.h" + +#include "base/android/reached_code_profiler.h" +#include "base/no_destructor.h" +#include "base/strings/strcat.h" +#include "content/browser/tracing/background_tracing_rule.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "services/tracing/public/mojom/perfetto_service.mojom-forward.h" + +namespace content { + +namespace { + +const char kReachedCodeTracingConfig[] = "reached-code-config"; + +BackgroundReachedCodeTracingObserver* g_trace_log_for_testing = nullptr; + +} // namespace + +// static +BackgroundReachedCodeTracingObserver& +BackgroundReachedCodeTracingObserver::GetInstance() { + static base::NoDestructor<BackgroundReachedCodeTracingObserver> instance; + return *instance; +} + +// static +void BackgroundReachedCodeTracingObserver::ResetForTesting() { + if (!g_trace_log_for_testing) + return; + g_trace_log_for_testing->~BackgroundReachedCodeTracingObserver(); + new (g_trace_log_for_testing) BackgroundReachedCodeTracingObserver; +} + +BackgroundReachedCodeTracingObserver::BackgroundReachedCodeTracingObserver() + : enabled_in_current_session_( + base::android::IsReachedCodeProfilerEnabled()) { + g_trace_log_for_testing = this; +} + +BackgroundReachedCodeTracingObserver::~BackgroundReachedCodeTracingObserver() = + default; + +void BackgroundReachedCodeTracingObserver::OnScenarioActivated( + const BackgroundTracingConfigImpl* config) { + if (!enabled_in_current_session_) + return; + BackgroundTracingManagerImpl* manager = + BackgroundTracingManagerImpl::GetInstance(); + BackgroundTracingManager::TriggerHandle handle = + manager->RegisterTriggerType(kReachedCodeTracingConfig); + + BackgroundTracingManagerImpl::GetInstance()->TriggerNamedEvent( + handle, BackgroundTracingManager::StartedFinalizingCallback()); +} + +void BackgroundReachedCodeTracingObserver::OnScenarioAborted() { + enabled_in_current_session_ = false; +} + +void BackgroundReachedCodeTracingObserver::OnTracingEnabled( + BackgroundTracingConfigImpl::CategoryPreset preset) {} + +std::unique_ptr<BackgroundTracingConfigImpl> +BackgroundReachedCodeTracingObserver::IncludeReachedCodeConfigIfNeeded( + std::unique_ptr<BackgroundTracingConfigImpl> config) { + if (!enabled_in_current_session_) { + return config; + } + + if (config) { + enabled_in_current_session_ = false; + return config; + } + + auto rules_dict = std::make_unique<base::DictionaryValue>(); + rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED"); + rules_dict->SetString("trigger_name", kReachedCodeTracingConfig); + rules_dict->SetInteger("trigger_delay", 30); + + base::DictionaryValue dict; + auto rules_list = std::make_unique<base::ListValue>(); + rules_list->Append(std::move(rules_dict)); + dict.Set("configs", std::move(rules_list)); + dict.SetString( + "enabled_data_sources", + base::StrCat({tracing::mojom::kMetaDataSourceName, ",", + tracing::mojom::kReachedCodeProfilerSourceName})); + dict.SetString("category", "CUSTOM"); + dict.SetString("custom_categories", "-*"); + + config = BackgroundTracingConfigImpl::ReactiveFromDict(&dict); + return config; +} + +} // namespace content diff --git a/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.h b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.h new file mode 100644 index 00000000000..a65aa79c438 --- /dev/null +++ b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android.h @@ -0,0 +1,52 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_TRACING_BACKGROUND_REACHED_CODE_TRACING_OBSERVER_ANDROID_H_ +#define CONTENT_BROWSER_TRACING_BACKGROUND_REACHED_CODE_TRACING_OBSERVER_ANDROID_H_ + +#include <memory> + +#include "content/browser/tracing/background_tracing_manager_impl.h" + +namespace content { + +// Observes for reached code tracing config and sets up background tracing +// scenario to profile reached code. +class CONTENT_EXPORT BackgroundReachedCodeTracingObserver + : public BackgroundTracingManagerImpl::EnabledStateObserver { + public: + static BackgroundReachedCodeTracingObserver& GetInstance(); + + static void ResetForTesting(); + + // BackgroundTracingManagerImpl::EnabledStateObserver implementation. + void OnScenarioActivated(const BackgroundTracingConfigImpl* config) override; + void OnScenarioAborted() override; + void OnTracingEnabled( + BackgroundTracingConfigImpl::CategoryPreset preset) override; + + std::unique_ptr<BackgroundTracingConfigImpl> IncludeReachedCodeConfigIfNeeded( + std::unique_ptr<BackgroundTracingConfigImpl> config); + + bool enabled_in_current_session() const { + return enabled_in_current_session_; + } + + BackgroundReachedCodeTracingObserver(BackgroundReachedCodeTracingObserver&&) = + delete; + BackgroundReachedCodeTracingObserver& operator=( + BackgroundReachedCodeTracingObserver&&) = delete; + + private: + friend class base::NoDestructor<BackgroundReachedCodeTracingObserver>; + + BackgroundReachedCodeTracingObserver(); + ~BackgroundReachedCodeTracingObserver() override; + + bool enabled_in_current_session_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_TRACING_BACKGROUND_REACHED_CODE_TRACING_OBSERVER_ANDROID_H_ diff --git a/chromium/content/browser/tracing/background_reached_code_tracing_observer_android_unittest.cc b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android_unittest.cc new file mode 100644 index 00000000000..9a021655b25 --- /dev/null +++ b/chromium/content/browser/tracing/background_reached_code_tracing_observer_android_unittest.cc @@ -0,0 +1,167 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/tracing/background_reached_code_tracing_observer_android.h" + +#include "base/android/reached_code_profiler.h" +#include "base/base_switches.h" +#include "base/command_line.h" +#include "content/browser/tracing/background_tracing_rule.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { +namespace { + +bool EnableReachedCodeProfiler() { + if (!base::android::IsReachedCodeProfilerSupported()) + return false; + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableReachedCodeProfiler); + base::android::InitReachedCodeProfilerAtStartup( + base::android::PROCESS_BROWSER); + EXPECT_TRUE(base::android::IsReachedCodeProfilerEnabled); + return true; +} + +const BackgroundTracingRule* FindReachedCodeRuleInConfig( + const BackgroundTracingConfigImpl& config) { + for (const auto& rule : config.rules()) { + if (rule->rule_id().find("reached-code-config") != std::string::npos) { + return rule.get(); + } + } + return nullptr; +} + +std::unique_ptr<BackgroundTracingConfigImpl> GetGpuConfig() { + auto rules_dict = std::make_unique<base::DictionaryValue>(); + rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED"); + rules_dict->SetString("trigger_name", "test"); + rules_dict->SetString("category", "BENCHMARK_GPU"); + base::DictionaryValue dict; + auto rules_list = std::make_unique<base::ListValue>(); + rules_list->Append(std::move(rules_dict)); + dict.Set("configs", std::move(rules_list)); + return BackgroundTracingConfigImpl::ReactiveFromDict(&dict); +} + +std::unique_ptr<BackgroundTracingConfigImpl> GetReachedCodeConfig() { + auto rules_dict = std::make_unique<base::DictionaryValue>(); + rules_dict->SetString("rule", "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED"); + rules_dict->SetString("trigger_name", "reached-code-config"); + rules_dict->SetInteger("trigger_delay", 30); + + base::DictionaryValue dict; + auto rules_list = std::make_unique<base::ListValue>(); + rules_list->Append(std::move(rules_dict)); + dict.Set("configs", std::move(rules_list)); + dict.SetString( + "enabled_data_sources", + "org.chromium.trace_metadata,org.chromium.reached_code_profiler"); + dict.SetString("category", "CUSTOM"); + dict.SetString("custom_categories", "-*"); + auto config = BackgroundTracingConfigImpl::ReactiveFromDict(&dict); + EXPECT_TRUE(FindReachedCodeRuleInConfig(*config)); + return config; +} + +void TestReachedCodeRuleExists(const BackgroundTracingConfigImpl& config, + bool exists) { + const auto* rule = FindReachedCodeRuleInConfig(config); + if (exists) { + ASSERT_TRUE(rule); + EXPECT_EQ(30, rule->GetTraceDelay()); + EXPECT_FALSE(rule->stop_tracing_on_repeated_reactive()); + EXPECT_EQ("org.chromium.trace_metadata,org.chromium.reached_code_profiler", + config.enabled_data_sources()); + } else { + EXPECT_FALSE(rule); + } +} + +void TestGpuConfigExists(const BackgroundTracingConfigImpl& config) { + bool found_gpu = false; + for (const auto& rule : config.rules()) { + if (rule->category_preset() == + BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_GPU) { + found_gpu = true; + } + } + EXPECT_TRUE(found_gpu); +} + +} // namespace + +TEST(BackgroundReachedCodeTracingObserverTest, + IncludeReachedCodeConfigIfNeeded) { + EXPECT_FALSE(base::android::IsReachedCodeProfilerEnabled()); + BackgroundReachedCodeTracingObserver& observer = + BackgroundReachedCodeTracingObserver::GetInstance(); + + // Empty config without profiler set should not do anything. + std::unique_ptr<content::BackgroundTracingConfigImpl> config_impl; + config_impl = observer.IncludeReachedCodeConfigIfNeeded(nullptr); + EXPECT_FALSE(config_impl); + EXPECT_FALSE(observer.enabled_in_current_session()); + EXPECT_FALSE(base::android::IsReachedCodeProfilerEnabled()); + + // A GPU config without preference set should not set preference and keep + // config same. + config_impl = GetGpuConfig(); + ASSERT_TRUE(config_impl); + + EXPECT_FALSE(base::android::IsReachedCodeProfilerEnabled()); + config_impl = + observer.IncludeReachedCodeConfigIfNeeded(std::move(config_impl)); + EXPECT_FALSE(observer.enabled_in_current_session()); + EXPECT_FALSE(base::android::IsReachedCodeProfilerEnabled()); + EXPECT_EQ(1u, config_impl->rules().size()); + TestReachedCodeRuleExists(*config_impl, false); + TestGpuConfigExists(*config_impl); + + // A reached code config without profiler should stay config same. + config_impl = GetReachedCodeConfig(); + config_impl = + observer.IncludeReachedCodeConfigIfNeeded(std::move(config_impl)); + EXPECT_FALSE(observer.enabled_in_current_session()); + ASSERT_TRUE(config_impl); + EXPECT_FALSE(base::android::IsReachedCodeProfilerEnabled()); + EXPECT_EQ(1u, config_impl->rules().size()); + TestReachedCodeRuleExists(*config_impl, true); + + if (!base::android::IsReachedCodeProfilerSupported()) + return; + config_impl.reset(); + EXPECT_TRUE(EnableReachedCodeProfiler()); + BackgroundReachedCodeTracingObserver::ResetForTesting(); + EXPECT_TRUE(observer.enabled_in_current_session()); + + // Empty config with profiler should create a config. + EXPECT_TRUE(base::android::IsReachedCodeProfilerEnabled()); + config_impl = + observer.IncludeReachedCodeConfigIfNeeded(std::move(config_impl)); + EXPECT_TRUE(base::android::IsReachedCodeProfilerEnabled()); + EXPECT_TRUE(observer.enabled_in_current_session()); + ASSERT_TRUE(config_impl); + EXPECT_EQ(1u, config_impl->rules().size()); + EXPECT_EQ(BackgroundTracingConfig::TracingMode::REACTIVE, + config_impl->tracing_mode()); + TestReachedCodeRuleExists(*config_impl, true); + + // A GPU config with profiler on should not enabled reached code config. + config_impl = GetGpuConfig(); + config_impl = + observer.IncludeReachedCodeConfigIfNeeded(std::move(config_impl)); + EXPECT_FALSE(observer.enabled_in_current_session()); + ASSERT_TRUE(config_impl); + EXPECT_TRUE(base::android::IsReachedCodeProfilerEnabled()); + EXPECT_EQ(1u, config_impl->rules().size()); + EXPECT_EQ(BackgroundTracingConfig::TracingMode::REACTIVE, + config_impl->tracing_mode()); + TestReachedCodeRuleExists(*config_impl, false); + + TestGpuConfigExists(*config_impl); +} + +} // namespace content diff --git a/chromium/content/browser/tracing/background_startup_tracing_observer.cc b/chromium/content/browser/tracing/background_startup_tracing_observer.cc index 72c32bb600b..cc70f4690fc 100644 --- a/chromium/content/browser/tracing/background_startup_tracing_observer.cc +++ b/chromium/content/browser/tracing/background_startup_tracing_observer.cc @@ -5,7 +5,6 @@ #include "content/browser/tracing/background_startup_tracing_observer.h" #include "base/bind.h" -#include "base/task/post_task.h" #include "components/tracing/common/trace_startup_config.h" #include "content/browser/tracing/background_tracing_rule.h" #include "content/public/browser/browser_task_traits.h" @@ -68,8 +67,8 @@ void BackgroundStartupTracingObserver::OnScenarioActivated( DCHECK(startup_rule); // Post task to avoid reentrancy. - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &BackgroundTracingManagerImpl::OnRuleTriggered, base::Unretained(BackgroundTracingManagerImpl::GetInstance()), diff --git a/chromium/content/browser/tracing/background_tracing_active_scenario.cc b/chromium/content/browser/tracing/background_tracing_active_scenario.cc index ba985c5ff0f..1e044de7bf1 100644 --- a/chromium/content/browser/tracing/background_tracing_active_scenario.cc +++ b/chromium/content/browser/tracing/background_tracing_active_scenario.cc @@ -12,6 +12,7 @@ #include "base/memory/ref_counted_memory.h" #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" +#include "base/strings/string_tokenizer.h" #include "base/timer/timer.h" #include "build/build_config.h" #include "content/browser/tracing/background_tracing_config_impl.h" @@ -78,7 +79,7 @@ class PerfettoTracingSession public: PerfettoTracingSession(BackgroundTracingActiveScenario* parent_scenario, const TraceConfig& chrome_config, - int interning_reset_interval_ms) + const BackgroundTracingConfigImpl* config) : parent_scenario_(parent_scenario), raw_data_(std::make_unique<std::string>()) { #if !defined(OS_ANDROID) @@ -95,10 +96,17 @@ class PerfettoTracingSession GetTracingService().BindConsumerHost( consumer_host_.BindNewPipeAndPassReceiver()); - perfetto::TraceConfig perfetto_config = tracing::GetDefaultPerfettoConfig( - chrome_config, /*privacy_filtering_enabled=*/true); + perfetto::TraceConfig perfetto_config; perfetto_config.mutable_incremental_state_config()->set_clear_period_ms( - interning_reset_interval_ms); + config->interning_reset_interval_ms()); + base::StringTokenizer data_sources(config->enabled_data_sources(), ","); + std::set<std::string> data_source_filter; + while (data_sources.GetNext()) { + data_source_filter.insert(data_sources.token()); + } + perfetto_config = tracing::GetPerfettoConfigWithDataSources( + chrome_config, data_source_filter, + /*privacy_filtering_enabled=*/true); consumer_host_->EnableTracing( tracing_session_host_.BindNewPipeAndPassReceiver(), @@ -374,7 +382,7 @@ bool BackgroundTracingActiveScenario::StartTracing() { DCHECK(!tracing_session_); if (base::FeatureList::IsEnabled(features::kBackgroundTracingProtoOutput)) { tracing_session_ = std::make_unique<PerfettoTracingSession>( - this, chrome_config, config_->interning_reset_interval_ms()); + this, chrome_config, config_.get()); } else { tracing_session_ = std::make_unique<LegacyTracingSession>(this, chrome_config); diff --git a/chromium/content/browser/tracing/background_tracing_config_impl.cc b/chromium/content/browser/tracing/background_tracing_config_impl.cc index a74a0129ef4..2fe283bebea 100644 --- a/chromium/content/browser/tracing/background_tracing_config_impl.cc +++ b/chromium/content/browser/tracing/background_tracing_config_impl.cc @@ -33,6 +33,7 @@ const char kConfigModeSystem[] = "SYSTEM_TRACING_MODE"; const char kConfigScenarioName[] = "scenario_name"; const char kConfigTraceBrowserProcessOnly[] = "trace_browser_process_only"; +const char kEnabledDataSourcesKey[] = "enabled_data_sources"; const char kConfigCategoryKey[] = "category"; const char kConfigCustomCategoriesKey[] = "custom_categories"; @@ -202,6 +203,9 @@ void BackgroundTracingConfigImpl::IntoDict(base::DictionaryValue* dict) { dict->SetKey(kConfigTraceConfigKey, std::move(*trace_config)); } } + if (!enabled_data_sources_.empty()) { + dict->SetString(kEnabledDataSourcesKey, enabled_data_sources_); + } switch (tracing_mode()) { case BackgroundTracingConfigImpl::PREEMPTIVE: @@ -361,6 +365,10 @@ BackgroundTracingConfigImpl::PreemptiveFromDict( return nullptr; } } + if (const std::string* enabled_data_sources = + dict->FindStringKey(kEnabledDataSourcesKey)) { + config->enabled_data_sources_ = *enabled_data_sources; + } const base::ListValue* configs_list = nullptr; if (!dict->GetList(kConfigsKey, &configs_list)) @@ -408,6 +416,11 @@ BackgroundTracingConfigImpl::ReactiveFromDict( has_global_categories = true; } + if (const std::string* enabled_data_sources = + dict->FindStringKey(kEnabledDataSourcesKey)) { + config->enabled_data_sources_ = *enabled_data_sources; + } + const base::ListValue* configs_list = nullptr; if (!dict->GetList(kConfigsKey, &configs_list)) return nullptr; diff --git a/chromium/content/browser/tracing/background_tracing_config_impl.h b/chromium/content/browser/tracing/background_tracing_config_impl.h index b1a4ac8a278..844df6a00bb 100644 --- a/chromium/content/browser/tracing/background_tracing_config_impl.h +++ b/chromium/content/browser/tracing/background_tracing_config_impl.h @@ -46,7 +46,7 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl BENCHMARK_RENDERERS, BENCHMARK_SERVICEWORKER, BENCHMARK_POWER, - BLINK_STYLE + BLINK_STYLE, }; CategoryPreset category_preset() const { return category_preset_; } @@ -66,6 +66,9 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl void AddSystemRule(const base::DictionaryValue* dict); base::trace_event::TraceConfig GetTraceConfig() const; + const std::string& enabled_data_sources() const { + return enabled_data_sources_; + } size_t GetTraceUploadLimitKb() const; int interning_reset_interval_ms() const { @@ -120,6 +123,7 @@ class CONTENT_EXPORT BackgroundTracingConfigImpl std::vector<std::unique_ptr<BackgroundTracingRule>> rules_; std::string scenario_name_; std::string custom_categories_; + std::string enabled_data_sources_; bool requires_anonymized_data_ = false; bool trace_browser_process_only_ = false; diff --git a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc index 9e96304ecbe..23409f7d9cc 100644 --- a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc +++ b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc @@ -22,7 +22,6 @@ #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_tokenizer.h" -#include "base/task/post_task.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_timeouts.h" #include "base/test/trace_event_analyzer.h" @@ -299,11 +298,11 @@ class TestTraceReceiverHelper { file_contents_.assign(output_str.data(), bytes_written); // Post the callbacks. - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(done_callback), true)); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(done_callback), true)); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - wait_for_trace_received_.QuitWhenIdleClosure()); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, wait_for_trace_received_.QuitWhenIdleClosure()); } private: @@ -535,9 +534,9 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, EXPECT_TRUE(trace_receiver_helper.trace_received()); } -// This tests that non-whitelisted args get stripped if required. +// This tests that non-allowlisted args get stripped if required. IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, - NotWhitelistedArgsStripped) { + NotAllowlistedArgsStripped) { TestTraceReceiverHelper trace_receiver_helper; TestBackgroundTracingHelper background_tracing_helper; @@ -553,8 +552,8 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, background_tracing_helper.WaitForTracingEnabled(); { - TRACE_EVENT1("benchmark", "TestWhitelist", "test_whitelist", "abc"); - TRACE_EVENT1("benchmark", "TestNotWhitelist", "test_not_whitelist", "abc"); + TRACE_EVENT1("benchmark", "TestAllowlist", "test_allowlist", "abc"); + TRACE_EVENT1("benchmark", "TestNotAllowlist", "test_not_allowlist", "abc"); } TestTriggerHelper trigger_helper; @@ -568,9 +567,9 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, EXPECT_TRUE(trace_receiver_helper.trace_received()); EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("{")); - EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("test_whitelist")); + EXPECT_TRUE(trace_receiver_helper.TraceHasMatchingString("test_allowlist")); EXPECT_FALSE( - trace_receiver_helper.TraceHasMatchingString("test_not_whitelist")); + trace_receiver_helper.TraceHasMatchingString("test_not_allowlist")); } // Tests that events emitted by the browser process immediately after the diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.cc b/chromium/content/browser/tracing/background_tracing_manager_impl.cc index 720c216b055..42225d2d888 100644 --- a/chromium/content/browser/tracing/background_tracing_manager_impl.cc +++ b/chromium/content/browser/tracing/background_tracing_manager_impl.cc @@ -14,10 +14,10 @@ #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/single_thread_task_runner.h" -#include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/values.h" +#include "build/build_config.h" #include "components/tracing/common/trace_startup_config.h" #include "content/browser/tracing/background_memory_tracing_observer.h" #include "content/browser/tracing/background_startup_tracing_observer.h" @@ -40,6 +40,10 @@ #include "services/tracing/public/cpp/trace_event_agent.h" #include "services/tracing/public/cpp/tracing_features.h" +#if defined(OS_ANDROID) +#include "content/browser/tracing/background_reached_code_tracing_observer_android.h" +#endif + namespace content { // static @@ -70,8 +74,8 @@ void BackgroundTracingManagerImpl::ActivateForProcess( child_process->GetBackgroundTracingAgentProvider( pending_provider.InitWithNewPipeAndPassReceiver()); - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&BackgroundTracingManagerImpl::AddPendingAgent, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&BackgroundTracingManagerImpl::AddPendingAgent, child_process_id, std::move(pending_provider))); } @@ -80,6 +84,9 @@ BackgroundTracingManagerImpl::BackgroundTracingManagerImpl() trigger_handle_ids_(0) { AddEnabledStateObserver(BackgroundMemoryTracingObserver::GetInstance()); AddEnabledStateObserver(BackgroundStartupTracingObserver::GetInstance()); +#if defined(OS_ANDROID) + AddEnabledStateObserver(&BackgroundReachedCodeTracingObserver::GetInstance()); +#endif } BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() = default; @@ -120,6 +127,10 @@ bool BackgroundTracingManagerImpl::SetActiveScenario( static_cast<BackgroundTracingConfigImpl*>(config.release())); config_impl = BackgroundStartupTracingObserver::GetInstance() ->IncludeStartupConfigIfNeeded(std::move(config_impl)); +#if defined(OS_ANDROID) + config_impl = BackgroundReachedCodeTracingObserver::GetInstance() + .IncludeReachedCodeConfigIfNeeded(std::move(config_impl)); +#endif if (BackgroundStartupTracingObserver::GetInstance() ->enabled_in_current_session()) { // Anonymize data for startup tracing by default. We currently do not @@ -322,8 +333,8 @@ void BackgroundTracingManagerImpl::TriggerNamedEvent( BackgroundTracingManagerImpl::TriggerHandle handle, StartedFinalizingCallback callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&BackgroundTracingManagerImpl::TriggerNamedEvent, base::Unretained(this), handle, std::move(callback))); return; diff --git a/chromium/content/browser/tracing/background_tracing_rule.cc b/chromium/content/browser/tracing/background_tracing_rule.cc index a42a5ebaa35..45319ec0eff 100644 --- a/chromium/content/browser/tracing/background_tracing_rule.cc +++ b/chromium/content/browser/tracing/background_tracing_rule.cc @@ -13,7 +13,6 @@ #include "base/rand_util.h" #include "base/strings/safe_sprintf.h" #include "base/strings/strcat.h" -#include "base/task/post_task.h" #include "base/timer/timer.h" #include "base/trace_event/trace_event.h" #include "base/values.h" @@ -170,6 +169,8 @@ class NamedTriggerRule : public BackgroundTracingRule { named_rule->set_event_type(MetadataProto::NamedRule::NAVIGATION); } else if (named_event_ == "session-restore-config") { named_rule->set_event_type(MetadataProto::NamedRule::SESSION_RESTORE); + } else if (named_event_ == "reached-code-config") { + named_rule->set_event_type(MetadataProto::NamedRule::REACHED_CODE); } else if (named_event_ == "preemptive_test") { named_rule->set_event_type(MetadataProto::NamedRule::TEST_RULE); } @@ -283,8 +284,8 @@ class HistogramRule : public BackgroundTracingRule, if (histogram_name != histogram_name_) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &BackgroundTracingManagerImpl::OnRuleTriggered, base::Unretained(BackgroundTracingManagerImpl::GetInstance()), this, @@ -292,8 +293,8 @@ class HistogramRule : public BackgroundTracingRule, } void AbortTracing() { - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce( &BackgroundTracingManagerImpl::AbortScenario, base::Unretained(BackgroundTracingManagerImpl::GetInstance()))); diff --git a/chromium/content/browser/tracing/cros_tracing_agent.cc b/chromium/content/browser/tracing/cros_tracing_agent.cc index 598d6ce2cb1..d711592a289 100644 --- a/chromium/content/browser/tracing/cros_tracing_agent.cc +++ b/chromium/content/browser/tracing/cros_tracing_agent.cc @@ -13,12 +13,12 @@ #include "base/memory/ref_counted_memory.h" #include "base/no_destructor.h" #include "base/sequence_checker.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/trace_event/trace_config.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/debug_daemon/debug_daemon_client.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/system_trace_writer.h" #include "services/tracing/public/mojom/constants.mojom.h" @@ -106,16 +106,16 @@ class CrOSDataSource : public tracing::PerfettoTracedProcess::DataSourceBase { void StartTracing( tracing::PerfettoProducer* perfetto_producer, const perfetto::DataSourceConfig& data_source_config) override { - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&CrOSDataSource::StartTracingOnUI, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CrOSDataSource::StartTracingOnUI, base::Unretained(this), perfetto_producer, data_source_config)); } // Called from the tracing::PerfettoProducer on its sequence. void StopTracing(base::OnceClosure stop_complete_callback) override { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CrOSDataSource::StopTracingOnUI, base::Unretained(this), std::move(stop_complete_callback))); } @@ -191,8 +191,8 @@ class CrOSDataSource : public tracing::PerfettoTracedProcess::DataSourceBase { trace_writer_.reset(); // Destruction and reset of fields should happen on the UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CrOSDataSource::OnTraceDataOnUI, base::Unretained(this), std::move(stop_complete_callback))); } diff --git a/chromium/content/browser/tracing/tracing_controller_browsertest.cc b/chromium/content/browser/tracing/tracing_controller_browsertest.cc index 586e2227f02..662da436399 100644 --- a/chromium/content/browser/tracing/tracing_controller_browsertest.cc +++ b/chromium/content/browser/tracing/tracing_controller_browsertest.cc @@ -13,7 +13,6 @@ #include "base/memory/ref_counted_memory.h" #include "base/run_loop.h" #include "base/strings/pattern.h" -#include "base/task/post_task.h" #include "base/task/task_traits.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" @@ -81,8 +80,8 @@ class TracingControllerTestEndpoint } void ReceivedTraceFinalContents() override { - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(done_callback_), std::make_unique<std::string>(std::move(trace_)))); } diff --git a/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc b/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc index 98c312de2c8..9bc2eee77af 100644 --- a/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc +++ b/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc @@ -10,7 +10,6 @@ #include "base/memory/ref_counted_memory.h" #include "base/sequenced_task_runner.h" #include "base/strings/pattern.h" -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h" #include "content/browser/tracing/tracing_controller_impl.h" @@ -34,8 +33,8 @@ class StringTraceDataEndpoint : public TracingController::TraceDataEndpoint { trace_.str(""); trace_.clear(); - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(completion_callback_), std::move(str))); } @@ -86,11 +85,14 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint { } bool OpenFileIfNeededOnBlockingThread() { - base::ScopedBlockingCall scoped_blocking_call( - FROM_HERE, base::BlockingType::MAY_BLOCK); if (file_ != nullptr) return true; - file_ = base::OpenFile(file_path_, "w"); + + // The temporary trace file is produced in the same folder since paths must + // be on the same volume. + file_ = FileToFILE(CreateAndOpenTemporaryFileInDir(file_path_.DirName(), + &pending_file_path_), + "w"); if (file_ == nullptr) { LOG(ERROR) << "Failed to open " << file_path_.value(); return false; @@ -104,14 +106,23 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint { file_ = nullptr; } - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + base::File::Error error; + if (!base::ReplaceFile(pending_file_path_, file_path_, &error)) { + LOG(ERROR) << "Cannot replace file '" << file_path_ + << "' : " << base::File::ErrorToString(error); + base::DeleteFile(pending_file_path_, false); + return; + } + + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FileTraceDataEndpoint::FinalizeOnUIThread, this)); } void FinalizeOnUIThread() { std::move(completion_callback_).Run(); } base::FilePath file_path_; + base::FilePath pending_file_path_; base::OnceClosure completion_callback_; FILE* file_ = nullptr; const scoped_refptr<base::SequencedTaskRunner> may_block_task_runner_; diff --git a/chromium/content/browser/tracing/tracing_service_controller.cc b/chromium/content/browser/tracing/tracing_service_controller.cc index a7646b2f94f..c4b0fe4fae1 100644 --- a/chromium/content/browser/tracing/tracing_service_controller.cc +++ b/chromium/content/browser/tracing/tracing_service_controller.cc @@ -6,7 +6,6 @@ #include <utility> -#include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/time/time.h" #include "content/public/browser/browser_task_traits.h" @@ -62,8 +61,8 @@ TracingServiceController::RegisterClient(base::ProcessId pid, if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { // Force registration to happen on the UI thread. - base::PostTask( - FROM_HERE, {BrowserThread::UI}, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&TracingServiceController::RegisterClientOnUIThread, base::Unretained(this), pid, std::move(callback))); } else { @@ -133,8 +132,8 @@ void TracingServiceController::RegisterClientOnUIThread( void TracingServiceController::RemoveClient(base::ProcessId pid) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&TracingServiceController::RemoveClient, + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&TracingServiceController::RemoveClient, base::Unretained(this), pid)); return; } diff --git a/chromium/content/browser/tracing/tracing_ui.cc b/chromium/content/browser/tracing/tracing_ui.cc index df50d378560..c1b65f1e2c4 100644 --- a/chromium/content/browser/tracing/tracing_ui.cc +++ b/chromium/content/browser/tracing/tracing_ui.cc @@ -80,21 +80,6 @@ void OnTraceBufferUsageResult(WebUIDataSource::GotDataCallback callback, std::move(callback).Run(base::RefCountedString::TakeString(&str)); } -void OnTraceBufferStatusResult(WebUIDataSource::GotDataCallback callback, - float percent_full, - size_t approximate_event_count) { - base::DictionaryValue status; - status.SetDouble("percentFull", percent_full); - status.SetInteger("approximateEventCount", approximate_event_count); - - std::string status_json; - base::JSONWriter::Write(status, &status_json); - - base::RefCountedString* status_base64 = new base::RefCountedString(); - base::Base64Encode(status_json, &status_base64->data()); - std::move(callback).Run(status_base64); -} - void TracingCallbackWrapperBase64(WebUIDataSource::GotDataCallback callback, std::unique_ptr<std::string> data) { base::RefCountedString* data_base64 = new base::RefCountedString(); @@ -119,10 +104,6 @@ bool OnBeginJSONRequest(const std::string& path, return TracingController::GetInstance()->GetTraceBufferUsage( base::BindOnce(OnTraceBufferUsageResult, std::move(callback))); } - if (path == "json/get_buffer_status") { - return TracingController::GetInstance()->GetTraceBufferUsage( - base::BindOnce(OnTraceBufferStatusResult, std::move(callback))); - } if (path == "json/end_recording_compressed") { if (!TracingController::GetInstance()->IsTracing()) return false; @@ -213,30 +194,7 @@ bool TracingUI::GetTracingOptions( } // New style options dictionary. - if (options->HasKey("included_categories")) { - *trace_config = base::trace_event::TraceConfig(*options); - return true; - } - - bool options_ok = true; - std::string category_filter_string; - options_ok &= options->GetString("categoryFilter", &category_filter_string); - - std::string record_mode; - options_ok &= options->GetString("tracingRecordMode", &record_mode); - - *trace_config = - base::trace_event::TraceConfig(category_filter_string, record_mode); - - bool enable_systrace; - options_ok &= options->GetBoolean("useSystemTracing", &enable_systrace); - if (enable_systrace) - trace_config->EnableSystrace(); - - if (!options_ok) { - LOG(ERROR) << "Malformed options"; - return false; - } + *trace_config = base::trace_event::TraceConfig(*options); return true; } diff --git a/chromium/content/browser/tracing/tracing_ui_unittest.cc b/chromium/content/browser/tracing/tracing_ui_unittest.cc index c671230b728..431949fec9c 100644 --- a/chromium/content/browser/tracing/tracing_ui_unittest.cc +++ b/chromium/content/browser/tracing/tracing_ui_unittest.cc @@ -20,22 +20,7 @@ class TracingUITest : public testing::Test { TracingUITest() {} }; -std::string GetOldStyleConfig() { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("categoryFilter", "filter1,-filter2"); - dict->SetString("tracingRecordMode", "record-continuously"); - dict->SetBoolean("useSystemTracing", true); - - std::string results; - if (!base::JSONWriter::Write(*dict.get(), &results)) - return ""; - - std::string data; - base::Base64Encode(results, &data); - return data; -} - -std::string GetNewStyleConfig() { +std::string GetConfig() { std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); std::unique_ptr<base::Value> filter1( new base::Value(base::trace_event::MemoryDumpManager::kTraceCategory)); @@ -69,18 +54,9 @@ std::string GetNewStyleConfig() { return data; } -TEST_F(TracingUITest, OldStyleConfig) { - base::trace_event::TraceConfig config; - ASSERT_TRUE(TracingUI::GetTracingOptions(GetOldStyleConfig(), &config)); - EXPECT_EQ(config.GetTraceRecordMode(), - base::trace_event::RECORD_CONTINUOUSLY); - EXPECT_EQ(config.ToCategoryFilterString(), "filter1,-filter2"); - EXPECT_TRUE(config.IsSystraceEnabled()); -} - -TEST_F(TracingUITest, NewStyleConfig) { +TEST_F(TracingUITest, ConfigParsing) { base::trace_event::TraceConfig config; - ASSERT_TRUE(TracingUI::GetTracingOptions(GetNewStyleConfig(), &config)); + ASSERT_TRUE(TracingUI::GetTracingOptions(GetConfig(), &config)); EXPECT_EQ(config.GetTraceRecordMode(), base::trace_event::RECORD_CONTINUOUSLY); std::string expected(base::trace_event::MemoryDumpManager::kTraceCategory); |