app_list_service_impl.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
1// Copyright 2013 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/ui/app_list/app_list_service_impl.h" 6 7#include "apps/pref_names.h" 8#include "base/command_line.h" 9#include "base/metrics/histogram.h" 10#include "base/prefs/pref_service.h" 11#include "base/time/time.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/chrome_notification_types.h" 14#include "chrome/browser/profiles/profile_manager.h" 15#include "chrome/common/chrome_constants.h" 16#include "chrome/common/chrome_switches.h" 17#include "chrome/common/pref_names.h" 18#include "content/public/browser/browser_thread.h" 19#include "content/public/browser/notification_details.h" 20#include "content/public/browser/notification_source.h" 21 22namespace { 23 24void SendAppListAppLaunch(int count) { 25 UMA_HISTOGRAM_CUSTOM_COUNTS( 26 "Apps.AppListDailyAppLaunches", count, 1, 1000, 50); 27 if (count > 0) 28 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2); 29} 30 31void SendAppListLaunch(int count) { 32 UMA_HISTOGRAM_CUSTOM_COUNTS( 33 "Apps.AppListDailyLaunches", count, 1, 1000, 50); 34 if (count > 0) 35 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppListToday", 1, 2); 36} 37 38bool SendDailyEventFrequency( 39 const char* last_ping_pref, 40 const char* count_pref, 41 void (*send_callback)(int count)) { 42 PrefService* local_state = g_browser_process->local_state(); 43 44 base::Time now = base::Time::Now(); 45 base::Time last = base::Time::FromInternalValue(local_state->GetInt64( 46 last_ping_pref)); 47 int days = (now - last).InDays(); 48 if (days > 0) { 49 send_callback(local_state->GetInteger(count_pref)); 50 local_state->SetInt64( 51 last_ping_pref, 52 (last + base::TimeDelta::FromDays(days)).ToInternalValue()); 53 local_state->SetInteger(count_pref, 0); 54 return true; 55 } 56 return false; 57} 58 59void RecordDailyEventFrequency( 60 const char* last_ping_pref, 61 const char* count_pref, 62 void (*send_callback)(int count)) { 63 PrefService* local_state = g_browser_process->local_state(); 64 65 int count = local_state->GetInteger(count_pref); 66 local_state->SetInteger(count_pref, count + 1); 67 if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) { 68 local_state->SetInteger(count_pref, 1); 69 } 70} 71 72bool HasAppListEnabledPreference() { 73 PrefService* local_state = g_browser_process->local_state(); 74 return local_state->GetBoolean(apps::prefs::kAppLauncherHasBeenEnabled); 75} 76 77void SetAppListEnabledPreference(bool enabled) { 78 PrefService* local_state = g_browser_process->local_state(); 79 local_state->SetBoolean(apps::prefs::kAppLauncherHasBeenEnabled, enabled); 80} 81 82} // namespace 83 84// static 85void AppListServiceImpl::RecordAppListLaunch() { 86 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, 87 prefs::kAppListLaunchCount, 88 &SendAppListLaunch); 89} 90 91// static 92void AppListServiceImpl::RecordAppListAppLaunch() { 93 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 94 prefs::kAppListAppLaunchCount, 95 &SendAppListAppLaunch); 96} 97 98// static 99void AppListServiceImpl::SendAppListStats() { 100 if (!g_browser_process || g_browser_process->IsShuttingDown()) 101 return; 102 103 SendDailyEventFrequency(prefs::kLastAppListLaunchPing, 104 prefs::kAppListLaunchCount, 105 &SendAppListLaunch); 106 SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 107 prefs::kAppListAppLaunchCount, 108 &SendAppListAppLaunch); 109} 110 111AppListServiceImpl::AppListServiceImpl() 112 : profile_(NULL), 113 profile_load_sequence_id_(0), 114 pending_profile_loads_(0), 115 weak_factory_(this), 116 profile_loader_(g_browser_process->profile_manager()) { 117 ProfileManager* profile_manager = g_browser_process->profile_manager(); 118 profile_manager->GetProfileInfoCache().AddObserver(this); 119} 120 121AppListServiceImpl::~AppListServiceImpl() {} 122 123void AppListServiceImpl::HandleFirstRun() {} 124 125void AppListServiceImpl::Init(Profile* initial_profile) {} 126 127base::FilePath AppListServiceImpl::GetProfilePath( 128 const base::FilePath& user_data_dir) { 129 PrefService* local_state = g_browser_process->local_state(); 130 DCHECK(local_state); 131 132 std::string app_list_profile; 133 if (local_state->HasPrefPath(prefs::kAppListProfile)) 134 app_list_profile = local_state->GetString(prefs::kAppListProfile); 135 136 // If the user has no profile preference for the app launcher, default to the 137 // last browser profile used. 138 if (app_list_profile.empty() && 139 local_state->HasPrefPath(prefs::kProfileLastUsed)) { 140 app_list_profile = local_state->GetString(prefs::kProfileLastUsed); 141 } 142 143 // If there is no last used profile recorded, use the initial profile. 144 if (app_list_profile.empty()) 145 app_list_profile = chrome::kInitialProfile; 146 147 return user_data_dir.AppendASCII(app_list_profile); 148} 149 150void AppListServiceImpl::SetProfilePath(const base::FilePath& profile_path) { 151 g_browser_process->local_state()->SetString( 152 prefs::kAppListProfile, 153 profile_path.BaseName().MaybeAsASCII()); 154} 155 156AppListControllerDelegate* AppListServiceImpl::CreateControllerDelegate() { 157 return NULL; 158} 159 160void AppListServiceImpl::CreateShortcut() {} 161void AppListServiceImpl::OnSigninStatusChanged() {} 162 163// We need to watch for profile removal to keep kAppListProfile updated. 164void AppListServiceImpl::OnProfileWillBeRemoved( 165 const base::FilePath& profile_path) { 166 // If the profile the app list uses just got deleted, reset it to the last 167 // used profile. 168 PrefService* local_state = g_browser_process->local_state(); 169 std::string app_list_last_profile = local_state->GetString( 170 prefs::kAppListProfile); 171 if (profile_path.BaseName().MaybeAsASCII() == app_list_last_profile) { 172 local_state->SetString(prefs::kAppListProfile, 173 local_state->GetString(prefs::kProfileLastUsed)); 174 } 175} 176 177void AppListServiceImpl::Observe( 178 int type, 179 const content::NotificationSource& source, 180 const content::NotificationDetails& details) { 181 OnSigninStatusChanged(); 182} 183 184void AppListServiceImpl::Show() { 185 profile_loader_.LoadProfileInvalidatingOtherLoads( 186 GetProfilePath(g_browser_process->profile_manager()->user_data_dir()), 187 base::Bind(&AppListServiceImpl::ShowForProfile, 188 weak_factory_.GetWeakPtr())); 189} 190 191void AppListServiceImpl::EnableAppList(Profile* initial_profile) { 192 SetProfilePath(initial_profile->GetPath()); 193 if (HasAppListEnabledPreference()) 194 return; 195 196 SetAppListEnabledPreference(true); 197 CreateShortcut(); 198} 199 200Profile* AppListServiceImpl::GetCurrentAppListProfile() { 201 return profile(); 202} 203 204void AppListServiceImpl::SetProfile(Profile* new_profile) { 205 registrar_.RemoveAll(); 206 profile_ = new_profile; 207 if (!profile_) 208 return; 209 210 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 211 content::Source<Profile>(profile_)); 212 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, 213 content::Source<Profile>(profile_)); 214 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 215 content::Source<Profile>(profile_)); 216} 217 218void AppListServiceImpl::InvalidatePendingProfileLoads() { 219 profile_loader_.InvalidatePendingProfileLoads(); 220} 221 222void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) { 223 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppList)) 224 EnableAppList(initial_profile); 225 226 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableAppList)) 227 SetAppListEnabledPreference(false); 228} 229