File: app_list_service.cc

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (173 lines) | stat: -rw-r--r-- 6,515 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/app_list/app_list_service.h"

#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"

namespace {

enum StartupType {
  COLD_START,
  WARM_START,
  WARM_START_FAST,
};

// For when an app list show request is received via CommandLine. Indicates
// whether the Profile the app list was previously showing was the SAME, OTHER
// or NONE with respect to the new Profile to show.
enum ProfileLoadState {
  PROFILE_LOADED_SAME,
  PROFILE_LOADED_OTHER,
  PROFILE_LOADED_NONE,
};

base::Time GetOriginalProcessStartTime(const base::CommandLine& command_line) {
  if (command_line.HasSwitch(switches::kOriginalProcessStartTime)) {
    std::string start_time_string =
        command_line.GetSwitchValueASCII(switches::kOriginalProcessStartTime);
    int64 remote_start_time;
    base::StringToInt64(start_time_string, &remote_start_time);
    return base::Time::FromInternalValue(remote_start_time);
  }

// base::CurrentProcessInfo::CreationTime() is only defined on some
// platforms.
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
  return base::CurrentProcessInfo::CreationTime();
#else
  return base::Time();
#endif
}

StartupType GetStartupType(const base::CommandLine& command_line) {
  // The presence of kOriginalProcessStartTime implies that another process
  // has sent us its command line to handle, ie: we are already running.
  if (command_line.HasSwitch(switches::kOriginalProcessStartTime)) {
    return command_line.HasSwitch(switches::kFastStart) ?
        WARM_START_FAST : WARM_START;
  }
  return COLD_START;
}

// The time the process that caused the app list to be shown started. This isn't
// necessarily the currently executing process as we may be processing a command
// line given to a short-lived Chrome instance.
int64 g_original_process_start_time;

// The type of startup the the current app list show has gone through.
StartupType g_app_show_startup_type;

// The state of the active app list profile at the most recent launch.
ProfileLoadState g_profile_load_state;

void RecordFirstPaintTiming() {
  base::Time start_time(
      base::Time::FromInternalValue(g_original_process_start_time));
  base::TimeDelta elapsed = base::Time::Now() - start_time;
  switch (g_app_show_startup_type) {
    case COLD_START:
      DCHECK_EQ(PROFILE_LOADED_NONE, g_profile_load_state);
      UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintColdStart", elapsed);
      break;
    case WARM_START:
      // For warm starts, only record showing the same profile. "NONE" should
      // only occur in the first 30 seconds after startup. "OTHER" only occurs
      // for multi-profile cases. In these cases, timings are also affected by
      // whether or not a profile has been loaded from disk, which makes the
      // profile load asynchronous and skews results unpredictably.
      if (g_profile_load_state == PROFILE_LOADED_SAME)
        UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintWarmStart", elapsed);
      break;
    case WARM_START_FAST:
      if (g_profile_load_state == PROFILE_LOADED_SAME) {
        UMA_HISTOGRAM_LONG_TIMES("Startup.AppListFirstPaintWarmStartFast",
                                 elapsed);
      }
      break;
  }
}

void RecordStartupInfo(AppListService* service,
                       const base::CommandLine& command_line,
                       Profile* launch_profile) {
  base::Time start_time = GetOriginalProcessStartTime(command_line);
  if (start_time.is_null())
    return;

  base::TimeDelta elapsed = base::Time::Now() - start_time;
  StartupType startup_type = GetStartupType(command_line);
  switch (startup_type) {
    case COLD_START:
      UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListColdStart", elapsed);
      break;
    case WARM_START:
      UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListWarmStart", elapsed);
      break;
    case WARM_START_FAST:
      UMA_HISTOGRAM_LONG_TIMES("Startup.ShowAppListWarmStartFast", elapsed);
      break;
  }

  g_original_process_start_time = start_time.ToInternalValue();
  g_app_show_startup_type = startup_type;

  Profile* current_profile = service->GetCurrentAppListProfile();
  if (!current_profile)
    g_profile_load_state = PROFILE_LOADED_NONE;
  else if (current_profile == launch_profile)
    g_profile_load_state = PROFILE_LOADED_SAME;
  else
    g_profile_load_state = PROFILE_LOADED_OTHER;

  service->SetAppListNextPaintCallback(RecordFirstPaintTiming);
}

}  // namespace

// static
void AppListService::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterInt64Pref(prefs::kLastAppListLaunchPing, 0);
  registry->RegisterIntegerPref(prefs::kAppListLaunchCount, 0);
  registry->RegisterInt64Pref(prefs::kLastAppListAppLaunchPing, 0);
  registry->RegisterIntegerPref(prefs::kAppListAppLaunchCount, 0);
  registry->RegisterStringPref(prefs::kAppListProfile, std::string());
  registry->RegisterBooleanPref(prefs::kAppLauncherIsEnabled, false);
  registry->RegisterBooleanPref(prefs::kAppLauncherHasBeenEnabled, false);
  registry->RegisterIntegerPref(prefs::kAppListEnableMethod,
                                ENABLE_NOT_RECORDED);
  registry->RegisterInt64Pref(prefs::kAppListEnableTime, 0);

#if defined(OS_MACOSX)
  registry->RegisterIntegerPref(prefs::kAppLauncherShortcutVersion, 0);
#endif

  // Identifies whether we should show the app launcher promo or not.
  // Note that a field trial also controls the showing, so the promo won't show
  // unless the pref is set AND the field trial is set to a proper group.
  registry->RegisterBooleanPref(prefs::kShowAppLauncherPromo, false);
}

// static
bool AppListService::HandleLaunchCommandLine(
    const base::CommandLine& command_line,
    Profile* launch_profile) {
  InitAll(launch_profile);
  if (!command_line.HasSwitch(switches::kShowAppList))
    return false;

  // The --show-app-list switch is used for shortcuts on the native desktop.
  AppListService* service = Get(chrome::HOST_DESKTOP_TYPE_NATIVE);
  DCHECK(service);
  RecordStartupInfo(service, command_line, launch_profile);
  service->ShowForProfile(launch_profile);
  return true;
}