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.
5 #include "chrome/browser/metrics/metrics_service.h"
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/browser/android/activity_type_ids.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/common/pref_names.h"
18 // Increments a particular entry in the ListValue.
19 void IncrementListValue(base::ListValue* counts, int index) {
20 int current_count = 0;
21 counts->GetInteger(index, ¤t_count);
22 counts->Set(index, new base::FundamentalValue(current_count + 1));
25 // Takes an int corresponding to a Type and returns the corresponding flag.
26 int GetActivityFlag(int type_id) {
27 ActivityTypeIds::Type type = ActivityTypeIds::GetActivityType(type_id);
28 DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE);
35 void MetricsService::RegisterPrefsAndroid(PrefRegistrySimple* registry) {
36 registry->RegisterIntegerPref(prefs::kStabilityForegroundActivityType,
37 ActivityTypeIds::ACTIVITY_NONE);
38 registry->RegisterIntegerPref(prefs::kStabilityLaunchedActivityFlags, 0);
39 registry->RegisterListPref(prefs::kStabilityLaunchedActivityCounts);
40 registry->RegisterListPref(prefs::kStabilityCrashedActivityCounts);
43 void MetricsService::LogAndroidStabilityToPrefs(PrefService* pref) {
44 // Track which Activities were launched by the user.
45 // A 'launch' is defined as starting the Activity at least once during a
46 // UMA session. Multiple launches are counted only once since it is possible
47 // for users to hop between Activities (e.g. entering and leaving Settings).
48 int launched = pref->GetInteger(prefs::kStabilityLaunchedActivityFlags);
49 ListPrefUpdate update_launches(pref, prefs::kStabilityLaunchedActivityCounts);
50 base::ListValue* launch_counts = update_launches.Get();
51 for (int activity_type = ActivityTypeIds::ACTIVITY_NONE;
52 activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE;
54 if (launched & GetActivityFlag(activity_type))
55 IncrementListValue(launch_counts, activity_type);
57 pref->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0);
59 // Track any Activities that were in the foreground when Chrome died.
60 // These Activities failed to be recorded as leaving the foreground, so Chrome
61 // couldn't have ended the UMA session cleanly. Record them as crashing.
62 int foreground = pref->GetInteger(prefs::kStabilityForegroundActivityType);
63 if (foreground != ActivityTypeIds::ACTIVITY_NONE) {
64 ListPrefUpdate update_crashes(pref, prefs::kStabilityCrashedActivityCounts);
65 base::ListValue* crash_counts = update_crashes.Get();
66 IncrementListValue(crash_counts, foreground);
67 pref->SetInteger(prefs::kStabilityForegroundActivityType,
68 ActivityTypeIds::ACTIVITY_NONE);
71 pref->CommitPendingWrite();
74 void MetricsService::ConvertAndroidStabilityPrefsToHistograms(
76 ListPrefUpdate launch_updater(pref, prefs::kStabilityLaunchedActivityCounts);
77 ListPrefUpdate crash_updater(pref, prefs::kStabilityCrashedActivityCounts);
79 base::ListValue* launch_counts = launch_updater.Get();
80 base::ListValue* crash_counts = crash_updater.Get();
82 for (int activity_type = ActivityTypeIds::ACTIVITY_NONE;
83 activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE;
88 launch_counts->GetInteger(activity_type, &launch_count);
89 crash_counts->GetInteger(activity_type, &crash_count);
91 for (int count = 0; count < launch_count; ++count) {
92 UMA_STABILITY_HISTOGRAM_ENUMERATION(
93 "Chrome.Android.Activity.LaunchCounts",
95 ActivityTypeIds::ACTIVITY_MAX_VALUE);
98 for (int count = 0; count < crash_count; ++count) {
99 UMA_STABILITY_HISTOGRAM_ENUMERATION("Chrome.Android.Activity.CrashCounts",
101 ActivityTypeIds::ACTIVITY_MAX_VALUE);
105 launch_counts->Clear();
106 crash_counts->Clear();
109 void MetricsService::OnForegroundActivityChanged(PrefService* pref,
110 ActivityTypeIds::Type type) {
111 DCHECK(type < ActivityTypeIds::ACTIVITY_MAX_VALUE);
113 int activity_type = pref->GetInteger(prefs::kStabilityForegroundActivityType);
114 if (activity_type == type)
117 // Record that the Activity is now in the foreground.
118 pref->SetInteger(prefs::kStabilityForegroundActivityType, type);
120 // Record that the Activity was launched this sesaion.
121 // The pref stores a set of flags ORed together, where each set flag
122 // corresponds to a launched Activity type.
123 int launched = pref->GetInteger(prefs::kStabilityLaunchedActivityFlags);
124 if (type != ActivityTypeIds::ACTIVITY_NONE) {
125 launched |= GetActivityFlag(type);
126 pref->SetInteger(prefs::kStabilityLaunchedActivityFlags, launched);
129 pref->CommitPendingWrite();
133 void MetricsService::DiscardOldStabilityStatsAndroid(PrefService* local_state) {
134 local_state->SetInteger(prefs::kStabilityForegroundActivityType,
135 ActivityTypeIds::ACTIVITY_NONE);
136 local_state->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0);
138 ListPrefUpdate launches(local_state, prefs::kStabilityLaunchedActivityCounts);
139 launches.Get()->Clear();
141 ListPrefUpdate crashes(local_state, prefs::kStabilityCrashedActivityCounts);
142 crashes.Get()->Clear();