OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/app_list/app_list_service_impl.h" | 5 #include "chrome/browser/ui/app_list/app_list_service_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "apps/pref_names.h" | 9 #include "apps/pref_names.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "chrome/browser/apps/shortcut_manager.h" | 15 #include "chrome/browser/apps/shortcut_manager.h" |
16 #include "chrome/browser/apps/shortcut_manager_factory.h" | 16 #include "chrome/browser/apps/shortcut_manager_factory.h" |
17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
18 #include "chrome/browser/browser_shutdown.h" | |
18 #include "chrome/browser/profiles/profile_manager.h" | 19 #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.h" |
20 #include "chrome/browser/ui/app_list/keep_alive_service_impl.h" | 21 #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_loader.h" |
22 #include "chrome/browser/ui/app_list/profile_store.h" | 23 #include "chrome/browser/ui/app_list/profile_store.h" |
23 #include "chrome/common/chrome_constants.h" | 24 #include "chrome/common/chrome_constants.h" |
24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
25 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
26 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
31 const int kDiscoverabilityTimeoutMinutes = 60; | |
32 | |
30 void SendAppListAppLaunch(int count) { | 33 void SendAppListAppLaunch(int count) { |
31 UMA_HISTOGRAM_CUSTOM_COUNTS( | 34 UMA_HISTOGRAM_CUSTOM_COUNTS( |
32 "Apps.AppListDailyAppLaunches", count, 1, 1000, 50); | 35 "Apps.AppListDailyAppLaunches", count, 1, 1000, 50); |
33 if (count > 0) | 36 if (count > 0) |
34 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2); | 37 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2); |
35 } | 38 } |
36 | 39 |
37 void SendAppListLaunch(int count) { | 40 void SendAppListLaunch(int count) { |
38 UMA_HISTOGRAM_CUSTOM_COUNTS( | 41 UMA_HISTOGRAM_CUSTOM_COUNTS( |
39 "Apps.AppListDailyLaunches", count, 1, 1000, 50); | 42 "Apps.AppListDailyLaunches", count, 1, 1000, 50); |
(...skipping 19 matching lines...) Expand all Loading... | |
59 local_state->SetInteger(count_pref, 0); | 62 local_state->SetInteger(count_pref, 0); |
60 return true; | 63 return true; |
61 } | 64 } |
62 return false; | 65 return false; |
63 } | 66 } |
64 | 67 |
65 void RecordDailyEventFrequency( | 68 void RecordDailyEventFrequency( |
66 const char* last_ping_pref, | 69 const char* last_ping_pref, |
67 const char* count_pref, | 70 const char* count_pref, |
68 void (*send_callback)(int count)) { | 71 void (*send_callback)(int count)) { |
72 if (!g_browser_process) | |
73 return; // In a unit test. | |
74 | |
69 PrefService* local_state = g_browser_process->local_state(); | 75 PrefService* local_state = g_browser_process->local_state(); |
70 | 76 |
71 int count = local_state->GetInteger(count_pref); | 77 int count = local_state->GetInteger(count_pref); |
72 local_state->SetInteger(count_pref, count + 1); | 78 local_state->SetInteger(count_pref, count + 1); |
73 if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) { | 79 if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) { |
74 local_state->SetInteger(count_pref, 1); | 80 local_state->SetInteger(count_pref, 1); |
75 } | 81 } |
76 } | 82 } |
77 | 83 |
78 class ProfileStoreImpl : public ProfileStore { | 84 class ProfileStoreImpl : public ProfileStore { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 g_browser_process->profile_manager()->GetProfileInfoCache(); | 137 g_browser_process->profile_manager()->GetProfileInfoCache(); |
132 size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path); | 138 size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path); |
133 return profile_info.ProfileIsManagedAtIndex(profile_index); | 139 return profile_info.ProfileIsManagedAtIndex(profile_index); |
134 } | 140 } |
135 | 141 |
136 private: | 142 private: |
137 ProfileManager* profile_manager_; | 143 ProfileManager* profile_manager_; |
138 base::WeakPtrFactory<ProfileStoreImpl> weak_factory_; | 144 base::WeakPtrFactory<ProfileStoreImpl> weak_factory_; |
139 }; | 145 }; |
140 | 146 |
147 void RecordAppListDiscoverability(PrefService* local_state, | |
148 bool is_startup_check) { | |
benwells
2014/02/09 21:08:07
Nit: consider changing this parameter to was_launc
tapted
2014/02/10 02:54:29
At first I thought you meant ~was_(browser_process
benwells
2014/02/10 06:03:27
OK, sounds reasonable.
| |
149 if (browser_shutdown::IsTryingToQuit()) | |
benwells
2014/02/09 21:08:07
Nit: can you add a comment explaining when this ha
tapted
2014/02/10 02:54:29
Done.
| |
150 return; | |
151 | |
152 int64 enable_time_value = local_state->GetInt64(prefs::kAppListEnableTime); | |
153 if (enable_time_value == 0) | |
154 return; // Already recorded or never enabled. | |
155 | |
156 base::Time app_list_enable_time = | |
157 base::Time::FromInternalValue(enable_time_value); | |
158 if (is_startup_check) { | |
159 // When checking at startup, only clear and record the "timeout" case, | |
160 // otherwise wait for a timeout. | |
161 base::TimeDelta time_remaining = app_list_enable_time + | |
162 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes) - | |
163 base::Time::Now(); | |
164 if (time_remaining > base::TimeDelta()) { | |
165 base::MessageLoop::current()->PostDelayedTask( | |
166 FROM_HERE, | |
167 base::Bind(&RecordAppListDiscoverability, | |
168 base::Unretained(local_state), | |
169 false), | |
170 time_remaining); | |
171 return; | |
172 } | |
173 } | |
174 | |
175 local_state->SetInt64(prefs::kAppListEnableTime, 0); | |
176 | |
177 AppListService::AppListEnableSource enable_source = | |
178 static_cast<AppListService::AppListEnableSource>( | |
179 local_state->GetInteger(prefs::kAppListEnableMethod)); | |
180 if (enable_source == AppListService::ENABLE_FOR_APP_INSTALL) { | |
181 base::TimeDelta time_taken = base::Time::Now() - app_list_enable_time; | |
182 // This means the user "discovered" the app launcher naturally, after it was | |
183 // enabled on the first app install. Record how long it took to discover. | |
184 // Note that the last bucket is essentially "not discovered": subtract 1 | |
185 // minute to account for clock inaccuracy. | |
186 UMA_HISTOGRAM_CUSTOM_TIMES( | |
187 "Apps.AppListTimeToDiscover", | |
188 time_taken, | |
189 base::TimeDelta::FromSeconds(1), | |
190 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes - 1), | |
191 10 /* bucket_count */); | |
192 } | |
193 UMA_HISTOGRAM_ENUMERATION( | |
194 "Apps.AppListHowEnabled", | |
195 enable_source, | |
196 AppListService::ENABLE_NUM_ENABLE_SOURCES); | |
197 } | |
198 | |
141 } // namespace | 199 } // namespace |
142 | 200 |
143 // static | |
144 void AppListServiceImpl::RecordAppListLaunch() { | 201 void AppListServiceImpl::RecordAppListLaunch() { |
145 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, | 202 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, |
146 prefs::kAppListLaunchCount, | 203 prefs::kAppListLaunchCount, |
147 &SendAppListLaunch); | 204 &SendAppListLaunch); |
205 RecordAppListDiscoverability(local_state_, false); | |
148 } | 206 } |
149 | 207 |
150 // static | 208 // static |
151 void AppListServiceImpl::RecordAppListAppLaunch() { | 209 void AppListServiceImpl::RecordAppListAppLaunch() { |
152 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, | 210 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, |
153 prefs::kAppListAppLaunchCount, | 211 prefs::kAppListAppLaunchCount, |
154 &SendAppListAppLaunch); | 212 &SendAppListAppLaunch); |
155 } | 213 } |
156 | 214 |
157 // static | 215 // static |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 } | 306 } |
249 } | 307 } |
250 | 308 |
251 void AppListServiceImpl::Show() { | 309 void AppListServiceImpl::Show() { |
252 profile_loader_->LoadProfileInvalidatingOtherLoads( | 310 profile_loader_->LoadProfileInvalidatingOtherLoads( |
253 GetProfilePath(profile_store_->GetUserDataDir()), | 311 GetProfilePath(profile_store_->GetUserDataDir()), |
254 base::Bind(&AppListServiceImpl::ShowForProfile, | 312 base::Bind(&AppListServiceImpl::ShowForProfile, |
255 weak_factory_.GetWeakPtr())); | 313 weak_factory_.GetWeakPtr())); |
256 } | 314 } |
257 | 315 |
258 void AppListServiceImpl::EnableAppList(Profile* initial_profile) { | 316 void AppListServiceImpl::AutoShowForProfile(Profile* requested_profile) { |
317 local_state_->SetInteger(prefs::kAppListEnableMethod, | |
318 ENABLE_ALREADY_ENABLED); | |
benwells
2014/02/09 21:08:07
This is unclear. I think it means that the app lis
tapted
2014/02/10 02:54:29
Yep - I agree it sounds weird. This kinda made sen
| |
319 ShowForProfile(requested_profile); | |
320 } | |
321 | |
322 void AppListServiceImpl::EnableAppList(Profile* initial_profile, | |
323 AppListEnableSource enable_source) { | |
259 SetProfilePath(initial_profile->GetPath()); | 324 SetProfilePath(initial_profile->GetPath()); |
260 if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled)) | 325 if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled)) |
261 return; | 326 return; |
262 | 327 |
263 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true); | 328 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true); |
264 CreateShortcut(); | 329 CreateShortcut(); |
330 | |
331 // UMA for launcher discoverability. | |
332 local_state_->SetInt64(prefs::kAppListEnableTime, | |
333 base::Time::Now().ToInternalValue()); | |
334 local_state_->SetInteger(prefs::kAppListEnableMethod, | |
335 enable_source); | |
336 if (base::MessageLoop::current()) { | |
337 // Ensure a value is recorded if the user "never" shows the app list. Note | |
338 // there is no message loop in unit tests. | |
339 base::MessageLoop::current()->PostDelayedTask( | |
340 FROM_HERE, | |
341 base::Bind(&RecordAppListDiscoverability, | |
342 base::Unretained(local_state_), | |
343 false), | |
344 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes)); | |
345 } | |
346 | |
265 AppShortcutManager* shortcut_manager = | 347 AppShortcutManager* shortcut_manager = |
266 AppShortcutManagerFactory::GetForProfile(initial_profile); | 348 AppShortcutManagerFactory::GetForProfile(initial_profile); |
267 if (shortcut_manager) | 349 if (shortcut_manager) |
268 shortcut_manager->OnceOffCreateShortcuts(); | 350 shortcut_manager->OnceOffCreateShortcuts(); |
269 } | 351 } |
270 | 352 |
271 void AppListServiceImpl::InvalidatePendingProfileLoads() { | 353 void AppListServiceImpl::InvalidatePendingProfileLoads() { |
272 profile_loader_->InvalidatePendingProfileLoads(); | 354 profile_loader_->InvalidatePendingProfileLoads(); |
273 } | 355 } |
274 | 356 |
275 void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) { | 357 void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) { |
358 RecordAppListDiscoverability(local_state_, true); | |
benwells
2014/02/09 21:08:07
This doesn't seem like the right home for this.
tapted
2014/02/10 02:54:29
See how it feels now :). Renamed function to `Perf
| |
276 if (command_line_.HasSwitch(switches::kResetAppListInstallState)) | 359 if (command_line_.HasSwitch(switches::kResetAppListInstallState)) |
277 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false); | 360 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false); |
278 | 361 |
279 if (command_line_.HasSwitch(switches::kEnableAppList)) | 362 if (command_line_.HasSwitch(switches::kEnableAppList)) |
280 EnableAppList(initial_profile); | 363 EnableAppList(initial_profile, ENABLE_VIA_COMMAND_LINE); |
281 } | 364 } |
282 | 365 |
283 void AppListServiceImpl::SendUsageStats() { | 366 void AppListServiceImpl::SendUsageStats() { |
284 // Send app list usage stats after a delay. | 367 // Send app list usage stats after a delay. |
285 const int kSendUsageStatsDelay = 5; | 368 const int kSendUsageStatsDelay = 5; |
286 base::MessageLoop::current()->PostDelayedTask( | 369 base::MessageLoop::current()->PostDelayedTask( |
287 FROM_HERE, | 370 FROM_HERE, |
288 base::Bind(&AppListServiceImpl::SendAppListStats), | 371 base::Bind(&AppListServiceImpl::SendAppListStats), |
289 base::TimeDelta::FromSeconds(kSendUsageStatsDelay)); | 372 base::TimeDelta::FromSeconds(kSendUsageStatsDelay)); |
290 } | 373 } |
OLD | NEW |