Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / profiles / profile_metrics.cc
blob3914b3b75be282b8f37169b0a5ca09dc2a4119e0
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/browser/signin/signin_header_helper.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "chrome/installer/util/google_update_settings.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/user_metrics.h"
20 namespace {
22 const int kMaximumReportedProfileCount = 5;
23 const int kMaximumDaysOfDisuse = 4 * 7; // Should be integral number of weeks.
25 struct ProfileCounts {
26 size_t total;
27 size_t signedin;
28 size_t managed;
29 size_t unused;
31 ProfileCounts() : total(0), signedin(0), managed(0), unused(0) {}
34 ProfileMetrics::ProfileType GetProfileType(
35 const base::FilePath& profile_path) {
36 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
37 ProfileMetrics::ProfileType metric = ProfileMetrics::SECONDARY;
38 ProfileManager* manager = g_browser_process->profile_manager();
39 base::FilePath user_data_dir;
40 // In unittests, we do not always have a profile_manager so check.
41 if (manager) {
42 user_data_dir = manager->user_data_dir();
44 if (profile_path == user_data_dir.AppendASCII(chrome::kInitialProfile)) {
45 metric = ProfileMetrics::ORIGINAL;
47 return metric;
50 void UpdateReportedOSProfileStatistics(int active, int signedin) {
51 #if defined(OS_WIN)
52 GoogleUpdateSettings::UpdateProfileCounts(active, signedin);
53 #endif
56 bool CountProfileInformation(ProfileManager* manager, ProfileCounts* counts) {
57 const ProfileInfoCache& info_cache = manager->GetProfileInfoCache();
58 size_t number_of_profiles = info_cache.GetNumberOfProfiles();
59 counts->total = number_of_profiles;
61 // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
62 if (!number_of_profiles)
63 return false;
65 // Maximum age for "active" profile is 4 weeks.
66 base::Time oldest = base::Time::Now() -
67 base::TimeDelta::FromDays(kMaximumDaysOfDisuse);
69 for (size_t i = 0; i < number_of_profiles; ++i) {
70 if (info_cache.GetProfileActiveTimeAtIndex(i) < oldest) {
71 counts->unused++;
72 } else {
73 if (info_cache.ProfileIsManagedAtIndex(i))
74 counts->managed++;
75 if (!info_cache.GetUserNameOfProfileAtIndex(i).empty())
76 counts->signedin++;
79 return true;
82 } // namespace
84 enum ProfileAvatar {
85 AVATAR_GENERIC = 0, // The names for avatar icons
86 AVATAR_GENERIC_AQUA,
87 AVATAR_GENERIC_BLUE,
88 AVATAR_GENERIC_GREEN,
89 AVATAR_GENERIC_ORANGE,
90 AVATAR_GENERIC_PURPLE,
91 AVATAR_GENERIC_RED,
92 AVATAR_GENERIC_YELLOW,
93 AVATAR_SECRET_AGENT,
94 AVATAR_SUPERHERO,
95 AVATAR_VOLLEYBALL, // 10
96 AVATAR_BUSINESSMAN,
97 AVATAR_NINJA,
98 AVATAR_ALIEN,
99 AVATAR_AWESOME,
100 AVATAR_FLOWER,
101 AVATAR_PIZZA,
102 AVATAR_SOCCER,
103 AVATAR_BURGER,
104 AVATAR_CAT,
105 AVATAR_CUPCAKE, // 20
106 AVATAR_DOG,
107 AVATAR_HORSE,
108 AVATAR_MARGARITA,
109 AVATAR_NOTE,
110 AVATAR_SUN_CLOUD,
111 AVATAR_PLACEHOLDER,
112 AVATAR_UNKNOWN, // 27
113 AVATAR_GAIA, // 28
114 NUM_PROFILE_AVATAR_METRICS
117 void ProfileMetrics::UpdateReportedProfilesStatistics(ProfileManager* manager) {
118 ProfileCounts counts;
119 if (CountProfileInformation(manager, &counts)) {
120 int limited_total = counts.total;
121 int limited_signedin = counts.signedin;
122 if (limited_total > kMaximumReportedProfileCount) {
123 limited_total = kMaximumReportedProfileCount + 1;
124 limited_signedin =
125 (int)((float)(counts.signedin * limited_total)
126 / counts.total + 0.5);
128 UpdateReportedOSProfileStatistics(limited_total, limited_signedin);
132 void ProfileMetrics::LogNumberOfProfiles(ProfileManager* manager) {
133 ProfileCounts counts;
134 bool success = CountProfileInformation(manager, &counts);
135 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfProfiles", counts.total);
137 // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
138 if (success) {
139 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfManagedProfiles",
140 counts.managed);
141 UMA_HISTOGRAM_COUNTS_100("Profile.PercentageOfManagedProfiles",
142 100 * counts.managed / counts.total);
143 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfSignedInProfiles",
144 counts.signedin);
145 UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfUnusedProfiles",
146 counts.unused);
148 UpdateReportedOSProfileStatistics(counts.total, counts.signedin);
152 void ProfileMetrics::LogProfileAddNewUser(ProfileAdd metric) {
153 DCHECK(metric < NUM_PROFILE_ADD_METRICS);
154 UMA_HISTOGRAM_ENUMERATION("Profile.AddNewUser", metric,
155 NUM_PROFILE_ADD_METRICS);
156 UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", ADD_NEW_USER,
157 NUM_PROFILE_NET_METRICS);
160 void ProfileMetrics::LogProfileAvatarSelection(size_t icon_index) {
161 DCHECK(icon_index < NUM_PROFILE_AVATAR_METRICS);
162 ProfileAvatar icon_name = AVATAR_UNKNOWN;
163 switch (icon_index) {
164 case 0:
165 icon_name = AVATAR_GENERIC;
166 break;
167 case 1:
168 icon_name = AVATAR_GENERIC_AQUA;
169 break;
170 case 2:
171 icon_name = AVATAR_GENERIC_BLUE;
172 break;
173 case 3:
174 icon_name = AVATAR_GENERIC_GREEN;
175 break;
176 case 4:
177 icon_name = AVATAR_GENERIC_ORANGE;
178 break;
179 case 5:
180 icon_name = AVATAR_GENERIC_PURPLE;
181 break;
182 case 6:
183 icon_name = AVATAR_GENERIC_RED;
184 break;
185 case 7:
186 icon_name = AVATAR_GENERIC_YELLOW;
187 break;
188 case 8:
189 icon_name = AVATAR_SECRET_AGENT;
190 break;
191 case 9:
192 icon_name = AVATAR_SUPERHERO;
193 break;
194 case 10:
195 icon_name = AVATAR_VOLLEYBALL;
196 break;
197 case 11:
198 icon_name = AVATAR_BUSINESSMAN;
199 break;
200 case 12:
201 icon_name = AVATAR_NINJA;
202 break;
203 case 13:
204 icon_name = AVATAR_ALIEN;
205 break;
206 case 14:
207 icon_name = AVATAR_AWESOME;
208 break;
209 case 15:
210 icon_name = AVATAR_FLOWER;
211 break;
212 case 16:
213 icon_name = AVATAR_PIZZA;
214 break;
215 case 17:
216 icon_name = AVATAR_SOCCER;
217 break;
218 case 18:
219 icon_name = AVATAR_BURGER;
220 break;
221 case 19:
222 icon_name = AVATAR_CAT;
223 break;
224 case 20:
225 icon_name = AVATAR_CUPCAKE;
226 break;
227 case 21:
228 icon_name = AVATAR_DOG;
229 break;
230 case 22:
231 icon_name = AVATAR_HORSE;
232 break;
233 case 23:
234 icon_name = AVATAR_MARGARITA;
235 break;
236 case 24:
237 icon_name = AVATAR_NOTE;
238 break;
239 case 25:
240 icon_name = AVATAR_SUN_CLOUD;
241 break;
242 case 26:
243 icon_name = AVATAR_PLACEHOLDER;
244 break;
245 case 28:
246 icon_name = AVATAR_GAIA;
247 break;
248 default: // We should never actually get here.
249 NOTREACHED();
250 break;
252 UMA_HISTOGRAM_ENUMERATION("Profile.Avatar", icon_name,
253 NUM_PROFILE_AVATAR_METRICS);
256 void ProfileMetrics::LogProfileDeleteUser(ProfileNetUserCounts metric) {
257 DCHECK(metric < NUM_PROFILE_NET_METRICS);
258 UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", metric,
259 NUM_PROFILE_NET_METRICS);
262 void ProfileMetrics::LogProfileOpenMethod(ProfileOpen metric) {
263 DCHECK(metric < NUM_PROFILE_OPEN_METRICS);
264 UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric,
265 NUM_PROFILE_OPEN_METRICS);
268 void ProfileMetrics::LogProfileSwitchGaia(ProfileGaia metric) {
269 if (metric == GAIA_OPT_IN)
270 LogProfileAvatarSelection(AVATAR_GAIA);
271 UMA_HISTOGRAM_ENUMERATION("Profile.SwitchGaiaPhotoSettings",
272 metric,
273 NUM_PROFILE_GAIA_METRICS);
276 void ProfileMetrics::LogProfileSwitchUser(ProfileOpen metric) {
277 DCHECK(metric < NUM_PROFILE_OPEN_METRICS);
278 UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric,
279 NUM_PROFILE_OPEN_METRICS);
282 void ProfileMetrics::LogProfileSyncInfo(ProfileSync metric) {
283 DCHECK(metric < NUM_PROFILE_SYNC_METRICS);
284 UMA_HISTOGRAM_ENUMERATION("Profile.SyncCustomize", metric,
285 NUM_PROFILE_SYNC_METRICS);
288 void ProfileMetrics::LogProfileAuthResult(ProfileAuth metric) {
289 UMA_HISTOGRAM_ENUMERATION("Profile.AuthResult", metric,
290 NUM_PROFILE_AUTH_METRICS);
293 void ProfileMetrics::LogProfileUpgradeEnrollment(
294 ProfileUpgradeEnrollment metric) {
295 UMA_HISTOGRAM_ENUMERATION("Profile.UpgradeEnrollment", metric,
296 NUM_PROFILE_ENROLLMENT_METRICS);
299 void ProfileMetrics::LogProfileDesktopMenu(
300 ProfileDesktopMenu metric,
301 signin::GAIAServiceType gaia_service) {
302 // The first parameter to the histogram needs to be literal, because of the
303 // optimized implementation of |UMA_HISTOGRAM_ENUMERATION|. Do not attempt
304 // to refactor.
305 switch (gaia_service) {
306 case signin::GAIA_SERVICE_TYPE_NONE:
307 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.NonGAIA", metric,
308 NUM_PROFILE_DESKTOP_MENU_METRICS);
309 break;
310 case signin::GAIA_SERVICE_TYPE_SIGNOUT:
311 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.GAIASignout", metric,
312 NUM_PROFILE_DESKTOP_MENU_METRICS);
313 break;
314 case signin::GAIA_SERVICE_TYPE_INCOGNITO:
315 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.GAIAIncognito",
316 metric, NUM_PROFILE_DESKTOP_MENU_METRICS);
317 break;
318 case signin::GAIA_SERVICE_TYPE_ADDSESSION:
319 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.GAIAAddSession", metric,
320 NUM_PROFILE_DESKTOP_MENU_METRICS);
321 break;
322 case signin::GAIA_SERVICE_TYPE_REAUTH:
323 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.GAIAReAuth", metric,
324 NUM_PROFILE_DESKTOP_MENU_METRICS);
325 break;
326 case signin::GAIA_SERVICE_TYPE_DEFAULT:
327 UMA_HISTOGRAM_ENUMERATION("Profile.DesktopMenu.GAIADefault", metric,
328 NUM_PROFILE_DESKTOP_MENU_METRICS);
329 break;
333 #if defined(OS_ANDROID)
334 void ProfileMetrics::LogProfileAndroidAccountManagementMenu(
335 ProfileAndroidAccountManagementMenu metric,
336 signin::GAIAServiceType gaia_service) {
337 // The first parameter to the histogram needs to be literal, because of the
338 // optimized implementation of |UMA_HISTOGRAM_ENUMERATION|. Do not attempt
339 // to refactor.
340 switch (gaia_service) {
341 case signin::GAIA_SERVICE_TYPE_NONE:
342 UMA_HISTOGRAM_ENUMERATION(
343 "Profile.AndroidAccountManagementMenu.NonGAIA",
344 metric,
345 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
346 break;
347 case signin::GAIA_SERVICE_TYPE_SIGNOUT:
348 UMA_HISTOGRAM_ENUMERATION(
349 "Profile.AndroidAccountManagementMenu.GAIASignout",
350 metric,
351 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
352 break;
353 case signin::GAIA_SERVICE_TYPE_INCOGNITO:
354 UMA_HISTOGRAM_ENUMERATION(
355 "Profile.AndroidAccountManagementMenu.GAIASignoutIncognito",
356 metric,
357 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
358 break;
359 case signin::GAIA_SERVICE_TYPE_ADDSESSION:
360 UMA_HISTOGRAM_ENUMERATION(
361 "Profile.AndroidAccountManagementMenu.GAIAAddSession",
362 metric,
363 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
364 break;
365 case signin::GAIA_SERVICE_TYPE_REAUTH:
366 UMA_HISTOGRAM_ENUMERATION(
367 "Profile.AndroidAccountManagementMenu.GAIAReAuth",
368 metric,
369 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
370 break;
371 case signin::GAIA_SERVICE_TYPE_DEFAULT:
372 UMA_HISTOGRAM_ENUMERATION(
373 "Profile.AndroidAccountManagementMenu.GAIADefault",
374 metric,
375 NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS);
376 break;
379 #endif // defined(OS_ANDROID)
381 void ProfileMetrics::LogProfileLaunch(Profile* profile) {
382 base::FilePath profile_path = profile->GetPath();
383 UMA_HISTOGRAM_ENUMERATION("Profile.LaunchBrowser",
384 GetProfileType(profile_path),
385 NUM_PROFILE_TYPE_METRICS);
387 if (profile->IsManaged()) {
388 content::RecordAction(
389 base::UserMetricsAction("ManagedMode_NewManagedUserWindow"));
393 void ProfileMetrics::LogProfileSyncSignIn(const base::FilePath& profile_path) {
394 UMA_HISTOGRAM_ENUMERATION("Profile.SyncSignIn",
395 GetProfileType(profile_path),
396 NUM_PROFILE_TYPE_METRICS);
399 void ProfileMetrics::LogProfileUpdate(const base::FilePath& profile_path) {
400 UMA_HISTOGRAM_ENUMERATION("Profile.Update",
401 GetProfileType(profile_path),
402 NUM_PROFILE_TYPE_METRICS);