1 // Copyright (c) 2011 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/profiles/profile_metrics.h"
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/profiles/profile_info_cache.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/installer/util/google_update_settings.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/user_metrics.h"
21 const int kMaximumReportedProfileCount
= 5;
22 const int kMaximumDaysOfDisuse
= 4 * 7; // Should be integral number of weeks.
24 struct ProfileCounts
{
30 ProfileCounts() : total(0), signedin(0), managed(0), unused(0) {}
33 ProfileMetrics::ProfileType
GetProfileType(
34 const base::FilePath
& profile_path
) {
35 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
36 ProfileMetrics::ProfileType metric
= ProfileMetrics::SECONDARY
;
37 ProfileManager
* manager
= g_browser_process
->profile_manager();
38 base::FilePath user_data_dir
;
39 // In unittests, we do not always have a profile_manager so check.
41 user_data_dir
= manager
->user_data_dir();
43 if (profile_path
== user_data_dir
.AppendASCII(chrome::kInitialProfile
)) {
44 metric
= ProfileMetrics::ORIGINAL
;
49 void UpdateReportedOSProfileStatistics(int active
, int signedin
) {
51 GoogleUpdateSettings::UpdateProfileCounts(active
, signedin
);
55 bool CountProfileInformation(ProfileManager
* manager
, ProfileCounts
* counts
) {
56 const ProfileInfoCache
& info_cache
= manager
->GetProfileInfoCache();
57 size_t number_of_profiles
= info_cache
.GetNumberOfProfiles();
58 counts
->total
= number_of_profiles
;
60 // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
61 if (!number_of_profiles
)
64 // Maximum age for "active" profile is 4 weeks.
65 base::Time oldest
= base::Time::Now() -
66 base::TimeDelta::FromDays(kMaximumDaysOfDisuse
);
68 for (size_t i
= 0; i
< number_of_profiles
; ++i
) {
69 if (info_cache
.GetProfileActiveTimeAtIndex(i
) < oldest
) {
72 if (info_cache
.ProfileIsManagedAtIndex(i
))
74 if (!info_cache
.GetUserNameOfProfileAtIndex(i
).empty())
84 AVATAR_GENERIC
= 0, // The names for avatar icons
88 AVATAR_GENERIC_ORANGE
,
89 AVATAR_GENERIC_PURPLE
,
91 AVATAR_GENERIC_YELLOW
,
94 AVATAR_VOLLEYBALL
, // 10
104 AVATAR_CUPCAKE
, // 20
110 AVATAR_UNKNOWN
, // 26
112 NUM_PROFILE_AVATAR_METRICS
115 void ProfileMetrics::UpdateReportedProfilesStatistics(ProfileManager
* manager
) {
116 ProfileCounts counts
;
117 if (CountProfileInformation(manager
, &counts
)) {
118 int limited_total
= counts
.total
;
119 int limited_signedin
= counts
.signedin
;
120 if (limited_total
> kMaximumReportedProfileCount
) {
121 limited_total
= kMaximumReportedProfileCount
+ 1;
123 (int)((float)(counts
.signedin
* limited_total
)
124 / counts
.total
+ 0.5);
126 UpdateReportedOSProfileStatistics(limited_total
, limited_signedin
);
130 void ProfileMetrics::LogNumberOfProfiles(ProfileManager
* manager
) {
131 ProfileCounts counts
;
132 bool success
= CountProfileInformation(manager
, &counts
);
133 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfProfiles", counts
.total
);
135 // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
137 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfManagedProfiles",
139 UMA_HISTOGRAM_COUNTS_100("Profile.PercentageOfManagedProfiles",
140 100 * counts
.managed
/ counts
.total
);
141 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfSignedInProfiles",
143 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfUnusedProfiles",
146 UpdateReportedOSProfileStatistics(counts
.total
, counts
.signedin
);
150 void ProfileMetrics::LogProfileAddNewUser(ProfileAdd metric
) {
151 DCHECK(metric
< NUM_PROFILE_ADD_METRICS
);
152 UMA_HISTOGRAM_ENUMERATION("Profile.AddNewUser", metric
,
153 NUM_PROFILE_ADD_METRICS
);
154 UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", ADD_NEW_USER
,
155 NUM_PROFILE_NET_METRICS
);
158 void ProfileMetrics::LogProfileAvatarSelection(size_t icon_index
) {
159 DCHECK(icon_index
< NUM_PROFILE_AVATAR_METRICS
);
160 ProfileAvatar icon_name
= AVATAR_UNKNOWN
;
161 switch (icon_index
) {
163 icon_name
= AVATAR_GENERIC
;
166 icon_name
= AVATAR_GENERIC_AQUA
;
169 icon_name
= AVATAR_GENERIC_BLUE
;
172 icon_name
= AVATAR_GENERIC_GREEN
;
175 icon_name
= AVATAR_GENERIC_ORANGE
;
178 icon_name
= AVATAR_GENERIC_PURPLE
;
181 icon_name
= AVATAR_GENERIC_RED
;
184 icon_name
= AVATAR_GENERIC_YELLOW
;
187 icon_name
= AVATAR_SECRET_AGENT
;
190 icon_name
= AVATAR_SUPERHERO
;
193 icon_name
= AVATAR_VOLLEYBALL
;
196 icon_name
= AVATAR_BUSINESSMAN
;
199 icon_name
= AVATAR_NINJA
;
202 icon_name
= AVATAR_ALIEN
;
205 icon_name
= AVATAR_AWESOME
;
208 icon_name
= AVATAR_FLOWER
;
211 icon_name
= AVATAR_PIZZA
;
214 icon_name
= AVATAR_SOCCER
;
217 icon_name
= AVATAR_BURGER
;
220 icon_name
= AVATAR_CAT
;
223 icon_name
= AVATAR_CUPCAKE
;
226 icon_name
= AVATAR_DOG
;
229 icon_name
= AVATAR_HORSE
;
232 icon_name
= AVATAR_MARGARITA
;
235 icon_name
= AVATAR_NOTE
;
238 icon_name
= AVATAR_SUN_CLOUD
;
241 icon_name
= AVATAR_GAIA
;
243 default: // We should never actually get here.
247 UMA_HISTOGRAM_ENUMERATION("Profile.Avatar", icon_name
,
248 NUM_PROFILE_AVATAR_METRICS
);
251 void ProfileMetrics::LogProfileDeleteUser(ProfileNetUserCounts metric
) {
252 DCHECK(metric
< NUM_PROFILE_NET_METRICS
);
253 UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", metric
,
254 NUM_PROFILE_NET_METRICS
);
257 void ProfileMetrics::LogProfileOpenMethod(ProfileOpen metric
) {
258 DCHECK(metric
< NUM_PROFILE_OPEN_METRICS
);
259 UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric
,
260 NUM_PROFILE_OPEN_METRICS
);
263 void ProfileMetrics::LogProfileSwitchGaia(ProfileGaia metric
) {
264 if (metric
== GAIA_OPT_IN
)
265 LogProfileAvatarSelection(AVATAR_GAIA
);
266 UMA_HISTOGRAM_ENUMERATION("Profile.SwitchGaiaPhotoSettings",
268 NUM_PROFILE_GAIA_METRICS
);
271 void ProfileMetrics::LogProfileSwitchUser(ProfileOpen metric
) {
272 DCHECK(metric
< NUM_PROFILE_OPEN_METRICS
);
273 UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric
,
274 NUM_PROFILE_OPEN_METRICS
);
277 void ProfileMetrics::LogProfileSyncInfo(ProfileSync metric
) {
278 DCHECK(metric
< NUM_PROFILE_SYNC_METRICS
);
279 UMA_HISTOGRAM_ENUMERATION("Profile.SyncCustomize", metric
,
280 NUM_PROFILE_SYNC_METRICS
);
283 void ProfileMetrics::LogProfileAuthResult(ProfileAuth metric
) {
284 UMA_HISTOGRAM_ENUMERATION("Profile.AuthResult", metric
,
285 NUM_PROFILE_AUTH_METRICS
);
288 void ProfileMetrics::LogProfileLaunch(Profile
* profile
) {
289 base::FilePath profile_path
= profile
->GetPath();
290 UMA_HISTOGRAM_ENUMERATION("Profile.LaunchBrowser",
291 GetProfileType(profile_path
),
292 NUM_PROFILE_TYPE_METRICS
);
294 if (profile
->IsManaged()) {
295 content::RecordAction(
296 base::UserMetricsAction("ManagedMode_NewManagedUserWindow"));
300 void ProfileMetrics::LogProfileSyncSignIn(const base::FilePath
& profile_path
) {
301 UMA_HISTOGRAM_ENUMERATION("Profile.SyncSignIn",
302 GetProfileType(profile_path
),
303 NUM_PROFILE_TYPE_METRICS
);
306 void ProfileMetrics::LogProfileUpdate(const base::FilePath
& profile_path
) {
307 UMA_HISTOGRAM_ENUMERATION("Profile.Update",
308 GetProfileType(profile_path
),
309 NUM_PROFILE_TYPE_METRICS
);