• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/profiles/profile_metrics.h"
6 
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"
18 
19 namespace {
20 
21 const int kMaximumReportedProfileCount = 5;
22 
23 struct ProfileCounts {
24   size_t total;
25   size_t signedin;
26   size_t managed;
27 
ProfileCounts__anon469766c30111::ProfileCounts28   ProfileCounts() : total(0), signedin(0), managed(0) {}
29 };
30 
GetProfileType(const base::FilePath & profile_path)31 ProfileMetrics::ProfileType GetProfileType(
32     const base::FilePath& profile_path) {
33   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
34   ProfileMetrics::ProfileType metric = ProfileMetrics::SECONDARY;
35   ProfileManager* manager = g_browser_process->profile_manager();
36   base::FilePath user_data_dir;
37   // In unittests, we do not always have a profile_manager so check.
38   if (manager) {
39     user_data_dir = manager->user_data_dir();
40   }
41   if (profile_path == user_data_dir.AppendASCII(chrome::kInitialProfile)) {
42     metric = ProfileMetrics::ORIGINAL;
43   }
44   return metric;
45 }
46 
UpdateReportedOSProfileStatistics(int active,int signedin)47 void UpdateReportedOSProfileStatistics(int active, int signedin) {
48 #if defined(OS_WIN)
49   GoogleUpdateSettings::UpdateProfileCounts(active, signedin);
50 #endif
51 }
52 
CountProfileInformation(ProfileManager * manager,ProfileCounts * counts)53 bool CountProfileInformation(ProfileManager* manager, ProfileCounts* counts) {
54   const ProfileInfoCache& info_cache = manager->GetProfileInfoCache();
55   size_t number_of_profiles = info_cache.GetNumberOfProfiles();
56   counts->total = number_of_profiles;
57 
58   // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
59   if (!number_of_profiles)
60     return false;
61 
62   for (size_t i = 0; i < number_of_profiles; ++i) {
63     if (info_cache.ProfileIsManagedAtIndex(i))
64       counts->managed++;
65     if (!info_cache.GetUserNameOfProfileAtIndex(i).empty())
66       counts->signedin++;
67   }
68   return true;
69 }
70 
71 }  // namespace
72 
73 enum ProfileAvatar {
74   AVATAR_GENERIC = 0,       // The names for avatar icons
75   AVATAR_GENERIC_AQUA,
76   AVATAR_GENERIC_BLUE,
77   AVATAR_GENERIC_GREEN,
78   AVATAR_GENERIC_ORANGE,
79   AVATAR_GENERIC_PURPLE,
80   AVATAR_GENERIC_RED,
81   AVATAR_GENERIC_YELLOW,
82   AVATAR_SECRET_AGENT,
83   AVATAR_SUPERHERO,
84   AVATAR_VOLLEYBALL,        // 10
85   AVATAR_BUSINESSMAN,
86   AVATAR_NINJA,
87   AVATAR_ALIEN,
88   AVATAR_AWESOME,
89   AVATAR_FLOWER,
90   AVATAR_PIZZA,
91   AVATAR_SOCCER,
92   AVATAR_BURGER,
93   AVATAR_CAT,
94   AVATAR_CUPCAKE,           // 20
95   AVATAR_DOG,
96   AVATAR_HORSE,
97   AVATAR_MARGARITA,
98   AVATAR_NOTE,
99   AVATAR_SUN_CLOUD,
100   AVATAR_UNKNOWN,           // 26
101   AVATAR_GAIA,              // 27
102   NUM_PROFILE_AVATAR_METRICS
103 };
104 
UpdateReportedProfilesStatistics(ProfileManager * manager)105 void ProfileMetrics::UpdateReportedProfilesStatistics(ProfileManager* manager) {
106   ProfileCounts counts;
107   if (CountProfileInformation(manager, &counts)) {
108     int limited_total = counts.total;
109     int limited_signedin = counts.signedin;
110     if (limited_total > kMaximumReportedProfileCount) {
111       limited_total = kMaximumReportedProfileCount + 1;
112       limited_signedin =
113           (int)((float)(counts.signedin * limited_total)
114           / counts.total + 0.5);
115     }
116     UpdateReportedOSProfileStatistics(limited_total, limited_signedin);
117   }
118 }
119 
LogNumberOfProfiles(ProfileManager * manager)120 void ProfileMetrics::LogNumberOfProfiles(ProfileManager* manager) {
121   ProfileCounts counts;
122   bool success = CountProfileInformation(manager, &counts);
123   UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfProfiles", counts.total);
124 
125   // Ignore other metrics if we have no profiles, e.g. in Chrome Frame tests.
126   if (success) {
127     UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfManagedProfiles",
128                              counts.managed);
129     UMA_HISTOGRAM_COUNTS_100("Profile.PercentageOfManagedProfiles",
130                              100 * counts.managed / counts.total);
131     UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfSignedInProfiles",
132                              counts.signedin);
133 
134     UpdateReportedOSProfileStatistics(counts.total, counts.signedin);
135   }
136 }
137 
LogProfileAddNewUser(ProfileAdd metric)138 void ProfileMetrics::LogProfileAddNewUser(ProfileAdd metric) {
139   DCHECK(metric < NUM_PROFILE_ADD_METRICS);
140   UMA_HISTOGRAM_ENUMERATION("Profile.AddNewUser", metric,
141                             NUM_PROFILE_ADD_METRICS);
142   UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", ADD_NEW_USER,
143                             NUM_PROFILE_NET_METRICS);
144 }
145 
LogProfileAvatarSelection(size_t icon_index)146 void ProfileMetrics::LogProfileAvatarSelection(size_t icon_index) {
147   DCHECK(icon_index < NUM_PROFILE_AVATAR_METRICS);
148   ProfileAvatar icon_name = AVATAR_UNKNOWN;
149   switch (icon_index) {
150     case 0:
151       icon_name = AVATAR_GENERIC;
152       break;
153     case 1:
154       icon_name = AVATAR_GENERIC_AQUA;
155       break;
156     case 2:
157       icon_name = AVATAR_GENERIC_BLUE;
158       break;
159     case 3:
160       icon_name = AVATAR_GENERIC_GREEN;
161       break;
162     case 4:
163       icon_name = AVATAR_GENERIC_ORANGE;
164       break;
165     case 5:
166       icon_name = AVATAR_GENERIC_PURPLE;
167       break;
168     case 6:
169       icon_name = AVATAR_GENERIC_RED;
170       break;
171     case 7:
172       icon_name = AVATAR_GENERIC_YELLOW;
173       break;
174     case 8:
175       icon_name = AVATAR_SECRET_AGENT;
176       break;
177     case 9:
178       icon_name = AVATAR_SUPERHERO;
179       break;
180     case 10:
181       icon_name = AVATAR_VOLLEYBALL;
182       break;
183     case 11:
184       icon_name = AVATAR_BUSINESSMAN;
185       break;
186     case 12:
187       icon_name = AVATAR_NINJA;
188       break;
189     case 13:
190       icon_name = AVATAR_ALIEN;
191       break;
192     case 14:
193       icon_name = AVATAR_AWESOME;
194       break;
195     case 15:
196       icon_name = AVATAR_FLOWER;
197       break;
198     case 16:
199       icon_name = AVATAR_PIZZA;
200       break;
201     case 17:
202       icon_name = AVATAR_SOCCER;
203       break;
204     case 18:
205       icon_name = AVATAR_BURGER;
206       break;
207     case 19:
208       icon_name = AVATAR_CAT;
209       break;
210     case 20:
211       icon_name = AVATAR_CUPCAKE;
212       break;
213     case 21:
214       icon_name = AVATAR_DOG;
215       break;
216     case 22:
217       icon_name = AVATAR_HORSE;
218       break;
219     case 23:
220       icon_name = AVATAR_MARGARITA;
221       break;
222     case 24:
223       icon_name = AVATAR_NOTE;
224       break;
225     case 25:
226       icon_name = AVATAR_SUN_CLOUD;
227       break;
228     case 27:
229       icon_name = AVATAR_GAIA;
230       break;
231     default:  // We should never actually get here.
232       NOTREACHED();
233       break;
234   }
235   UMA_HISTOGRAM_ENUMERATION("Profile.Avatar", icon_name,
236                             NUM_PROFILE_AVATAR_METRICS);
237 }
238 
LogProfileDeleteUser(ProfileNetUserCounts metric)239 void ProfileMetrics::LogProfileDeleteUser(ProfileNetUserCounts metric) {
240   DCHECK(metric < NUM_PROFILE_NET_METRICS);
241   UMA_HISTOGRAM_ENUMERATION("Profile.NetUserCount", metric,
242                             NUM_PROFILE_NET_METRICS);
243 }
244 
LogProfileOpenMethod(ProfileOpen metric)245 void ProfileMetrics::LogProfileOpenMethod(ProfileOpen metric) {
246   DCHECK(metric < NUM_PROFILE_OPEN_METRICS);
247   UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric,
248                             NUM_PROFILE_OPEN_METRICS);
249 }
250 
LogProfileSwitchGaia(ProfileGaia metric)251 void ProfileMetrics::LogProfileSwitchGaia(ProfileGaia metric) {
252   if (metric == GAIA_OPT_IN)
253     LogProfileAvatarSelection(AVATAR_GAIA);
254   UMA_HISTOGRAM_ENUMERATION("Profile.SwitchGaiaPhotoSettings",
255                             metric,
256                             NUM_PROFILE_GAIA_METRICS);
257 }
258 
LogProfileSwitchUser(ProfileOpen metric)259 void ProfileMetrics::LogProfileSwitchUser(ProfileOpen metric) {
260   DCHECK(metric < NUM_PROFILE_OPEN_METRICS);
261   UMA_HISTOGRAM_ENUMERATION("Profile.OpenMethod", metric,
262                             NUM_PROFILE_OPEN_METRICS);
263 }
264 
LogProfileSyncInfo(ProfileSync metric)265 void ProfileMetrics::LogProfileSyncInfo(ProfileSync metric) {
266   DCHECK(metric < NUM_PROFILE_SYNC_METRICS);
267   UMA_HISTOGRAM_ENUMERATION("Profile.SyncCustomize", metric,
268                             NUM_PROFILE_SYNC_METRICS);
269 }
270 
LogProfileLaunch(Profile * profile)271 void ProfileMetrics::LogProfileLaunch(Profile* profile) {
272   base::FilePath profile_path = profile->GetPath();
273   UMA_HISTOGRAM_ENUMERATION("Profile.LaunchBrowser",
274                             GetProfileType(profile_path),
275                             NUM_PROFILE_TYPE_METRICS);
276 
277   if (profile->IsManaged()) {
278     content::RecordAction(
279         content::UserMetricsAction("ManagedMode_NewManagedUserWindow"));
280   }
281 }
282 
LogProfileSyncSignIn(const base::FilePath & profile_path)283 void ProfileMetrics::LogProfileSyncSignIn(const base::FilePath& profile_path) {
284   UMA_HISTOGRAM_ENUMERATION("Profile.SyncSignIn",
285                             GetProfileType(profile_path),
286                             NUM_PROFILE_TYPE_METRICS);
287 }
288 
LogProfileUpdate(const base::FilePath & profile_path)289 void ProfileMetrics::LogProfileUpdate(const base::FilePath& profile_path) {
290   UMA_HISTOGRAM_ENUMERATION("Profile.Update",
291                             GetProfileType(profile_path),
292                             NUM_PROFILE_TYPE_METRICS);
293 }
294