| // Copyright 2014 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 "chrome/browser/metrics/android_metrics_provider.h" |
| |
| #include "base/metrics/histogram.h" |
| #include "base/prefs/pref_registry_simple.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/prefs/scoped_user_pref_update.h" |
| #include "base/values.h" |
| #include "chrome/common/pref_names.h" |
| |
| namespace { |
| |
| // Increments a particular entry in the ListValue. |
| void IncrementListValue(base::ListValue* counts, int index) { |
| int current_count = 0; |
| counts->GetInteger(index, ¤t_count); |
| counts->Set(index, new base::FundamentalValue(current_count + 1)); |
| } |
| |
| // Takes an int corresponding to a Type and returns the corresponding flag. |
| int GetActivityFlag(int type_id) { |
| ActivityTypeIds::Type type = ActivityTypeIds::GetActivityType(type_id); |
| DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE); |
| return (1 << type); |
| } |
| |
| } // namespace |
| |
| AndroidMetricsProvider::AndroidMetricsProvider(PrefService* local_state) |
| : local_state_(local_state) { |
| LogStabilityToPrefs(); |
| } |
| |
| AndroidMetricsProvider::~AndroidMetricsProvider() { |
| } |
| |
| |
| void AndroidMetricsProvider::ProvideStabilityMetrics( |
| metrics::SystemProfileProto* system_profile_proto) { |
| ConvertStabilityPrefsToHistograms(); |
| } |
| |
| void AndroidMetricsProvider::LogStabilityToPrefs() { |
| // Track which Activities were launched by the user. |
| // A 'launch' is defined as starting the Activity at least once during a |
| // UMA session. Multiple launches are counted only once since it is possible |
| // for users to hop between Activities (e.g. entering and leaving Settings). |
| const int launched = |
| local_state_->GetInteger(prefs::kStabilityLaunchedActivityFlags); |
| ListPrefUpdate update_launches(local_state_, |
| prefs::kStabilityLaunchedActivityCounts); |
| base::ListValue* launch_counts = update_launches.Get(); |
| for (int activity_type = ActivityTypeIds::ACTIVITY_NONE; |
| activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE; |
| ++activity_type) { |
| if (launched & GetActivityFlag(activity_type)) |
| IncrementListValue(launch_counts, activity_type); |
| } |
| local_state_->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0); |
| |
| // Track any Activities that were in the foreground when Chrome died. |
| // These Activities failed to be recorded as leaving the foreground, so Chrome |
| // couldn't have ended the UMA session cleanly. Record them as crashing. |
| const int foreground = |
| local_state_->GetInteger(prefs::kStabilityForegroundActivityType); |
| if (foreground != ActivityTypeIds::ACTIVITY_NONE) { |
| ListPrefUpdate update_crashes(local_state_, |
| prefs::kStabilityCrashedActivityCounts); |
| base::ListValue* crash_counts = update_crashes.Get(); |
| IncrementListValue(crash_counts, foreground); |
| local_state_->SetInteger(prefs::kStabilityForegroundActivityType, |
| ActivityTypeIds::ACTIVITY_NONE); |
| } |
| |
| local_state_->CommitPendingWrite(); |
| } |
| |
| void AndroidMetricsProvider::ConvertStabilityPrefsToHistograms() { |
| ListPrefUpdate launch_updater(local_state_, |
| prefs::kStabilityLaunchedActivityCounts); |
| ListPrefUpdate crash_updater(local_state_, |
| prefs::kStabilityCrashedActivityCounts); |
| |
| base::ListValue* launch_counts = launch_updater.Get(); |
| base::ListValue* crash_counts = crash_updater.Get(); |
| |
| for (int activity_type = ActivityTypeIds::ACTIVITY_NONE; |
| activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE; |
| ++activity_type) { |
| int launch_count = 0; |
| int crash_count = 0; |
| |
| launch_counts->GetInteger(activity_type, &launch_count); |
| crash_counts->GetInteger(activity_type, &crash_count); |
| |
| for (int count = 0; count < launch_count; ++count) { |
| UMA_STABILITY_HISTOGRAM_ENUMERATION( |
| "Chrome.Android.Activity.LaunchCounts", |
| activity_type, |
| ActivityTypeIds::ACTIVITY_MAX_VALUE); |
| } |
| |
| for (int count = 0; count < crash_count; ++count) { |
| UMA_STABILITY_HISTOGRAM_ENUMERATION("Chrome.Android.Activity.CrashCounts", |
| activity_type, |
| ActivityTypeIds::ACTIVITY_MAX_VALUE); |
| } |
| } |
| |
| launch_counts->Clear(); |
| crash_counts->Clear(); |
| } |
| |
| void AndroidMetricsProvider::OnForegroundActivityChanged( |
| ActivityTypeIds::Type type) { |
| DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE); |
| |
| if (type == local_state_->GetInteger(prefs::kStabilityForegroundActivityType)) |
| return; |
| |
| // Record that the Activity is now in the foreground. |
| local_state_->SetInteger(prefs::kStabilityForegroundActivityType, type); |
| |
| // Record that the Activity was launched this sesaion. |
| // The pref stores a set of flags ORed together, where each set flag |
| // corresponds to a launched Activity type. |
| int launched = |
| local_state_->GetInteger(prefs::kStabilityLaunchedActivityFlags); |
| if (type != ActivityTypeIds::ACTIVITY_NONE) { |
| launched |= GetActivityFlag(type); |
| local_state_->SetInteger(prefs::kStabilityLaunchedActivityFlags, launched); |
| } |
| |
| local_state_->CommitPendingWrite(); |
| } |
| |
| // static |
| void AndroidMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) { |
| registry->RegisterIntegerPref(prefs::kStabilityForegroundActivityType, |
| ActivityTypeIds::ACTIVITY_NONE); |
| registry->RegisterIntegerPref(prefs::kStabilityLaunchedActivityFlags, 0); |
| registry->RegisterListPref(prefs::kStabilityLaunchedActivityCounts); |
| registry->RegisterListPref(prefs::kStabilityCrashedActivityCounts); |
| } |