Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / app_list / app_list_service_impl.cc
index 043da34..b2d3230 100644 (file)
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "apps/pref_names.h"
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
@@ -15,6 +16,7 @@
 #include "chrome/browser/apps/shortcut_manager.h"
 #include "chrome/browser/apps/shortcut_manager_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/app_list/keep_alive_service.h"
 #include "chrome/browser/ui/app_list/keep_alive_service_impl.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
-#include "content/public/browser/browser_thread.h"
 
 namespace {
 
+const int kDiscoverabilityTimeoutMinutes = 60;
+
 void SendAppListAppLaunch(int count) {
   UMA_HISTOGRAM_CUSTOM_COUNTS(
       "Apps.AppListDailyAppLaunches", count, 1, 1000, 50);
@@ -66,6 +69,9 @@ void RecordDailyEventFrequency(
     const char* last_ping_pref,
     const char* count_pref,
     void (*send_callback)(int count)) {
+  if (!g_browser_process)
+    return;  // In a unit test.
+
   PrefService* local_state = g_browser_process->local_state();
 
   int count = local_state->GetInteger(count_pref);
@@ -138,13 +144,67 @@ class ProfileStoreImpl : public ProfileStore {
   base::WeakPtrFactory<ProfileStoreImpl> weak_factory_;
 };
 
+void RecordAppListDiscoverability(PrefService* local_state,
+                                  bool is_startup_check) {
+  // Since this task may be delayed, ensure it does not interfere with shutdown
+  // when they unluckily coincide.
+  if (browser_shutdown::IsTryingToQuit())
+    return;
+
+  int64 enable_time_value = local_state->GetInt64(prefs::kAppListEnableTime);
+  if (enable_time_value == 0)
+    return;  // Already recorded or never enabled.
+
+  base::Time app_list_enable_time =
+      base::Time::FromInternalValue(enable_time_value);
+  if (is_startup_check) {
+    // When checking at startup, only clear and record the "timeout" case,
+    // otherwise wait for a timeout.
+    base::TimeDelta time_remaining =
+        app_list_enable_time +
+        base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes) -
+        base::Time::Now();
+    if (time_remaining > base::TimeDelta()) {
+      base::MessageLoop::current()->PostDelayedTask(
+          FROM_HERE,
+          base::Bind(&RecordAppListDiscoverability,
+                     base::Unretained(local_state),
+                     false),
+          time_remaining);
+      return;
+    }
+  }
+
+  local_state->SetInt64(prefs::kAppListEnableTime, 0);
+
+  AppListService::AppListEnableSource enable_source =
+      static_cast<AppListService::AppListEnableSource>(
+          local_state->GetInteger(prefs::kAppListEnableMethod));
+  if (enable_source == AppListService::ENABLE_FOR_APP_INSTALL) {
+    base::TimeDelta time_taken = base::Time::Now() - app_list_enable_time;
+    // This means the user "discovered" the app launcher naturally, after it was
+    // enabled on the first app install. Record how long it took to discover.
+    // Note that the last bucket is essentially "not discovered": subtract 1
+    // minute to account for clock inaccuracy.
+    UMA_HISTOGRAM_CUSTOM_TIMES(
+        "Apps.AppListTimeToDiscover",
+        time_taken,
+        base::TimeDelta::FromSeconds(1),
+        base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes - 1),
+        10 /* bucket_count */);
+  }
+  UMA_HISTOGRAM_ENUMERATION("Apps.AppListHowEnabled",
+                            enable_source,
+                            AppListService::ENABLE_NUM_ENABLE_SOURCES);
+}
+
 }  // namespace
 
-// static
 void AppListServiceImpl::RecordAppListLaunch() {
   RecordDailyEventFrequency(prefs::kLastAppListLaunchPing,
                             prefs::kAppListLaunchCount,
                             &SendAppListLaunch);
+  RecordAppListDiscoverability(local_state_, false);
 }
 
 // static
@@ -255,13 +315,40 @@ void AppListServiceImpl::Show() {
                  weak_factory_.GetWeakPtr()));
 }
 
-void AppListServiceImpl::EnableAppList(Profile* initial_profile) {
+void AppListServiceImpl::AutoShowForProfile(Profile* requested_profile) {
+  if (local_state_->GetInt64(prefs::kAppListEnableTime) != 0) {
+    // User has not yet discovered the app launcher. Update the enable method to
+    // indicate this. It will then be recorded in UMA.
+    local_state_->SetInteger(prefs::kAppListEnableMethod,
+                             ENABLE_SHOWN_UNDISCOVERED);
+  }
+  ShowForProfile(requested_profile);
+}
+
+void AppListServiceImpl::EnableAppList(Profile* initial_profile,
+                                       AppListEnableSource enable_source) {
   SetProfilePath(initial_profile->GetPath());
   if (local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled))
     return;
 
   local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true);
   CreateShortcut();
+
+  // UMA for launcher discoverability.
+  local_state_->SetInt64(prefs::kAppListEnableTime,
+                         base::Time::Now().ToInternalValue());
+  local_state_->SetInteger(prefs::kAppListEnableMethod, enable_source);
+  if (base::MessageLoop::current()) {
+    // Ensure a value is recorded if the user "never" shows the app list. Note
+    // there is no message loop in unit tests.
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&RecordAppListDiscoverability,
+                   base::Unretained(local_state_),
+                   false),
+        base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes));
+  }
+
   AppShortcutManager* shortcut_manager =
       AppShortcutManagerFactory::GetForProfile(initial_profile);
   if (shortcut_manager)
@@ -272,15 +359,20 @@ void AppListServiceImpl::InvalidatePendingProfileLoads() {
   profile_loader_->InvalidatePendingProfileLoads();
 }
 
-void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) {
+void AppListServiceImpl::PerformStartupChecks(Profile* initial_profile) {
+  // Except in rare, once-off cases, this just checks that a pref is "0" and
+  // returns.
+  RecordAppListDiscoverability(local_state_, true);
+
   if (command_line_.HasSwitch(switches::kResetAppListInstallState))
     local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false);
 
   if (command_line_.HasSwitch(switches::kEnableAppList))
-    EnableAppList(initial_profile);
-}
+    EnableAppList(initial_profile, ENABLE_VIA_COMMAND_LINE);
+
+  if (!base::MessageLoop::current())
+    return;  // In a unit test.
 
-void AppListServiceImpl::SendUsageStats() {
   // Send app list usage stats after a delay.
   const int kSendUsageStatsDelay = 5;
   base::MessageLoop::current()->PostDelayedTask(