[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 1 | // Copyright 2014 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 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 5 | #include "chrome/browser/metrics/chromeos_metrics_provider.h" |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 6 | |
avi | 6846aef | 2015-12-26 01:09:38 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | |
Steven Holte | 915c99f | 2017-07-21 23:34:31 | [diff] [blame] | 9 | #include "base/barrier_closure.h" |
sque | 82e4d155 | 2016-02-26 22:47:19 | [diff] [blame] | 10 | #include "base/feature_list.h" |
asvitkine | 776f9db | 2017-01-25 21:39:29 | [diff] [blame] | 11 | #include "base/metrics/histogram_macros.h" |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 12 | #include "base/strings/string_number_conversions.h" |
| 13 | #include "base/strings/string_util.h" |
| 14 | #include "base/strings/utf_string_conversions.h" |
isherman | 904f82f | 2017-06-30 18:36:29 | [diff] [blame] | 15 | #include "base/task_scheduler/post_task.h" |
| 16 | #include "base/task_scheduler/task_traits.h" |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 17 | #include "chrome/browser/browser_process.h" |
hidehiko | 5d94408 | 2016-11-18 06:16:04 | [diff] [blame] | 18 | #include "chrome/browser/chromeos/arc/arc_session_manager.h" |
kaznacheev | 9ec1251 | 2015-03-11 21:49:37 | [diff] [blame] | 19 | #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
sque | 82e4d155 | 2016-02-26 22:47:19 | [diff] [blame] | 20 | #include "chrome/common/chrome_features.h" |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 21 | #include "chrome/common/pref_names.h" |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 22 | #include "chromeos/system/statistics_provider.h" |
sque | 82e4d155 | 2016-02-26 22:47:19 | [diff] [blame] | 23 | #include "components/metrics/leak_detector/leak_detector.h" |
[email protected] | d6147bd | 2014-06-11 01:58:19 | [diff] [blame] | 24 | #include "components/metrics/metrics_service.h" |
brettw | b1fc1b8 | 2016-02-02 00:19:08 | [diff] [blame] | 25 | #include "components/prefs/pref_registry_simple.h" |
| 26 | #include "components/prefs/pref_service.h" |
[email protected] | 4d39078 | 2014-08-15 09:22:58 | [diff] [blame] | 27 | #include "components/user_manager/user_manager.h" |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 28 | #include "device/bluetooth/bluetooth_adapter.h" |
| 29 | #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 30 | #include "device/bluetooth/bluetooth_device.h" |
Steven Holte | f9d5ed6 | 2017-10-21 02:02:30 | [diff] [blame^] | 31 | #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 32 | #include "ui/display/display.h" |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 33 | #include "ui/events/event_utils.h" |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 34 | |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 35 | using metrics::ChromeUserMetricsExtension; |
[email protected] | dbd4e609 | 2014-05-31 01:04:21 | [diff] [blame] | 36 | using metrics::SampledProfile; |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 37 | using metrics::SystemProfileProto; |
| 38 | typedef SystemProfileProto::Hardware::Bluetooth::PairedDevice PairedDevice; |
| 39 | |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 40 | namespace { |
| 41 | |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 42 | PairedDevice::Type AsBluetoothDeviceType( |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 43 | device::BluetoothDeviceType device_type) { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 44 | switch (device_type) { |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 45 | case device::BluetoothDeviceType::UNKNOWN: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 46 | return PairedDevice::DEVICE_UNKNOWN; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 47 | case device::BluetoothDeviceType::COMPUTER: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 48 | return PairedDevice::DEVICE_COMPUTER; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 49 | case device::BluetoothDeviceType::PHONE: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 50 | return PairedDevice::DEVICE_PHONE; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 51 | case device::BluetoothDeviceType::MODEM: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 52 | return PairedDevice::DEVICE_MODEM; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 53 | case device::BluetoothDeviceType::AUDIO: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 54 | return PairedDevice::DEVICE_AUDIO; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 55 | case device::BluetoothDeviceType::CAR_AUDIO: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 56 | return PairedDevice::DEVICE_CAR_AUDIO; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 57 | case device::BluetoothDeviceType::VIDEO: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 58 | return PairedDevice::DEVICE_VIDEO; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 59 | case device::BluetoothDeviceType::PERIPHERAL: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 60 | return PairedDevice::DEVICE_PERIPHERAL; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 61 | case device::BluetoothDeviceType::JOYSTICK: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 62 | return PairedDevice::DEVICE_JOYSTICK; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 63 | case device::BluetoothDeviceType::GAMEPAD: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 64 | return PairedDevice::DEVICE_GAMEPAD; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 65 | case device::BluetoothDeviceType::KEYBOARD: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 66 | return PairedDevice::DEVICE_KEYBOARD; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 67 | case device::BluetoothDeviceType::MOUSE: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 68 | return PairedDevice::DEVICE_MOUSE; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 69 | case device::BluetoothDeviceType::TABLET: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 70 | return PairedDevice::DEVICE_TABLET; |
fukino | 6da34d6 | 2016-10-05 23:03:13 | [diff] [blame] | 71 | case device::BluetoothDeviceType::KEYBOARD_MOUSE_COMBO: |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 72 | return PairedDevice::DEVICE_KEYBOARD_MOUSE_COMBO; |
| 73 | } |
| 74 | |
| 75 | NOTREACHED(); |
| 76 | return PairedDevice::DEVICE_UNKNOWN; |
| 77 | } |
| 78 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 79 | void IncrementPrefValue(const char* path) { |
| 80 | PrefService* pref = g_browser_process->local_state(); |
| 81 | DCHECK(pref); |
| 82 | int value = pref->GetInteger(path); |
| 83 | pref->SetInteger(path, value + 1); |
| 84 | } |
| 85 | |
Steven Holte | b7f8139b | 2017-08-08 20:00:21 | [diff] [blame] | 86 | // Called on a background thread to load hardware class information. |
| 87 | std::string GetHardwareClassOnBackgroundThread() { |
Steven Holte | b7f8139b | 2017-08-08 20:00:21 | [diff] [blame] | 88 | std::string hardware_class; |
| 89 | chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic( |
| 90 | "hardware_class", &hardware_class); |
| 91 | return hardware_class; |
| 92 | } |
| 93 | |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 94 | } // namespace |
| 95 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 96 | ChromeOSMetricsProvider::ChromeOSMetricsProvider() |
| 97 | : registered_user_count_at_log_initialization_(false), |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 98 | user_count_at_log_initialization_(0), |
| 99 | weak_ptr_factory_(this) { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 100 | } |
| 101 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 102 | ChromeOSMetricsProvider::~ChromeOSMetricsProvider() { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 103 | } |
| 104 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 105 | // static |
| 106 | void ChromeOSMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) { |
| 107 | registry->RegisterIntegerPref(prefs::kStabilityOtherUserCrashCount, 0); |
| 108 | registry->RegisterIntegerPref(prefs::kStabilityKernelCrashCount, 0); |
| 109 | registry->RegisterIntegerPref(prefs::kStabilitySystemUncleanShutdownCount, 0); |
| 110 | } |
| 111 | |
| 112 | // static |
| 113 | void ChromeOSMetricsProvider::LogCrash(const std::string& crash_type) { |
| 114 | if (crash_type == "user") |
| 115 | IncrementPrefValue(prefs::kStabilityOtherUserCrashCount); |
| 116 | else if (crash_type == "kernel") |
| 117 | IncrementPrefValue(prefs::kStabilityKernelCrashCount); |
| 118 | else if (crash_type == "uncleanshutdown") |
| 119 | IncrementPrefValue(prefs::kStabilitySystemUncleanShutdownCount); |
| 120 | else |
| 121 | NOTREACHED() << "Unexpected Chrome OS crash type " << crash_type; |
| 122 | |
| 123 | // Wake up metrics logs sending if necessary now that new |
| 124 | // log data is available. |
| 125 | g_browser_process->metrics_service()->OnApplicationNotIdle(); |
| 126 | } |
| 127 | |
glevin | a7154d15 | 2015-11-04 14:28:43 | [diff] [blame] | 128 | ChromeOSMetricsProvider::EnrollmentStatus |
| 129 | ChromeOSMetricsProvider::GetEnrollmentStatus() { |
| 130 | policy::BrowserPolicyConnectorChromeOS* connector = |
| 131 | g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
| 132 | if (!connector) |
| 133 | return ERROR_GETTING_ENROLLMENT_STATUS; |
| 134 | |
| 135 | return connector->IsEnterpriseManaged() ? MANAGED : NON_MANAGED; |
| 136 | } |
| 137 | |
dhsharp | b0073a2 | 2016-02-18 21:54:09 | [diff] [blame] | 138 | void ChromeOSMetricsProvider::Init() { |
| 139 | perf_provider_.Init(); |
sque | 82e4d155 | 2016-02-26 22:47:19 | [diff] [blame] | 140 | |
sque | 961ce9c | 2016-04-21 04:42:55 | [diff] [blame] | 141 | #if defined(ARCH_CPU_X86_64) |
| 142 | // Currently, the runtime memory leak detector is only supported on x86_64 |
| 143 | // systems. |
sque | 82e4d155 | 2016-02-26 22:47:19 | [diff] [blame] | 144 | if (base::FeatureList::IsEnabled(features::kRuntimeMemoryLeakDetector)) { |
| 145 | leak_detector_controller_.reset(new metrics::LeakDetectorController); |
| 146 | } |
sque | 961ce9c | 2016-04-21 04:42:55 | [diff] [blame] | 147 | #endif |
dhsharp | b0073a2 | 2016-02-18 21:54:09 | [diff] [blame] | 148 | } |
| 149 | |
Steven Holte | 915c99f | 2017-07-21 23:34:31 | [diff] [blame] | 150 | void ChromeOSMetricsProvider::AsyncInit(const base::Closure& done_callback) { |
| 151 | base::Closure barrier = base::BarrierClosure(2, done_callback); |
| 152 | InitTaskGetHardwareClass(barrier); |
| 153 | InitTaskGetBluetoothAdapter(barrier); |
| 154 | } |
| 155 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 156 | void ChromeOSMetricsProvider::OnDidCreateMetricsLog() { |
| 157 | registered_user_count_at_log_initialization_ = false; |
[email protected] | 4d39078 | 2014-08-15 09:22:58 | [diff] [blame] | 158 | if (user_manager::UserManager::IsInitialized()) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 159 | registered_user_count_at_log_initialization_ = true; |
| 160 | user_count_at_log_initialization_ = |
[email protected] | 4d39078 | 2014-08-15 09:22:58 | [diff] [blame] | 161 | user_manager::UserManager::Get()->GetLoggedInUsers().size(); |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 162 | } |
| 163 | } |
| 164 | |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 165 | void ChromeOSMetricsProvider::InitTaskGetHardwareClass( |
| 166 | const base::Closure& callback) { |
isherman | 904f82f | 2017-06-30 18:36:29 | [diff] [blame] | 167 | // Run the (potentially expensive) task in the background to avoid blocking |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 168 | // the UI thread. |
Steven Holte | b7f8139b | 2017-08-08 20:00:21 | [diff] [blame] | 169 | base::PostTaskWithTraitsAndReplyWithResult( |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 170 | FROM_HERE, |
Ilya Sherman | f97af9d | 2017-07-20 20:16:23 | [diff] [blame] | 171 | {base::MayBlock(), base::WithBaseSyncPrimitives(), |
| 172 | base::TaskPriority::BACKGROUND, |
isherman | 904f82f | 2017-06-30 18:36:29 | [diff] [blame] | 173 | base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, |
Steven Holte | b7f8139b | 2017-08-08 20:00:21 | [diff] [blame] | 174 | base::BindOnce(&GetHardwareClassOnBackgroundThread), |
| 175 | base::BindOnce(&ChromeOSMetricsProvider::SetHardwareClass, |
| 176 | weak_ptr_factory_.GetWeakPtr(), callback)); |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 177 | } |
| 178 | |
ortuno | 4958ca4f | 2016-02-26 02:15:43 | [diff] [blame] | 179 | void ChromeOSMetricsProvider::InitTaskGetBluetoothAdapter( |
| 180 | const base::Closure& callback) { |
| 181 | device::BluetoothAdapterFactory::GetAdapter( |
| 182 | base::Bind(&ChromeOSMetricsProvider::SetBluetoothAdapter, |
| 183 | weak_ptr_factory_.GetWeakPtr(), callback)); |
| 184 | } |
| 185 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 186 | void ChromeOSMetricsProvider::ProvideSystemProfileMetrics( |
| 187 | metrics::SystemProfileProto* system_profile_proto) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 188 | WriteBluetoothProto(system_profile_proto); |
| 189 | UpdateMultiProfileUserCount(system_profile_proto); |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 190 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 191 | metrics::SystemProfileProto::Hardware* hardware = |
| 192 | system_profile_proto->mutable_hardware(); |
[email protected] | 51994b2 | 2014-05-30 13:24:21 | [diff] [blame] | 193 | hardware->set_hardware_class(hardware_class_); |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 194 | display::Display::TouchSupport has_touch = |
| 195 | ui::GetInternalDisplayTouchSupport(); |
| 196 | if (has_touch == display::Display::TOUCH_SUPPORT_AVAILABLE) |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 197 | hardware->set_internal_display_supports_touch(true); |
oshima | d5c972e | 2016-04-28 23:17:14 | [diff] [blame] | 198 | else if (has_touch == display::Display::TOUCH_SUPPORT_UNAVAILABLE) |
[email protected] | 8620392 | 2014-02-07 08:10:10 | [diff] [blame] | 199 | hardware->set_internal_display_supports_touch(false); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 200 | } |
| 201 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 202 | void ChromeOSMetricsProvider::ProvideStabilityMetrics( |
| 203 | metrics::SystemProfileProto* system_profile_proto) { |
| 204 | metrics::SystemProfileProto::Stability* stability_proto = |
| 205 | system_profile_proto->mutable_stability(); |
| 206 | PrefService* pref = g_browser_process->local_state(); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 207 | int count = pref->GetInteger(prefs::kStabilityOtherUserCrashCount); |
| 208 | if (count) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 209 | stability_proto->set_other_user_crash_count(count); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 210 | pref->SetInteger(prefs::kStabilityOtherUserCrashCount, 0); |
| 211 | } |
| 212 | |
| 213 | count = pref->GetInteger(prefs::kStabilityKernelCrashCount); |
| 214 | if (count) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 215 | stability_proto->set_kernel_crash_count(count); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 216 | pref->SetInteger(prefs::kStabilityKernelCrashCount, 0); |
| 217 | } |
| 218 | |
| 219 | count = pref->GetInteger(prefs::kStabilitySystemUncleanShutdownCount); |
| 220 | if (count) { |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 221 | stability_proto->set_unclean_system_shutdown_count(count); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 222 | pref->SetInteger(prefs::kStabilitySystemUncleanShutdownCount, 0); |
| 223 | } |
| 224 | } |
| 225 | |
Steven Holte | 141462ac | 2017-07-26 01:35:07 | [diff] [blame] | 226 | void ChromeOSMetricsProvider::ProvidePreviousSessionData( |
[email protected] | a00d413 | 2014-05-29 20:16:25 | [diff] [blame] | 227 | metrics::ChromeUserMetricsExtension* uma_proto) { |
Steven Holte | 141462ac | 2017-07-26 01:35:07 | [diff] [blame] | 228 | ProvideStabilityMetrics(uma_proto->mutable_system_profile()); |
Mark Pearson | 25a36bd | 2017-09-14 22:39:15 | [diff] [blame] | 229 | // The enrollment status and ARC state of a client are not likely to change |
| 230 | // between browser restarts. Hence, it's safe and useful to attach these |
| 231 | // values to a previous session log. |
| 232 | RecordEnrollmentStatus(); |
| 233 | RecordArcState(); |
Steven Holte | 141462ac | 2017-07-26 01:35:07 | [diff] [blame] | 234 | } |
| 235 | |
| 236 | void ChromeOSMetricsProvider::ProvideCurrentSessionData( |
| 237 | metrics::ChromeUserMetricsExtension* uma_proto) { |
| 238 | ProvideStabilityMetrics(uma_proto->mutable_system_profile()); |
[email protected] | dbd4e609 | 2014-05-31 01:04:21 | [diff] [blame] | 239 | std::vector<SampledProfile> sampled_profiles; |
| 240 | if (perf_provider_.GetSampledProfiles(&sampled_profiles)) { |
sque | ae77ab6 | 2016-04-20 07:54:01 | [diff] [blame] | 241 | for (auto& profile : sampled_profiles) { |
| 242 | uma_proto->add_sampled_profile()->Swap(&profile); |
[email protected] | a00d413 | 2014-05-29 20:16:25 | [diff] [blame] | 243 | } |
| 244 | } |
sque | ae77ab6 | 2016-04-20 07:54:01 | [diff] [blame] | 245 | |
| 246 | if (leak_detector_controller_) { |
| 247 | std::vector<metrics::MemoryLeakReportProto> reports; |
| 248 | leak_detector_controller_->GetLeakReports(&reports); |
| 249 | for (auto& report : reports) { |
| 250 | uma_proto->add_memory_leak_report()->Swap(&report); |
| 251 | } |
| 252 | } |
| 253 | |
kaznacheev | 9ec1251 | 2015-03-11 21:49:37 | [diff] [blame] | 254 | RecordEnrollmentStatus(); |
elijahtaylor | d88371f2 | 2016-11-05 00:07:18 | [diff] [blame] | 255 | RecordArcState(); |
[email protected] | a00d413 | 2014-05-29 20:16:25 | [diff] [blame] | 256 | } |
| 257 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 258 | void ChromeOSMetricsProvider::WriteBluetoothProto( |
| 259 | metrics::SystemProfileProto* system_profile_proto) { |
| 260 | metrics::SystemProfileProto::Hardware* hardware = |
| 261 | system_profile_proto->mutable_hardware(); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 262 | |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 263 | SystemProfileProto::Hardware::Bluetooth* bluetooth = |
| 264 | hardware->mutable_bluetooth(); |
| 265 | |
| 266 | bluetooth->set_is_present(adapter_->IsPresent()); |
| 267 | bluetooth->set_is_enabled(adapter_->IsPowered()); |
| 268 | |
| 269 | device::BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 270 | for (device::BluetoothAdapter::DeviceList::iterator iter = devices.begin(); |
| 271 | iter != devices.end(); |
| 272 | ++iter) { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 273 | device::BluetoothDevice* device = *iter; |
[email protected] | c8154319 | 2014-03-11 22:44:48 | [diff] [blame] | 274 | // Don't collect information about LE devices yet. |
| 275 | if (!device->IsPaired()) |
| 276 | continue; |
| 277 | |
| 278 | PairedDevice* paired_device = bluetooth->add_paired_device(); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 279 | paired_device->set_bluetooth_class(device->GetBluetoothClass()); |
| 280 | paired_device->set_type(AsBluetoothDeviceType(device->GetDeviceType())); |
| 281 | |
| 282 | // |address| is xx:xx:xx:xx:xx:xx, extract the first three components and |
avi | 6846aef | 2015-12-26 01:09:38 | [diff] [blame] | 283 | // pack into a uint32_t. |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 284 | std::string address = device->GetAddress(); |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 285 | if (address.size() > 9 && address[2] == ':' && address[5] == ':' && |
| 286 | address[8] == ':') { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 287 | std::string vendor_prefix_str; |
avi | 6846aef | 2015-12-26 01:09:38 | [diff] [blame] | 288 | uint64_t vendor_prefix; |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 289 | |
| 290 | base::RemoveChars(address.substr(0, 9), ":", &vendor_prefix_str); |
| 291 | DCHECK_EQ(6U, vendor_prefix_str.size()); |
| 292 | base::HexStringToUInt64(vendor_prefix_str, &vendor_prefix); |
| 293 | |
| 294 | paired_device->set_vendor_prefix(vendor_prefix); |
| 295 | } |
| 296 | |
[email protected] | c8154319 | 2014-03-11 22:44:48 | [diff] [blame] | 297 | switch (device->GetVendorIDSource()) { |
| 298 | case device::BluetoothDevice::VENDOR_ID_BLUETOOTH: |
| 299 | paired_device->set_vendor_id_source(PairedDevice::VENDOR_ID_BLUETOOTH); |
| 300 | break; |
| 301 | case device::BluetoothDevice::VENDOR_ID_USB: |
| 302 | paired_device->set_vendor_id_source(PairedDevice::VENDOR_ID_USB); |
| 303 | break; |
| 304 | default: |
| 305 | paired_device->set_vendor_id_source(PairedDevice::VENDOR_ID_UNKNOWN); |
| 306 | } |
| 307 | |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 308 | paired_device->set_vendor_id(device->GetVendorID()); |
| 309 | paired_device->set_product_id(device->GetProductID()); |
| 310 | paired_device->set_device_id(device->GetDeviceID()); |
| 311 | } |
| 312 | } |
| 313 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 314 | void ChromeOSMetricsProvider::UpdateMultiProfileUserCount( |
| 315 | metrics::SystemProfileProto* system_profile_proto) { |
[email protected] | 4d39078 | 2014-08-15 09:22:58 | [diff] [blame] | 316 | if (user_manager::UserManager::IsInitialized()) { |
| 317 | size_t user_count = |
| 318 | user_manager::UserManager::Get()->GetLoggedInUsers().size(); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 319 | |
| 320 | // We invalidate the user count if it changed while the log was open. |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 321 | if (registered_user_count_at_log_initialization_ && |
| 322 | user_count != user_count_at_log_initialization_) { |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 323 | user_count = 0; |
| 324 | } |
| 325 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 326 | system_profile_proto->set_multi_profile_user_count(user_count); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 327 | } |
| 328 | } |
| 329 | |
[email protected] | 8304f61a | 2014-05-24 12:17:33 | [diff] [blame] | 330 | void ChromeOSMetricsProvider::SetBluetoothAdapter( |
ortuno | 4958ca4f | 2016-02-26 02:15:43 | [diff] [blame] | 331 | base::Closure callback, |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 332 | scoped_refptr<device::BluetoothAdapter> adapter) { |
| 333 | adapter_ = adapter; |
ortuno | 4958ca4f | 2016-02-26 02:15:43 | [diff] [blame] | 334 | callback.Run(); |
[email protected] | c9afed6e | 2014-02-03 22:12:29 | [diff] [blame] | 335 | } |
kaznacheev | 9ec1251 | 2015-03-11 21:49:37 | [diff] [blame] | 336 | |
Steven Holte | b7f8139b | 2017-08-08 20:00:21 | [diff] [blame] | 337 | void ChromeOSMetricsProvider::SetHardwareClass(base::Closure callback, |
| 338 | std::string hardware_class) { |
| 339 | hardware_class_ = hardware_class; |
| 340 | callback.Run(); |
| 341 | } |
| 342 | |
kaznacheev | 9ec1251 | 2015-03-11 21:49:37 | [diff] [blame] | 343 | void ChromeOSMetricsProvider::RecordEnrollmentStatus() { |
Mark Pearson | 25a36bd | 2017-09-14 22:39:15 | [diff] [blame] | 344 | UMA_STABILITY_HISTOGRAM_ENUMERATION( |
kaznacheev | 9ec1251 | 2015-03-11 21:49:37 | [diff] [blame] | 345 | "UMA.EnrollmentStatus", GetEnrollmentStatus(), ENROLLMENT_STATUS_MAX); |
| 346 | } |
elijahtaylor | d88371f2 | 2016-11-05 00:07:18 | [diff] [blame] | 347 | |
| 348 | void ChromeOSMetricsProvider::RecordArcState() { |
hidehiko | 5d94408 | 2016-11-18 06:16:04 | [diff] [blame] | 349 | arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get(); |
| 350 | if (arc_session_manager) |
| 351 | arc_session_manager->RecordArcState(); |
elijahtaylor | d88371f2 | 2016-11-05 00:07:18 | [diff] [blame] | 352 | } |