app_list_service.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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.h" 6 7#include "base/command_line.h" 8#include "base/metrics/histogram.h" 9#include "base/prefs/pref_registry_simple.h" 10#include "base/process/process_info.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/time/time.h" 13#include "chrome/common/chrome_switches.h" 14#include "chrome/common/pref_names.h" 15 16namespace { 17 18enum StartupType { 19 COLD_START, 20 WARM_START, 21 WARM_START_FAST, 22}; 23 24// For when an app list show request is received via CommandLine. Indicates 25// whether the Profile the app list was previously showing was the SAME, OTHER 26// or NONE with respect to the new Profile to show. 27enum ProfileLoadState { 28 PROFILE_LOADED_SAME, 29 PROFILE_LOADED_OTHER, 30 PROFILE_LOADED_NONE, 31}; 32 33base::Time GetOriginalProcessStartTime(const CommandLine& command_line) { 34 if (command_line.HasSwitch(switches::kOriginalProcessStartTime)) { 35 std::string start_time_string = 36 command_line.GetSwitchValueASCII(switches::kOriginalProcessStartTime); 37 int64 remote_start_time; 38 base::StringToInt64(start_time_string, &remote_start_time); 39 return base::Time::FromInternalValue(remote_start_time); 40 } 41 42// base::CurrentProcessInfo::CreationTime() is only defined on some 43// platforms. 44#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) 45 return base::CurrentProcessInfo::CreationTime(); 46#else 47 return base::Time(); 48#endif 49} 50 51StartupType GetStartupType(const CommandLine& command_line) { 52 // The presence of kOriginalProcessStartTime implies that another process 53 // has sent us its command line to handle, ie: we are already running. 54 if (command_line.HasSwitch(switches::kOriginalProcessStartTime)) { 55 return command_line.HasSwitch(switches::kFastStart) ? 56 WARM_START_FAST : WARM_START; 57 } 58 return COLD_START; 59} 60 61// The time the process that caused the app list to be shown started. This isn't 62// necessarily the currently executing process as we may be processing a command 63// line given to a short-lived Chrome instance. 64int64 g_original_process_start_time; 65 66// The type of startup the the current app list show has gone through. 67StartupType g_app_show_startup_type; 68 69// The state of the active app list profile at the most recent launch. 70ProfileLoadState g_profile_load_state; 71 72void RecordFirstPaintTiming() { 73 base::Time start_time( 74 base::Time::FromInternalValue(g_original_process_start_time)); 75 base::TimeDelta elapsed = base::Time::Now() - start_time; 76 switch (g_app_show_startup_type) { 77 case COLD_START: 78 DCHECK_EQ(PROFILE_LOADED_NONE, g_profile_load_state); 79 UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintColdStart", elapsed); 80 break; 81 case WARM_START: 82 // For warm starts, only record showing the same profile. "NONE" should 83 // only occur in the first 30 seconds after startup. "OTHER" only occurs 84 // for multi-profile cases. In these cases, timings are also affected by 85 // whether or not a profile has been loaded from disk, which makes the 86 // profile load asynchronous and skews results unpredictably. 87 if (g_profile_load_state == PROFILE_LOADED_SAME) 88 UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintWarmStart", elapsed); 89 break; 90 case WARM_START_FAST: 91 if (g_profile_load_state == PROFILE_LOADED_SAME) { 92 UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintWarmStartFast", 93 elapsed); 94 } 95 break; 96 } 97} 98 99void RecordStartupInfo(AppListService* service, 100 const CommandLine& command_line, 101 Profile* launch_profile) { 102 base::Time start_time = GetOriginalProcessStartTime(command_line); 103 if (start_time.is_null()) 104 return; 105 106 base::TimeDelta elapsed = base::Time::Now() - start_time; 107 StartupType startup_type = GetStartupType(command_line); 108 switch (startup_type) { 109 case COLD_START: 110 UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListColdStart", elapsed); 111 break; 112 case WARM_START: 113 UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListWarmStart", elapsed); 114 break; 115 case WARM_START_FAST: 116 UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListWarmStartFast", elapsed); 117 break; 118 } 119 120 g_original_process_start_time = start_time.ToInternalValue(); 121 g_app_show_startup_type = startup_type; 122 123 Profile* current_profile = service->GetCurrentAppListProfile(); 124 if (!current_profile) 125 g_profile_load_state = PROFILE_LOADED_NONE; 126 else if (current_profile == launch_profile) 127 g_profile_load_state = PROFILE_LOADED_SAME; 128 else 129 g_profile_load_state = PROFILE_LOADED_OTHER; 130 131 service->SetAppListNextPaintCallback(RecordFirstPaintTiming); 132} 133 134} // namespace 135 136// static 137void AppListService::RegisterPrefs(PrefRegistrySimple* registry) { 138 registry->RegisterInt64Pref(prefs::kLastAppListLaunchPing, 0); 139 registry->RegisterIntegerPref(prefs::kAppListLaunchCount, 0); 140 registry->RegisterInt64Pref(prefs::kLastAppListAppLaunchPing, 0); 141 registry->RegisterIntegerPref(prefs::kAppListAppLaunchCount, 0); 142 registry->RegisterStringPref(prefs::kAppListProfile, std::string()); 143 registry->RegisterBooleanPref(prefs::kAppLauncherIsEnabled, false); 144 registry->RegisterBooleanPref(prefs::kAppLauncherHasBeenEnabled, false); 145 registry->RegisterIntegerPref(prefs::kAppListEnableMethod, 146 ENABLE_NOT_RECORDED); 147 registry->RegisterInt64Pref(prefs::kAppListEnableTime, 0); 148 149#if defined(OS_MACOSX) 150 registry->RegisterIntegerPref(prefs::kAppLauncherShortcutVersion, 0); 151#endif 152 153 // Identifies whether we should show the app launcher promo or not. 154 // Note that a field trial also controls the showing, so the promo won't show 155 // unless the pref is set AND the field trial is set to a proper group. 156 registry->RegisterBooleanPref(prefs::kShowAppLauncherPromo, true); 157} 158 159// static 160bool AppListService::HandleLaunchCommandLine( 161 const base::CommandLine& command_line, 162 Profile* launch_profile) { 163 InitAll(launch_profile); 164 if (!command_line.HasSwitch(switches::kShowAppList)) 165 return false; 166 167 // The --show-app-list switch is used for shortcuts on the native desktop. 168 AppListService* service = Get(chrome::HOST_DESKTOP_TYPE_NATIVE); 169 DCHECK(service); 170 RecordStartupInfo(service, command_line, launch_profile); 171 service->ShowForProfile(launch_profile); 172 return true; 173} 174