android_metrics_provider.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/metrics/android_metrics_provider.h" 6 7#include "base/metrics/histogram.h" 8#include "base/prefs/pref_registry_simple.h" 9#include "base/prefs/pref_service.h" 10#include "base/prefs/scoped_user_pref_update.h" 11#include "base/values.h" 12#include "chrome/common/pref_names.h" 13 14namespace { 15 16// Increments a particular entry in the ListValue. 17void IncrementListValue(base::ListValue* counts, int index) { 18 int current_count = 0; 19 counts->GetInteger(index, ¤t_count); 20 counts->Set(index, new base::FundamentalValue(current_count + 1)); 21} 22 23// Takes an int corresponding to a Type and returns the corresponding flag. 24int GetActivityFlag(int type_id) { 25 ActivityTypeIds::Type type = ActivityTypeIds::GetActivityType(type_id); 26 DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE); 27 return (1 << type); 28} 29 30} // namespace 31 32AndroidMetricsProvider::AndroidMetricsProvider(PrefService* local_state) 33 : local_state_(local_state) { 34 LogStabilityToPrefs(); 35} 36 37AndroidMetricsProvider::~AndroidMetricsProvider() { 38} 39 40 41void AndroidMetricsProvider::ProvideStabilityMetrics( 42 metrics::SystemProfileProto* system_profile_proto) { 43 ConvertStabilityPrefsToHistograms(); 44} 45 46void AndroidMetricsProvider::LogStabilityToPrefs() { 47 // Track which Activities were launched by the user. 48 // A 'launch' is defined as starting the Activity at least once during a 49 // UMA session. Multiple launches are counted only once since it is possible 50 // for users to hop between Activities (e.g. entering and leaving Settings). 51 const int launched = 52 local_state_->GetInteger(prefs::kStabilityLaunchedActivityFlags); 53 ListPrefUpdate update_launches(local_state_, 54 prefs::kStabilityLaunchedActivityCounts); 55 base::ListValue* launch_counts = update_launches.Get(); 56 for (int activity_type = ActivityTypeIds::ACTIVITY_NONE; 57 activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE; 58 ++activity_type) { 59 if (launched & GetActivityFlag(activity_type)) 60 IncrementListValue(launch_counts, activity_type); 61 } 62 local_state_->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0); 63 64 // Track any Activities that were in the foreground when Chrome died. 65 // These Activities failed to be recorded as leaving the foreground, so Chrome 66 // couldn't have ended the UMA session cleanly. Record them as crashing. 67 const int foreground = 68 local_state_->GetInteger(prefs::kStabilityForegroundActivityType); 69 if (foreground != ActivityTypeIds::ACTIVITY_NONE) { 70 ListPrefUpdate update_crashes(local_state_, 71 prefs::kStabilityCrashedActivityCounts); 72 base::ListValue* crash_counts = update_crashes.Get(); 73 IncrementListValue(crash_counts, foreground); 74 local_state_->SetInteger(prefs::kStabilityForegroundActivityType, 75 ActivityTypeIds::ACTIVITY_NONE); 76 } 77 78 local_state_->CommitPendingWrite(); 79} 80 81void AndroidMetricsProvider::ConvertStabilityPrefsToHistograms() { 82 ListPrefUpdate launch_updater(local_state_, 83 prefs::kStabilityLaunchedActivityCounts); 84 ListPrefUpdate crash_updater(local_state_, 85 prefs::kStabilityCrashedActivityCounts); 86 87 base::ListValue* launch_counts = launch_updater.Get(); 88 base::ListValue* crash_counts = crash_updater.Get(); 89 90 for (int activity_type = ActivityTypeIds::ACTIVITY_NONE; 91 activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE; 92 ++activity_type) { 93 int launch_count = 0; 94 int crash_count = 0; 95 96 launch_counts->GetInteger(activity_type, &launch_count); 97 crash_counts->GetInteger(activity_type, &crash_count); 98 99 for (int count = 0; count < launch_count; ++count) { 100 UMA_STABILITY_HISTOGRAM_ENUMERATION( 101 "Chrome.Android.Activity.LaunchCounts", 102 activity_type, 103 ActivityTypeIds::ACTIVITY_MAX_VALUE); 104 } 105 106 for (int count = 0; count < crash_count; ++count) { 107 UMA_STABILITY_HISTOGRAM_ENUMERATION("Chrome.Android.Activity.CrashCounts", 108 activity_type, 109 ActivityTypeIds::ACTIVITY_MAX_VALUE); 110 } 111 } 112 113 launch_counts->Clear(); 114 crash_counts->Clear(); 115} 116 117void AndroidMetricsProvider::OnForegroundActivityChanged( 118 ActivityTypeIds::Type type) { 119 DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE); 120 121 if (type == local_state_->GetInteger(prefs::kStabilityForegroundActivityType)) 122 return; 123 124 // Record that the Activity is now in the foreground. 125 local_state_->SetInteger(prefs::kStabilityForegroundActivityType, type); 126 127 // Record that the Activity was launched this sesaion. 128 // The pref stores a set of flags ORed together, where each set flag 129 // corresponds to a launched Activity type. 130 int launched = 131 local_state_->GetInteger(prefs::kStabilityLaunchedActivityFlags); 132 if (type != ActivityTypeIds::ACTIVITY_NONE) { 133 launched |= GetActivityFlag(type); 134 local_state_->SetInteger(prefs::kStabilityLaunchedActivityFlags, launched); 135 } 136 137 local_state_->CommitPendingWrite(); 138} 139 140// static 141void AndroidMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) { 142 registry->RegisterIntegerPref(prefs::kStabilityForegroundActivityType, 143 ActivityTypeIds::ACTIVITY_NONE); 144 registry->RegisterIntegerPref(prefs::kStabilityLaunchedActivityFlags, 0); 145 registry->RegisterListPref(prefs::kStabilityLaunchedActivityCounts); 146 registry->RegisterListPref(prefs::kStabilityCrashedActivityCounts); 147} 148