Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / app_list / app_list_service_impl.cc
blob043da34896f22c3d8a14cce14981d3f0535f6bdb
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.
5 #include "chrome/browser/ui/app_list/app_list_service_impl.h"
7 #include <string>
9 #include "apps/pref_names.h"
10 #include "base/command_line.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string16.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/apps/shortcut_manager.h"
16 #include "chrome/browser/apps/shortcut_manager_factory.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/ui/app_list/keep_alive_service.h"
20 #include "chrome/browser/ui/app_list/keep_alive_service_impl.h"
21 #include "chrome/browser/ui/app_list/profile_loader.h"
22 #include "chrome/browser/ui/app_list/profile_store.h"
23 #include "chrome/common/chrome_constants.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h"
26 #include "content/public/browser/browser_thread.h"
28 namespace {
30 void SendAppListAppLaunch(int count) {
31 UMA_HISTOGRAM_CUSTOM_COUNTS(
32 "Apps.AppListDailyAppLaunches", count, 1, 1000, 50);
33 if (count > 0)
34 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2);
37 void SendAppListLaunch(int count) {
38 UMA_HISTOGRAM_CUSTOM_COUNTS(
39 "Apps.AppListDailyLaunches", count, 1, 1000, 50);
40 if (count > 0)
41 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppListToday", 1, 2);
44 bool SendDailyEventFrequency(
45 const char* last_ping_pref,
46 const char* count_pref,
47 void (*send_callback)(int count)) {
48 PrefService* local_state = g_browser_process->local_state();
50 base::Time now = base::Time::Now();
51 base::Time last = base::Time::FromInternalValue(local_state->GetInt64(
52 last_ping_pref));
53 int days = (now - last).InDays();
54 if (days > 0) {
55 send_callback(local_state->GetInteger(count_pref));
56 local_state->SetInt64(
57 last_ping_pref,
58 (last + base::TimeDelta::FromDays(days)).ToInternalValue());
59 local_state->SetInteger(count_pref, 0);
60 return true;
62 return false;
65 void RecordDailyEventFrequency(
66 const char* last_ping_pref,
67 const char* count_pref,
68 void (*send_callback)(int count)) {
69 PrefService* local_state = g_browser_process->local_state();
71 int count = local_state->GetInteger(count_pref);
72 local_state->SetInteger(count_pref, count + 1);
73 if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) {
74 local_state->SetInteger(count_pref, 1);
78 class ProfileStoreImpl : public ProfileStore {
79 public:
80 explicit ProfileStoreImpl(ProfileManager* profile_manager)
81 : profile_manager_(profile_manager),
82 weak_factory_(this) {
85 virtual void AddProfileObserver(ProfileInfoCacheObserver* observer) OVERRIDE {
86 profile_manager_->GetProfileInfoCache().AddObserver(observer);
89 virtual void LoadProfileAsync(
90 const base::FilePath& path,
91 base::Callback<void(Profile*)> callback) OVERRIDE {
92 profile_manager_->CreateProfileAsync(
93 path,
94 base::Bind(&ProfileStoreImpl::OnProfileCreated,
95 weak_factory_.GetWeakPtr(),
96 callback),
97 base::string16(),
98 base::string16(),
99 std::string());
102 void OnProfileCreated(base::Callback<void(Profile*)> callback,
103 Profile* profile,
104 Profile::CreateStatus status) {
105 switch (status) {
106 case Profile::CREATE_STATUS_CREATED:
107 break;
108 case Profile::CREATE_STATUS_INITIALIZED:
109 callback.Run(profile);
110 break;
111 case Profile::CREATE_STATUS_LOCAL_FAIL:
112 case Profile::CREATE_STATUS_REMOTE_FAIL:
113 case Profile::CREATE_STATUS_CANCELED:
114 break;
115 case Profile::MAX_CREATE_STATUS:
116 NOTREACHED();
117 break;
121 virtual Profile* GetProfileByPath(const base::FilePath& path) OVERRIDE {
122 return profile_manager_->GetProfileByPath(path);
125 virtual base::FilePath GetUserDataDir() OVERRIDE {
126 return profile_manager_->user_data_dir();
129 virtual bool IsProfileManaged(const base::FilePath& profile_path) OVERRIDE {
130 ProfileInfoCache& profile_info =
131 g_browser_process->profile_manager()->GetProfileInfoCache();
132 size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path);
133 return profile_info.ProfileIsManagedAtIndex(profile_index);
136 private:
137 ProfileManager* profile_manager_;
138 base::WeakPtrFactory<ProfileStoreImpl> weak_factory_;
141 } // namespace
143 // static
144 void AppListServiceImpl::RecordAppListLaunch() {
145 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing,
146 prefs::kAppListLaunchCount,
147 &SendAppListLaunch);
150 // static
151 void AppListServiceImpl::RecordAppListAppLaunch() {
152 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing,
153 prefs::kAppListAppLaunchCount,
154 &SendAppListAppLaunch);
157 // static
158 void AppListServiceImpl::SendAppListStats() {
159 if (!g_browser_process || g_browser_process->IsShuttingDown())
160 return;
162 SendDailyEventFrequency(prefs::kLastAppListLaunchPing,
163 prefs::kAppListLaunchCount,
164 &SendAppListLaunch);
165 SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing,
166 prefs::kAppListAppLaunchCount,
167 &SendAppListAppLaunch);
170 AppListServiceImpl::AppListServiceImpl()
171 : profile_store_(new ProfileStoreImpl(
172 g_browser_process->profile_manager())),
173 weak_factory_(this),
174 command_line_(*CommandLine::ForCurrentProcess()),
175 local_state_(g_browser_process->local_state()),
176 profile_loader_(new ProfileLoader(
177 profile_store_.get(),
178 scoped_ptr<KeepAliveService>(new KeepAliveServiceImpl))) {
179 profile_store_->AddProfileObserver(this);
182 AppListServiceImpl::AppListServiceImpl(
183 const CommandLine& command_line,
184 PrefService* local_state,
185 scoped_ptr<ProfileStore> profile_store,
186 scoped_ptr<KeepAliveService> keep_alive_service)
187 : profile_store_(profile_store.Pass()),
188 weak_factory_(this),
189 command_line_(command_line),
190 local_state_(local_state),
191 profile_loader_(new ProfileLoader(
192 profile_store_.get(), keep_alive_service.Pass())) {
193 profile_store_->AddProfileObserver(this);
196 AppListServiceImpl::~AppListServiceImpl() {}
198 void AppListServiceImpl::SetAppListNextPaintCallback(void (*callback)()) {}
200 void AppListServiceImpl::HandleFirstRun() {}
202 void AppListServiceImpl::Init(Profile* initial_profile) {}
204 base::FilePath AppListServiceImpl::GetProfilePath(
205 const base::FilePath& user_data_dir) {
206 std::string app_list_profile;
207 if (local_state_->HasPrefPath(prefs::kAppListProfile))
208 app_list_profile = local_state_->GetString(prefs::kAppListProfile);
210 // If the user has no profile preference for the app launcher, default to the
211 // last browser profile used.
212 if (app_list_profile.empty() &&
213 local_state_->HasPrefPath(prefs::kProfileLastUsed)) {
214 app_list_profile = local_state_->GetString(prefs::kProfileLastUsed);
217 // If there is no last used profile recorded, use the initial profile.
218 if (app_list_profile.empty())
219 app_list_profile = chrome::kInitialProfile;
221 return user_data_dir.AppendASCII(app_list_profile);
224 void AppListServiceImpl::SetProfilePath(const base::FilePath& profile_path) {
225 // Ensure we don't set the pref to a managed user's profile path.
226 // TODO(calamity): Filter out managed profiles from the settings app so this
227 // can't get hit, so we can remove it.
228 if (profile_store_->IsProfileManaged(profile_path))
229 return;
231 local_state_->SetString(
232 prefs::kAppListProfile,
233 profile_path.BaseName().MaybeAsASCII());
236 void AppListServiceImpl::CreateShortcut() {}
238 // We need to watch for profile removal to keep kAppListProfile updated.
239 void AppListServiceImpl::OnProfileWillBeRemoved(
240 const base::FilePath& profile_path) {
241 // If the profile the app list uses just got deleted, reset it to the last
242 // used profile.
243 std::string app_list_last_profile = local_state_->GetString(
244 prefs::kAppListProfile);
245 if (profile_path.BaseName().MaybeAsASCII() == app_list_last_profile) {
246 local_state_->SetString(prefs::kAppListProfile,
247 local_state_->GetString(prefs::kProfileLastUsed));
251 void AppListServiceImpl::Show() {
252 profile_loader_->LoadProfileInvalidatingOtherLoads(
253 GetProfilePath(profile_store_->GetUserDataDir()),
254 base::Bind(&AppListServiceImpl::ShowForProfile,
255 weak_factory_.GetWeakPtr()));
258 void AppListServiceImpl::EnableAppList(Profile* initial_profile) {
259 SetProfilePath(initial_profile->GetPath());
260 if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled))
261 return;
263 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true);
264 CreateShortcut();
265 AppShortcutManager* shortcut_manager =
266 AppShortcutManagerFactory::GetForProfile(initial_profile);
267 if (shortcut_manager)
268 shortcut_manager->OnceOffCreateShortcuts();
271 void AppListServiceImpl::InvalidatePendingProfileLoads() {
272 profile_loader_->InvalidatePendingProfileLoads();
275 void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) {
276 if (command_line_.HasSwitch(switches::kResetAppListInstallState))
277 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false);
279 if (command_line_.HasSwitch(switches::kEnableAppList))
280 EnableAppList(initial_profile);
283 void AppListServiceImpl::SendUsageStats() {
284 // Send app list usage stats after a delay.
285 const int kSendUsageStatsDelay = 5;
286 base::MessageLoop::current()->PostDelayedTask(
287 FROM_HERE,
288 base::Bind(&AppListServiceImpl::SendAppListStats),
289 base::TimeDelta::FromSeconds(kSendUsageStatsDelay));