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/threading/sequenced_worker_pool.h" 14#include "base/time/time.h" 15#include "chrome/browser/about_flags.h" 16#include "chrome/browser/browser_process.h" 17#include "chrome/browser/chrome_browser_main.h" 18#include "chrome/browser/pref_service_flags_storage.h" 19#include "chrome/browser/shell_integration.h" 20#include "content/public/browser/browser_thread.h" 21#include "ui/base/touch/touch_device.h" 22#include "ui/base/ui_base_switches.h" 23 24#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 25#include <gnu/libc-version.h> 26 27#include "base/version.h" 28#endif 29 30namespace { 31 32enum UMALinuxGlibcVersion { 33 UMA_LINUX_GLIBC_NOT_PARSEABLE, 34 UMA_LINUX_GLIBC_UNKNOWN, 35 UMA_LINUX_GLIBC_2_11, 36 UMA_LINUX_GLIBC_2_19 = UMA_LINUX_GLIBC_2_11 + 8, 37 // NOTE: Add new version above this line and update the enum list in 38 // tools/histograms/histograms.xml accordingly. 39 UMA_LINUX_GLIBC_VERSION_COUNT 40}; 41 42enum UMATouchEventsState { 43 UMA_TOUCH_EVENTS_ENABLED, 44 UMA_TOUCH_EVENTS_AUTO_ENABLED, 45 UMA_TOUCH_EVENTS_AUTO_DISABLED, 46 UMA_TOUCH_EVENTS_DISABLED, 47 // NOTE: Add states only immediately above this line. Make sure to 48 // update the enum list in tools/histograms/histograms.xml accordingly. 49 UMA_TOUCH_EVENTS_STATE_COUNT 50}; 51 52void RecordIntelMicroArchitecture() { 53#if defined(ARCH_CPU_X86_FAMILY) 54 base::CPU cpu; 55 base::CPU::IntelMicroArchitecture arch = cpu.GetIntelMicroArchitecture(); 56 UMA_HISTOGRAM_ENUMERATION("Platform.IntelMaxMicroArchitecture", arch, 57 base::CPU::MAX_INTEL_MICRO_ARCHITECTURE); 58#endif // defined(ARCH_CPU_X86_FAMILY) 59} 60 61void RecordDefaultBrowserUMAStat() { 62 // Record whether Chrome is the default browser or not. 63 ShellIntegration::DefaultWebClientState default_state = 64 ShellIntegration::GetDefaultBrowser(); 65 UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.State", default_state, 66 ShellIntegration::NUM_DEFAULT_STATES); 67} 68 69void RecordLinuxGlibcVersion() { 70#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 71 Version version(gnu_get_libc_version()); 72 73 UMALinuxGlibcVersion glibc_version_result = UMA_LINUX_GLIBC_NOT_PARSEABLE; 74 if (version.IsValid() && version.components().size() == 2) { 75 glibc_version_result = UMA_LINUX_GLIBC_UNKNOWN; 76 int glibc_major_version = version.components()[0]; 77 int glibc_minor_version = version.components()[1]; 78 if (glibc_major_version == 2) { 79 // A constant to translate glibc 2.x minor versions to their 80 // equivalent UMALinuxGlibcVersion values. 81 const int kGlibcMinorVersionTranslationOffset = 11 - UMA_LINUX_GLIBC_2_11; 82 int translated_glibc_minor_version = 83 glibc_minor_version - kGlibcMinorVersionTranslationOffset; 84 if (translated_glibc_minor_version >= UMA_LINUX_GLIBC_2_11 && 85 translated_glibc_minor_version <= UMA_LINUX_GLIBC_2_19) { 86 glibc_version_result = 87 static_cast<UMALinuxGlibcVersion>(translated_glibc_minor_version); 88 } 89 } 90 } 91 UMA_HISTOGRAM_ENUMERATION("Linux.GlibcVersion", glibc_version_result, 92 UMA_LINUX_GLIBC_VERSION_COUNT); 93#endif 94} 95 96void RecordTouchEventState() { 97 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 98 const std::string touch_enabled_switch = 99 command_line.HasSwitch(switches::kTouchEvents) ? 100 command_line.GetSwitchValueASCII(switches::kTouchEvents) : 101 switches::kTouchEventsAuto; 102 103 UMATouchEventsState state; 104 if (touch_enabled_switch.empty() || 105 touch_enabled_switch == switches::kTouchEventsEnabled) { 106 state = UMA_TOUCH_EVENTS_ENABLED; 107 } else if (touch_enabled_switch == switches::kTouchEventsAuto) { 108 state = ui::IsTouchDevicePresent() ? 109 UMA_TOUCH_EVENTS_AUTO_ENABLED : UMA_TOUCH_EVENTS_AUTO_DISABLED; 110 } else if (touch_enabled_switch == switches::kTouchEventsDisabled) { 111 state = UMA_TOUCH_EVENTS_DISABLED; 112 } else { 113 NOTREACHED(); 114 return; 115 } 116 117 UMA_HISTOGRAM_ENUMERATION("Touchscreen.TouchEventsEnabled", state, 118 UMA_TOUCH_EVENTS_STATE_COUNT); 119} 120 121} // namespace 122 123ChromeBrowserMainExtraPartsMetrics::ChromeBrowserMainExtraPartsMetrics() { 124} 125 126ChromeBrowserMainExtraPartsMetrics::~ChromeBrowserMainExtraPartsMetrics() { 127} 128 129void ChromeBrowserMainExtraPartsMetrics::PreProfileInit() { 130 RecordIntelMicroArchitecture(); 131} 132 133void ChromeBrowserMainExtraPartsMetrics::PreBrowserStart() { 134 about_flags::PrefServiceFlagsStorage flags_storage_( 135 g_browser_process->local_state()); 136 about_flags::RecordUMAStatistics(&flags_storage_); 137 138 // Querying the default browser state can be slow, do it in the background. 139 content::BrowserThread::GetBlockingPool()->PostDelayedTask( 140 FROM_HERE, 141 base::Bind(&RecordDefaultBrowserUMAStat), 142 base::TimeDelta::FromSeconds(45)); 143} 144 145void ChromeBrowserMainExtraPartsMetrics::PostBrowserStart() { 146 RecordLinuxGlibcVersion(); 147 RecordTouchEventState(); 148} 149 150namespace chrome { 151 152void AddMetricsExtraParts(ChromeBrowserMainParts* main_parts) { 153 main_parts->AddParts(new ChromeBrowserMainExtraPartsMetrics()); 154} 155 156} // namespace chrome 157