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/chromeos/device_uma.h" 6 7 #include <X11/extensions/XInput.h> 8 #include <X11/extensions/XInput2.h> 9 10 #include "base/logging.h" 11 #include "base/memory/singleton.h" 12 #include "base/metrics/histogram.h" 13 #include "ui/events/event_constants.h" 14 #include "ui/events/event_utils.h" 15 #include "ui/events/x/device_data_manager.h" 16 17 // Enum type for CrOS gesture lib UMA 18 enum UMACrosGestureMetricsType{ 19 // To give an estimated number of all interested events. 20 UMA_CROS_GESTURE_METRICS_ALL_EVENTS, 21 UMA_CROS_GESTURE_METRICS_NOISY_GROUND, 22 // NOTE: Add states only immediately above this line. Make sure to 23 // update the enum list in tools/metrics/histograms/histograms.xml 24 // accordingly. 25 UMA_CROS_GESTURE_METRICS_COUNT 26 }; 27 28 namespace chromeos { 29 30 DeviceUMA* DeviceUMA::GetInstance() { 31 return Singleton<DeviceUMA>::get(); 32 } 33 34 DeviceUMA::DeviceUMA() 35 :is_observing_(false) { 36 AddMessageLoopObserver(); 37 } 38 39 DeviceUMA::~DeviceUMA() { 40 RemoveMessageLoopObserver(); 41 } 42 43 void DeviceUMA::Stop() { 44 RemoveMessageLoopObserver(); 45 } 46 47 void DeviceUMA::AddMessageLoopObserver() { 48 if (!is_observing_) { 49 base::MessageLoopForUI::current()->AddObserver(this); 50 is_observing_ = true; 51 } 52 } 53 54 void DeviceUMA::RemoveMessageLoopObserver() { 55 if (is_observing_) { 56 base::MessageLoopForUI::current()->RemoveObserver(this); 57 is_observing_ = false; 58 } 59 } 60 61 base::EventStatus DeviceUMA::WillProcessEvent( 62 const base::NativeEvent& event) { 63 CheckIncomingEvent(event); 64 return base::EVENT_CONTINUE; 65 } 66 67 void DeviceUMA::DidProcessEvent( 68 const base::NativeEvent& event) { 69 } 70 71 void DeviceUMA::CheckTouchpadEvent(const base::NativeEvent& native_event) { 72 XIDeviceEvent* xiev = 73 static_cast<XIDeviceEvent*>(native_event->xcookie.data); 74 // We take only the slave event since there is no need to count twice. 75 if (xiev->deviceid != xiev->sourceid) 76 return; 77 UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics", 78 UMA_CROS_GESTURE_METRICS_ALL_EVENTS, 79 UMA_CROS_GESTURE_METRICS_COUNT); 80 81 // Check for the CrOS touchpad metrics gesture 82 ui::DeviceDataManager *manager = ui::DeviceDataManager::GetInstance(); 83 if (manager->IsCMTMetricsEvent(native_event)) { 84 ui::GestureMetricsType type; 85 float data1, data2; 86 manager->GetMetricsData(native_event, &type, &data1, &data2); 87 88 // We currently track only the noisy ground issue. Please see 89 // http://crbug.com/237683. 90 if (type == ui::kGestureMetricsTypeNoisyGround) { 91 UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics", 92 UMA_CROS_GESTURE_METRICS_NOISY_GROUND, 93 UMA_CROS_GESTURE_METRICS_COUNT); 94 } 95 } 96 } 97 98 void DeviceUMA::CheckIncomingEvent(const base::NativeEvent& event) { 99 switch (event->type) { 100 case GenericEvent: { 101 if (ui::DeviceDataManager::GetInstance()->IsXIDeviceEvent(event) && 102 ui::IsTouchpadEvent(event)) 103 CheckTouchpadEvent(event); 104 break; 105 } 106 default: 107 break; 108 } 109 return; 110 } 111 112 } // namespace chromeos 113