| Index: components/metrics/call_stack_profile_metrics_provider.cc
|
| diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc
|
| index f96923bc5193d350be9fd8c96f922ab4cb725043..674af70afab108aa83ab2755caacd31fd28077c4 100644
|
| --- a/components/metrics/call_stack_profile_metrics_provider.cc
|
| +++ b/components/metrics/call_stack_profile_metrics_provider.cc
|
| @@ -8,8 +8,11 @@
|
| #include <map>
|
| #include <utility>
|
|
|
| +#include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/metrics/field_trial.h"
|
| #include "base/profiler/stack_sampling_profiler.h"
|
| #include "components/metrics/metrics_hashes.h"
|
| #include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
|
| @@ -20,6 +23,12 @@ namespace metrics {
|
|
|
| namespace {
|
|
|
| +// Accepts and ignores the completed profiles. Used when metrics reporting is
|
| +// disabled.
|
| +void IgnoreCompletedProfiles(
|
| + const StackSamplingProfiler::CallStackProfiles& profiles) {
|
| +}
|
| +
|
| // The protobuf expects the MD5 checksum prefix of the module name.
|
| uint64 HashModuleFilename(const base::FilePath& filename) {
|
| const base::FilePath::StringType basename = filename.BaseName().value();
|
| @@ -104,30 +113,80 @@ void CopyProfileToProto(
|
| proto_profile->set_sampling_period_ms(
|
| profile.sampling_period.InMilliseconds());
|
| }
|
| +
|
| } // namespace
|
|
|
| -CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() {}
|
| +const char CallStackProfileMetricsProvider::kFieldTrialName[] =
|
| + "StackProfiling";
|
| +const char CallStackProfileMetricsProvider::kReportProfilesGroupName[] =
|
| + "Report profiles";
|
| +
|
| +CallStackProfileMetricsProvider::CallStackProfileMetricsProvider()
|
| + : weak_factory_(this) {
|
| +}
|
| +
|
| +CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {
|
| + StackSamplingProfiler::SetDefaultCompletedCallback(
|
| + StackSamplingProfiler::CompletedCallback());
|
| +}
|
| +
|
| +void CallStackProfileMetricsProvider::OnRecordingEnabled() {
|
| + StackSamplingProfiler::SetDefaultCompletedCallback(
|
| + base::Bind(&CallStackProfileMetricsProvider::ReceiveCompletedProfiles,
|
| + base::MessageLoopProxy::current(),
|
| + weak_factory_.GetWeakPtr()));
|
| +}
|
|
|
| -CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() {}
|
| +void CallStackProfileMetricsProvider::OnRecordingDisabled() {
|
| + StackSamplingProfiler::SetDefaultCompletedCallback(
|
| + base::Bind(&IgnoreCompletedProfiles));
|
| + pending_profiles_.clear();
|
| +}
|
|
|
| void CallStackProfileMetricsProvider::ProvideGeneralMetrics(
|
| ChromeUserMetricsExtension* uma_proto) {
|
| - std::vector<StackSamplingProfiler::CallStackProfile> profiles;
|
| - if (!source_profiles_for_test_.empty())
|
| - profiles.swap(source_profiles_for_test_);
|
| - else
|
| - StackSamplingProfiler::GetPendingProfiles(&profiles);
|
| -
|
| - for (const StackSamplingProfiler::CallStackProfile& profile : profiles) {
|
| + DCHECK(IsSamplingProfilingReportingEnabled() || pending_profiles_.empty());
|
| + for (const StackSamplingProfiler::CallStackProfile& profile :
|
| + pending_profiles_) {
|
| CallStackProfile* call_stack_profile =
|
| uma_proto->add_sampled_profile()->mutable_call_stack_profile();
|
| CopyProfileToProto(profile, call_stack_profile);
|
| }
|
| + pending_profiles_.clear();
|
| }
|
|
|
| -void CallStackProfileMetricsProvider::SetSourceProfilesForTesting(
|
| +void CallStackProfileMetricsProvider::AppendSourceProfilesForTesting(
|
| const std::vector<StackSamplingProfiler::CallStackProfile>& profiles) {
|
| - source_profiles_for_test_ = profiles;
|
| + AppendCompletedProfiles(profiles);
|
| +}
|
| +
|
| +// static
|
| +bool CallStackProfileMetricsProvider::IsSamplingProfilingReportingEnabled() {
|
| + const std::string group_name = base::FieldTrialList::FindFullName(
|
| + CallStackProfileMetricsProvider::kFieldTrialName);
|
| + return group_name ==
|
| + CallStackProfileMetricsProvider::kReportProfilesGroupName;
|
| +}
|
| +
|
| +// static
|
| +// Posts a message back to our own thread to collect the profiles.
|
| +void CallStackProfileMetricsProvider::ReceiveCompletedProfiles(
|
| + scoped_refptr<base::MessageLoopProxy> message_loop,
|
| + base::WeakPtr<CallStackProfileMetricsProvider> provider,
|
| + const StackSamplingProfiler::CallStackProfiles& profiles) {
|
| + message_loop->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&CallStackProfileMetricsProvider::AppendCompletedProfiles,
|
| + provider, profiles));
|
| +}
|
| +
|
| +void CallStackProfileMetricsProvider::AppendCompletedProfiles(
|
| + const StackSamplingProfiler::CallStackProfiles& profiles) {
|
| + // Don't bother to record profiles if reporting is not enabled.
|
| + if (IsSamplingProfilingReportingEnabled()) {
|
| + pending_profiles_.insert(pending_profiles_.end(), profiles.begin(),
|
| + profiles.end());
|
| + }
|
| }
|
|
|
| } // namespace metrics
|
|
|