Home | History | Annotate | Download | only in profiles
      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