1 // Copyright (c) 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/metrics/chrome_browser_main_extra_parts_metrics.h" 6 7 #include <string> 8 9 #include "base/bind.h" 10 #include "base/command_line.h" 11 #include "base/cpu.h" 12 #include "base/metrics/histogram.h" 13 #include "base/metrics/sparse_histogram.h" 14 #include "base/sys_info.h" 15 #include "base/threading/sequenced_worker_pool.h" 16 #include "base/time/time.h" 17 #include "chrome/browser/about_flags.h" 18 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/chrome_browser_main.h" 20 #include "chrome/browser/mac/bluetooth_utility.h" 21 #include "chrome/browser/pref_service_flags_storage.h" 22 #include "chrome/browser/shell_integration.h" 23 #include "content/public/browser/browser_thread.h" 24 #include "ui/base/touch/touch_device.h" 25 #include "ui/base/ui_base_switches.h" 26 #include "ui/events/event_switches.h" 27 28 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 29 #include <gnu/libc-version.h> 30 31 #include "base/version.h" 32 #if defined(USE_X11) 33 #include "ui/base/x/x11_util.h" 34 #endif 35 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) 36 37 #if defined(OS_WIN) 38 #include "chrome/installer/util/google_update_settings.h" 39 #endif // defined(OS_WIN) 40 41 namespace { 42 43 enum UMALinuxGlibcVersion { 44 UMA_LINUX_GLIBC_NOT_PARSEABLE, 45 UMA_LINUX_GLIBC_UNKNOWN, 46 UMA_LINUX_GLIBC_2_11, 47 UMA_LINUX_GLIBC_2_19 = UMA_LINUX_GLIBC_2_11 + 8, 48 // NOTE: Add new version above this line and update the enum list in 49 // tools/metrics/histograms/histograms.xml accordingly. 50 UMA_LINUX_GLIBC_VERSION_COUNT 51 }; 52 53 enum UMALinuxWindowManager { 54 UMA_LINUX_WINDOW_MANAGER_OTHER, 55 UMA_LINUX_WINDOW_MANAGER_BLACKBOX, 56 UMA_LINUX_WINDOW_MANAGER_CHROME_OS, // Deprecated. 57 UMA_LINUX_WINDOW_MANAGER_COMPIZ, 58 UMA_LINUX_WINDOW_MANAGER_ENLIGHTENMENT, 59 UMA_LINUX_WINDOW_MANAGER_ICE_WM, 60 UMA_LINUX_WINDOW_MANAGER_KWIN, 61 UMA_LINUX_WINDOW_MANAGER_METACITY, 62 UMA_LINUX_WINDOW_MANAGER_MUFFIN, 63 UMA_LINUX_WINDOW_MANAGER_MUTTER, 64 UMA_LINUX_WINDOW_MANAGER_OPENBOX, 65 UMA_LINUX_WINDOW_MANAGER_XFWM4, 66 UMA_LINUX_WINDOW_MANAGER_AWESOME, 67 UMA_LINUX_WINDOW_MANAGER_I3, 68 UMA_LINUX_WINDOW_MANAGER_ION3, 69 UMA_LINUX_WINDOW_MANAGER_MATCHBOX, 70 UMA_LINUX_WINDOW_MANAGER_NOTION, 71 UMA_LINUX_WINDOW_MANAGER_QTILE, 72 UMA_LINUX_WINDOW_MANAGER_RATPOISON, 73 UMA_LINUX_WINDOW_MANAGER_STUMPWM, 74 // NOTE: Append new window managers to the list above this line (i.e. don't 75 // renumber) and update LinuxWindowManagerName in 76 // tools/metrics/histograms/histograms.xml accordingly. 77 UMA_LINUX_WINDOW_MANAGER_COUNT 78 }; 79 80 enum UMATouchEventsState { 81 UMA_TOUCH_EVENTS_ENABLED, 82 UMA_TOUCH_EVENTS_AUTO_ENABLED, 83 UMA_TOUCH_EVENTS_AUTO_DISABLED, 84 UMA_TOUCH_EVENTS_DISABLED, 85 // NOTE: Add states only immediately above this line. Make sure to 86 // update the enum list in tools/metrics/histograms/histograms.xml 87 // accordingly. 88 UMA_TOUCH_EVENTS_STATE_COUNT 89 }; 90 91 void RecordMicroArchitectureStats() { 92 #if defined(ARCH_CPU_X86_FAMILY) 93 base::CPU cpu; 94 base::CPU::IntelMicroArchitecture arch = cpu.GetIntelMicroArchitecture(); 95 UMA_HISTOGRAM_ENUMERATION("Platform.IntelMaxMicroArchitecture", arch, 96 base::CPU::MAX_INTEL_MICRO_ARCHITECTURE); 97 #endif // defined(ARCH_CPU_X86_FAMILY) 98 UMA_HISTOGRAM_SPARSE_SLOWLY("Platform.LogicalCpuCount", 99 base::SysInfo::NumberOfProcessors()); 100 } 101 102 // Called on the blocking pool some time after startup to avoid slowing down 103 // startup with metrics that aren't trivial to compute. 104 void RecordStartupMetricsOnBlockingPool() { 105 #if defined(OS_WIN) 106 GoogleUpdateSettings::RecordChromeUpdatePolicyHistograms(); 107 #endif // defined(OS_WIN) 108 109 #if defined(OS_MACOSX) && !defined(OS_IOS) 110 bluetooth_utility::BluetoothAvailability availability = 111 bluetooth_utility::GetBluetoothAvailability(); 112 UMA_HISTOGRAM_ENUMERATION("OSX.BluetoothAvailability", 113 availability, 114 bluetooth_utility::BLUETOOTH_AVAILABILITY_COUNT); 115 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 116 } 117 118 void RecordLinuxGlibcVersion() { 119 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 120 Version version(gnu_get_libc_version()); 121 122 UMALinuxGlibcVersion glibc_version_result = UMA_LINUX_GLIBC_NOT_PARSEABLE; 123 if (version.IsValid() && version.components().size() == 2) { 124 glibc_version_result = UMA_LINUX_GLIBC_UNKNOWN; 125 int glibc_major_version = version.components()[0]; 126 int glibc_minor_version = version.components()[1]; 127 if (glibc_major_version == 2) { 128 // A constant to translate glibc 2.x minor versions to their 129 // equivalent UMALinuxGlibcVersion values. 130 const int kGlibcMinorVersionTranslationOffset = 11 - UMA_LINUX_GLIBC_2_11; 131 int translated_glibc_minor_version = 132 glibc_minor_version - kGlibcMinorVersionTranslationOffset; 133 if (translated_glibc_minor_version >= UMA_LINUX_GLIBC_2_11 && 134 translated_glibc_minor_version <= UMA_LINUX_GLIBC_2_19) { 135 glibc_version_result = 136 static_cast<UMALinuxGlibcVersion>(translated_glibc_minor_version); 137 } 138 } 139 } 140 UMA_HISTOGRAM_ENUMERATION("Linux.GlibcVersion", glibc_version_result, 141 UMA_LINUX_GLIBC_VERSION_COUNT); 142 #endif 143 } 144 145 #if defined(USE_X11) && !defined(OS_CHROMEOS) 146 UMALinuxWindowManager GetLinuxWindowManager() { 147 switch (ui::GuessWindowManager()) { 148 case ui::WM_UNKNOWN: 149 return UMA_LINUX_WINDOW_MANAGER_OTHER; 150 case ui::WM_AWESOME: 151 return UMA_LINUX_WINDOW_MANAGER_AWESOME; 152 case ui::WM_BLACKBOX: 153 return UMA_LINUX_WINDOW_MANAGER_BLACKBOX; 154 case ui::WM_COMPIZ: 155 return UMA_LINUX_WINDOW_MANAGER_COMPIZ; 156 case ui::WM_ENLIGHTENMENT: 157 return UMA_LINUX_WINDOW_MANAGER_ENLIGHTENMENT; 158 case ui::WM_I3: 159 return UMA_LINUX_WINDOW_MANAGER_I3; 160 case ui::WM_ICE_WM: 161 return UMA_LINUX_WINDOW_MANAGER_ICE_WM; 162 case ui::WM_ION3: 163 return UMA_LINUX_WINDOW_MANAGER_ION3; 164 case ui::WM_KWIN: 165 return UMA_LINUX_WINDOW_MANAGER_KWIN; 166 case ui::WM_MATCHBOX: 167 return UMA_LINUX_WINDOW_MANAGER_MATCHBOX; 168 case ui::WM_METACITY: 169 return UMA_LINUX_WINDOW_MANAGER_METACITY; 170 case ui::WM_MUFFIN: 171 return UMA_LINUX_WINDOW_MANAGER_MUFFIN; 172 case ui::WM_MUTTER: 173 return UMA_LINUX_WINDOW_MANAGER_MUTTER; 174 case ui::WM_NOTION: 175 return UMA_LINUX_WINDOW_MANAGER_NOTION; 176 case ui::WM_OPENBOX: 177 return UMA_LINUX_WINDOW_MANAGER_OPENBOX; 178 case ui::WM_QTILE: 179 return UMA_LINUX_WINDOW_MANAGER_QTILE; 180 case ui::WM_RATPOISON: 181 return UMA_LINUX_WINDOW_MANAGER_RATPOISON; 182 case ui::WM_STUMPWM: 183 return UMA_LINUX_WINDOW_MANAGER_STUMPWM; 184 case ui::WM_XFWM4: 185 return UMA_LINUX_WINDOW_MANAGER_XFWM4; 186 } 187 return UMA_LINUX_WINDOW_MANAGER_OTHER; 188 } 189 #endif 190 191 void RecordTouchEventState() { 192 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 193 const std::string touch_enabled_switch = 194 command_line.HasSwitch(switches::kTouchEvents) ? 195 command_line.GetSwitchValueASCII(switches::kTouchEvents) : 196 switches::kTouchEventsAuto; 197 198 UMATouchEventsState state; 199 if (touch_enabled_switch.empty() || 200 touch_enabled_switch == switches::kTouchEventsEnabled) { 201 state = UMA_TOUCH_EVENTS_ENABLED; 202 } else if (touch_enabled_switch == switches::kTouchEventsAuto) { 203 state = ui::IsTouchDevicePresent() ? 204 UMA_TOUCH_EVENTS_AUTO_ENABLED : UMA_TOUCH_EVENTS_AUTO_DISABLED; 205 } else if (touch_enabled_switch == switches::kTouchEventsDisabled) { 206 state = UMA_TOUCH_EVENTS_DISABLED; 207 } else { 208 NOTREACHED(); 209 return; 210 } 211 212 UMA_HISTOGRAM_ENUMERATION("Touchscreen.TouchEventsEnabled", state, 213 UMA_TOUCH_EVENTS_STATE_COUNT); 214 } 215 216 } // namespace 217 218 ChromeBrowserMainExtraPartsMetrics::ChromeBrowserMainExtraPartsMetrics() { 219 } 220 221 ChromeBrowserMainExtraPartsMetrics::~ChromeBrowserMainExtraPartsMetrics() { 222 } 223 224 void ChromeBrowserMainExtraPartsMetrics::PreProfileInit() { 225 RecordMicroArchitectureStats(); 226 } 227 228 void ChromeBrowserMainExtraPartsMetrics::PreBrowserStart() { 229 about_flags::PrefServiceFlagsStorage flags_storage_( 230 g_browser_process->local_state()); 231 about_flags::RecordUMAStatistics(&flags_storage_); 232 } 233 234 void ChromeBrowserMainExtraPartsMetrics::PostBrowserStart() { 235 RecordLinuxGlibcVersion(); 236 #if defined(USE_X11) && !defined(OS_CHROMEOS) 237 UMA_HISTOGRAM_ENUMERATION("Linux.WindowManager", 238 GetLinuxWindowManager(), 239 UMA_LINUX_WINDOW_MANAGER_COUNT); 240 #endif 241 RecordTouchEventState(); 242 243 const int kStartupMetricsGatheringDelaySeconds = 45; 244 content::BrowserThread::GetBlockingPool()->PostDelayedTask( 245 FROM_HERE, 246 base::Bind(&RecordStartupMetricsOnBlockingPool), 247 base::TimeDelta::FromSeconds(kStartupMetricsGatheringDelaySeconds)); 248 } 249 250 namespace chrome { 251 252 void AddMetricsExtraParts(ChromeBrowserMainParts* main_parts) { 253 main_parts->AddParts(new ChromeBrowserMainExtraPartsMetrics()); 254 } 255 256 } // namespace chrome 257