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 28 ProfileCounts() : total(0), signedin(0), managed(0) {} 29 }; 30 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 47 void UpdateReportedOSProfileStatistics(int active, int signedin) { 48 #if defined(OS_WIN) 49 GoogleUpdateSettings::UpdateProfileCounts(active, signedin); 50 #endif 51 } 52 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 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 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 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 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 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 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 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 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 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 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 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 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