app_list_service_impl.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 "base/metrics/histogram.h" 8#include "base/prefs/pref_service.h" 9#include "base/time/time.h" 10#include "chrome/browser/browser_process.h" 11#include "chrome/browser/chrome_notification_types.h" 12#include "chrome/browser/profiles/profile_manager.h" 13#include "chrome/common/chrome_constants.h" 14#include "chrome/common/pref_names.h" 15#include "content/public/browser/browser_thread.h" 16#include "content/public/browser/notification_details.h" 17#include "content/public/browser/notification_source.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 69} // namespace 70 71// static 72void AppListServiceImpl::RecordAppListLaunch() { 73 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, 74 prefs::kAppListLaunchCount, 75 &SendAppListLaunch); 76} 77 78// static 79void AppListServiceImpl::RecordAppListAppLaunch() { 80 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 81 prefs::kAppListAppLaunchCount, 82 &SendAppListAppLaunch); 83} 84 85// static 86void AppListServiceImpl::SendAppListStats() { 87 if (!g_browser_process || g_browser_process->IsShuttingDown()) 88 return; 89 90 SendDailyEventFrequency(prefs::kLastAppListLaunchPing, 91 prefs::kAppListLaunchCount, 92 &SendAppListLaunch); 93 SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 94 prefs::kAppListAppLaunchCount, 95 &SendAppListAppLaunch); 96} 97 98AppListServiceImpl::AppListServiceImpl() 99 : profile_(NULL), 100 profile_load_sequence_id_(0), 101 pending_profile_loads_(0), 102 weak_factory_(this), 103 profile_loader_(g_browser_process->profile_manager()) { 104 ProfileManager* profile_manager = g_browser_process->profile_manager(); 105 profile_manager->GetProfileInfoCache().AddObserver(this); 106} 107 108AppListServiceImpl::~AppListServiceImpl() {} 109 110void AppListServiceImpl::Init(Profile* initial_profile) {} 111 112base::FilePath AppListServiceImpl::GetProfilePath( 113 const base::FilePath& user_data_dir) { 114 PrefService* local_state = g_browser_process->local_state(); 115 DCHECK(local_state); 116 117 std::string app_list_profile; 118 if (local_state->HasPrefPath(prefs::kAppListProfile)) 119 app_list_profile = local_state->GetString(prefs::kAppListProfile); 120 121 // If the user has no profile preference for the app launcher, default to the 122 // last browser profile used. 123 if (app_list_profile.empty() && 124 local_state->HasPrefPath(prefs::kProfileLastUsed)) 125 app_list_profile = local_state->GetString(prefs::kProfileLastUsed); 126 127 std::string profile_path = app_list_profile.empty() ? 128 chrome::kInitialProfile : 129 app_list_profile; 130 131 return user_data_dir.AppendASCII(profile_path); 132} 133 134AppListControllerDelegate* AppListServiceImpl::CreateControllerDelegate() { 135 return NULL; 136} 137 138void AppListServiceImpl::OnSigninStatusChanged() {} 139 140// We need to watch for profile removal to keep kAppListProfile updated. 141void AppListServiceImpl::OnProfileWillBeRemoved( 142 const base::FilePath& profile_path) { 143 // If the profile the app list uses just got deleted, reset it to the last 144 // used profile. 145 PrefService* local_state = g_browser_process->local_state(); 146 std::string app_list_last_profile = local_state->GetString( 147 prefs::kAppListProfile); 148 if (profile_path.BaseName().MaybeAsASCII() == app_list_last_profile) { 149 local_state->SetString(prefs::kAppListProfile, 150 local_state->GetString(prefs::kProfileLastUsed)); 151 } 152} 153 154void AppListServiceImpl::Observe( 155 int type, 156 const content::NotificationSource& source, 157 const content::NotificationDetails& details) { 158 OnSigninStatusChanged(); 159} 160 161void AppListServiceImpl::SetAppListProfile( 162 const base::FilePath& profile_file_path) { 163 profile_loader_.LoadProfileInvalidatingOtherLoads( 164 profile_file_path, base::Bind(&AppListServiceImpl::ShowAppList, 165 weak_factory_.GetWeakPtr())); 166} 167 168void AppListServiceImpl::ShowForSavedProfile() { 169 SetAppListProfile(GetProfilePath( 170 g_browser_process->profile_manager()->user_data_dir())); 171} 172 173Profile* AppListServiceImpl::GetCurrentAppListProfile() { 174 return profile(); 175} 176 177void AppListServiceImpl::SetProfile(Profile* new_profile) { 178 registrar_.RemoveAll(); 179 profile_ = new_profile; 180 if (!profile_) 181 return; 182 183 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 184 content::Source<Profile>(profile_)); 185 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, 186 content::Source<Profile>(profile_)); 187 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 188 content::Source<Profile>(profile_)); 189} 190 191void AppListServiceImpl::InvalidatePendingProfileLoads() { 192 profile_loader_.InvalidatePendingProfileLoads(); 193} 194 195void AppListServiceImpl::SaveProfilePathToLocalState( 196 const base::FilePath& profile_file_path) { 197 g_browser_process->local_state()->SetString( 198 prefs::kAppListProfile, 199 profile_file_path.BaseName().MaybeAsASCII()); 200} 201