1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// 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);
}
|