Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: chrome/browser/ui/app_list/app_list_service_impl.cc

Issue 143683004: Add UMA to track app launcher discoverability. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: git cl format because it warns now Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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) {
149 // Since this task may be delayed, ensure it does not interfere with shutdown
150 // when they unluckily coincide.
151 if (browser_shutdown::IsTryingToQuit())
152 return;
153
154 int64 enable_time_value = local_state->GetInt64(prefs::kAppListEnableTime);
155 if (enable_time_value == 0)
156 return; // Already recorded or never enabled.
157
158 base::Time app_list_enable_time =
159 base::Time::FromInternalValue(enable_time_value);
160 if (is_startup_check) {
161 // When checking at startup, only clear and record the "timeout" case,
162 // otherwise wait for a timeout.
163 base::TimeDelta time_remaining =
164 app_list_enable_time +
165 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes) -
166 base::Time::Now();
167 if (time_remaining > base::TimeDelta()) {
168 base::MessageLoop::current()->PostDelayedTask(
169 FROM_HERE,
170 base::Bind(&RecordAppListDiscoverability,
171 base::Unretained(local_state),
172 false),
173 time_remaining);
174 return;
175 }
176 }
177
178 local_state->SetInt64(prefs::kAppListEnableTime, 0);
179
180 AppListService::AppListEnableSource enable_source =
181 static_cast<AppListService::AppListEnableSource>(
182 local_state->GetInteger(prefs::kAppListEnableMethod));
183 if (enable_source == AppListService::ENABLE_FOR_APP_INSTALL) {
184 base::TimeDelta time_taken = base::Time::Now() - app_list_enable_time;
185 // This means the user "discovered" the app launcher naturally, after it was
186 // enabled on the first app install. Record how long it took to discover.
187 // Note that the last bucket is essentially "not discovered": subtract 1
188 // minute to account for clock inaccuracy.
189 UMA_HISTOGRAM_CUSTOM_TIMES(
190 "Apps.AppListTimeToDiscover",
191 time_taken,
192 base::TimeDelta::FromSeconds(1),
193 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes - 1),
194 10 /* bucket_count */);
195 }
196 UMA_HISTOGRAM_ENUMERATION("Apps.AppListHowEnabled",
197 enable_source,
198 AppListService::ENABLE_NUM_ENABLE_SOURCES);
199 }
200
141 } // namespace 201 } // namespace
142 202
143 // static
144 void AppListServiceImpl::RecordAppListLaunch() { 203 void AppListServiceImpl::RecordAppListLaunch() {
145 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, 204 RecordDailyEventFrequency(prefs::kLastAppListLaunchPing,
146 prefs::kAppListLaunchCount, 205 prefs::kAppListLaunchCount,
147 &SendAppListLaunch); 206 &SendAppListLaunch);
207 RecordAppListDiscoverability(local_state_, false);
148 } 208 }
149 209
150 // static 210 // static
151 void AppListServiceImpl::RecordAppListAppLaunch() { 211 void AppListServiceImpl::RecordAppListAppLaunch() {
152 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 212 RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing,
153 prefs::kAppListAppLaunchCount, 213 prefs::kAppListAppLaunchCount,
154 &SendAppListAppLaunch); 214 &SendAppListAppLaunch);
155 } 215 }
156 216
157 // static 217 // static
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 } 308 }
249 } 309 }
250 310
251 void AppListServiceImpl::Show() { 311 void AppListServiceImpl::Show() {
252 profile_loader_->LoadProfileInvalidatingOtherLoads( 312 profile_loader_->LoadProfileInvalidatingOtherLoads(
253 GetProfilePath(profile_store_->GetUserDataDir()), 313 GetProfilePath(profile_store_->GetUserDataDir()),
254 base::Bind(&AppListServiceImpl::ShowForProfile, 314 base::Bind(&AppListServiceImpl::ShowForProfile,
255 weak_factory_.GetWeakPtr())); 315 weak_factory_.GetWeakPtr()));
256 } 316 }
257 317
258 void AppListServiceImpl::EnableAppList(Profile* initial_profile) { 318 void AppListServiceImpl::AutoShowForProfile(Profile* requested_profile) {
319 if (local_state_->GetInt64(prefs::kAppListEnableTime) != 0) {
320 // User has not yet discovered the app launcher. Update the enable method to
321 // indicate this. It will then be recorded in UMA.
322 local_state_->SetInteger(prefs::kAppListEnableMethod,
323 ENABLE_SHOWN_UNDISCOVERED);
324 }
325 ShowForProfile(requested_profile);
326 }
327
328 void AppListServiceImpl::EnableAppList(Profile* initial_profile,
329 AppListEnableSource enable_source) {
259 SetProfilePath(initial_profile->GetPath()); 330 SetProfilePath(initial_profile->GetPath());
260 if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled)) 331 if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled))
261 return; 332 return;
262 333
263 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true); 334 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true);
264 CreateShortcut(); 335 CreateShortcut();
336
337 // UMA for launcher discoverability.
338 local_state_->SetInt64(prefs::kAppListEnableTime,
339 base::Time::Now().ToInternalValue());
340 local_state_->SetInteger(prefs::kAppListEnableMethod, enable_source);
341 if (base::MessageLoop::current()) {
342 // Ensure a value is recorded if the user "never" shows the app list. Note
343 // there is no message loop in unit tests.
344 base::MessageLoop::current()->PostDelayedTask(
345 FROM_HERE,
346 base::Bind(&RecordAppListDiscoverability,
347 base::Unretained(local_state_),
348 false),
349 base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes));
350 }
351
265 AppShortcutManager* shortcut_manager = 352 AppShortcutManager* shortcut_manager =
266 AppShortcutManagerFactory::GetForProfile(initial_profile); 353 AppShortcutManagerFactory::GetForProfile(initial_profile);
267 if (shortcut_manager) 354 if (shortcut_manager)
268 shortcut_manager->OnceOffCreateShortcuts(); 355 shortcut_manager->OnceOffCreateShortcuts();
269 } 356 }
270 357
271 void AppListServiceImpl::InvalidatePendingProfileLoads() { 358 void AppListServiceImpl::InvalidatePendingProfileLoads() {
272 profile_loader_->InvalidatePendingProfileLoads(); 359 profile_loader_->InvalidatePendingProfileLoads();
273 } 360 }
274 361
275 void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) { 362 void AppListServiceImpl::PerformStartupChecks(Profile* initial_profile) {
363 // Except in rare, once-off cases, this just checks that a pref is "0" and
364 // returns.
365 RecordAppListDiscoverability(local_state_, true);
366
276 if (command_line_.HasSwitch(switches::kResetAppListInstallState)) 367 if (command_line_.HasSwitch(switches::kResetAppListInstallState))
277 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false); 368 local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false);
278 369
279 if (command_line_.HasSwitch(switches::kEnableAppList)) 370 if (command_line_.HasSwitch(switches::kEnableAppList))
280 EnableAppList(initial_profile); 371 EnableAppList(initial_profile, ENABLE_VIA_COMMAND_LINE);
281 }
282 372
283 void AppListServiceImpl::SendUsageStats() { 373 if (!base::MessageLoop::current())
374 return; // In a unit test.
375
284 // Send app list usage stats after a delay. 376 // Send app list usage stats after a delay.
285 const int kSendUsageStatsDelay = 5; 377 const int kSendUsageStatsDelay = 5;
286 base::MessageLoop::current()->PostDelayedTask( 378 base::MessageLoop::current()->PostDelayedTask(
287 FROM_HERE, 379 FROM_HERE,
288 base::Bind(&AppListServiceImpl::SendAppListStats), 380 base::Bind(&AppListServiceImpl::SendAppListStats),
289 base::TimeDelta::FromSeconds(kSendUsageStatsDelay)); 381 base::TimeDelta::FromSeconds(kSendUsageStatsDelay));
290 } 382 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/app_list/app_list_service_impl.h ('k') | chrome/browser/ui/app_list/app_list_service_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698