app_list_service_impl.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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/profiles/profile_manager.h" 14#include "chrome/common/chrome_constants.h" 15#include "chrome/common/chrome_switches.h" 16#include "chrome/common/pref_names.h" 17#include "content/public/browser/browser_thread.h" 18 19namespace { 20 21void SendAppListAppLaunch(int count) { 22 UMA_HISTOGRAM_CUSTOM_COUNTS( 23 "Apps.AppListDailyAppLaunches", count, 1, 1000, 50); 24 if (count > 0) 25 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2); 26} 27 28void SendAppListLaunch(int count) { 29 UMA_HISTOGRAM_CUSTOM_COUNTS( 30 "Apps.AppListDailyLaunches", count, 1, 1000, 50); 31 if (count > 0) 32 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppListToday", 1, 2); 33} 34 35bool SendDailyEventFrequency( 36 const char* last_ping_pref, 37 const char* count_pref, 38 void (*send_callback)(int count)) { 39 PrefService* local_state = g_browser_process->local_state(); 40 41 base::Time now = base::Time::Now(); 42 base::Time last = base::Time::FromInternalValue(local_state->GetInt64( 43 last_ping_pref)); 44 int days = (now - last).InDays(); 45 if (days > 0) { 46 send_callback(local_state->GetInteger(count_pref)); 47 local_state->SetInt64( 48 last_ping_pref, 49 (last + base::TimeDelta::FromDays(days)).ToInternalValue()); 50 local_state->SetInteger(count_pref, 0); 51 return true; 52 } 53 return false; 54} 55 56void RecordDailyEventFrequency( 57 const char* last_ping_pref, 58 const char* count_pref, 59 void (*send_callback)(int count)) { 60 PrefService* local_state = g_browser_process->local_state(); 61 62 int count = local_state->GetInteger(count_pref); 63 local_state->SetInteger(count_pref, count + 1); 64 if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) { 65 local_state->SetInteger(count_pref, 1); 66 } 67} 68 69bool HasAppListEnabledPreference() { 70 PrefService* local_state = g_browser_process->local_state(); 71 return local_state->GetBoolean(apps::prefs::kAppLauncherHasBeenEnabled); 72} 73 74void SetAppListEnabledPreference(bool enabled) { 75 PrefService* local_state = g_browser_process->local_state(); 76 local_state->SetBoolean(apps::prefs::kAppLauncherHasBeenEnabled, enabled); 77} 78 79} // namespace 80 81// static 82void AppListServiceImpl::RecordAppListLaunch() { 83 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, 84 prefs::kAppListLaunchCount, 85 &SendAppListLaunch); 86} 87 88// static 89void AppListServiceImpl::RecordAppListAppLaunch() { 90 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 91 prefs::kAppListAppLaunchCount, 92 &SendAppListAppLaunch); 93} 94 95// static 96void AppListServiceImpl::SendAppListStats() { 97 if (!g_browser_process || g_browser_process->IsShuttingDown()) 98 return; 99 100 SendDailyEventFrequency(prefs::kLastAppListLaunchPing, 101 prefs::kAppListLaunchCount, 102 &SendAppListLaunch); 103 SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 104 prefs::kAppListAppLaunchCount, 105 &SendAppListAppLaunch); 106} 107 108AppListServiceImpl::AppListServiceImpl() 109 : profile_(NULL), 110 profile_load_sequence_id_(0), 111 pending_profile_loads_(0), 112 weak_factory_(this), 113 profile_loader_(g_browser_process->profile_manager()) { 114 ProfileManager* profile_manager = g_browser_process->profile_manager(); 115 profile_manager->GetProfileInfoCache().AddObserver(this); 116} 117 118AppListServiceImpl::~AppListServiceImpl() {} 119 120void AppListServiceImpl::SetAppListNextPaintCallback( 121 const base::Closure& callback) {} 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 // Ensure we don't set the pref to a managed user's profile path. 152 ProfileInfoCache& profile_info = 153 g_browser_process->profile_manager()->GetProfileInfoCache(); 154 size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path); 155 if (profile_info.ProfileIsManagedAtIndex(profile_index)) 156 return; 157 158 g_browser_process->local_state()->SetString( 159 prefs::kAppListProfile, 160 profile_path.BaseName().MaybeAsASCII()); 161} 162 163void AppListServiceImpl::CreateShortcut() {} 164 165// We need to watch for profile removal to keep kAppListProfile updated. 166void AppListServiceImpl::OnProfileWillBeRemoved( 167 const base::FilePath& profile_path) { 168 // If the profile the app list uses just got deleted, reset it to the last 169 // used profile. 170 PrefService* local_state = g_browser_process->local_state(); 171 std::string app_list_last_profile = local_state->GetString( 172 prefs::kAppListProfile); 173 if (profile_path.BaseName().MaybeAsASCII() == app_list_last_profile) { 174 local_state->SetString(prefs::kAppListProfile, 175 local_state->GetString(prefs::kProfileLastUsed)); 176 } 177} 178 179void AppListServiceImpl::Show() { 180 profile_loader_.LoadProfileInvalidatingOtherLoads( 181 GetProfilePath(g_browser_process->profile_manager()->user_data_dir()), 182 base::Bind(&AppListServiceImpl::ShowForProfile, 183 weak_factory_.GetWeakPtr())); 184} 185 186void AppListServiceImpl::EnableAppList(Profile* initial_profile) { 187 SetProfilePath(initial_profile->GetPath()); 188 if (HasAppListEnabledPreference()) 189 return; 190 191 SetAppListEnabledPreference(true); 192 CreateShortcut(); 193} 194 195Profile* AppListServiceImpl::GetCurrentAppListProfile() { 196 return profile(); 197} 198 199void AppListServiceImpl::SetProfile(Profile* new_profile) { 200 profile_ = new_profile; 201} 202 203void AppListServiceImpl::InvalidatePendingProfileLoads() { 204 profile_loader_.InvalidatePendingProfileLoads(); 205} 206 207void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) { 208 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppList)) 209 EnableAppList(initial_profile); 210 211 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableAppList)) 212 SetAppListEnabledPreference(false); 213 214 // Send app list usage stats after a delay. 215 const int kSendUsageStatsDelay = 5; 216 base::MessageLoop::current()->PostDelayedTask( 217 FROM_HERE, 218 base::Bind(&AppListServiceImpl::SendAppListStats), 219 base::TimeDelta::FromSeconds(kSendUsageStatsDelay)); 220} 221