device_uma.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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/base/x/device_data_manager.h"
14#include "ui/events/event_constants.h"
15#include "ui/events/event_utils.h"
16
17// Enum type for CrOS gesture lib UMA
18enum 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
28namespace chromeos {
29
30DeviceUMA* DeviceUMA::GetInstance() {
31  return Singleton<DeviceUMA>::get();
32}
33
34DeviceUMA::DeviceUMA()
35    :is_observing_(false) {
36  AddMessageLoopObserver();
37}
38
39DeviceUMA::~DeviceUMA() {
40  RemoveMessageLoopObserver();
41}
42
43void DeviceUMA::Stop() {
44  RemoveMessageLoopObserver();
45}
46
47void DeviceUMA::AddMessageLoopObserver() {
48  if (!is_observing_) {
49    base::MessageLoopForUI::current()->AddObserver(this);
50    is_observing_ = true;
51  }
52}
53
54void DeviceUMA::RemoveMessageLoopObserver() {
55  if (is_observing_) {
56    base::MessageLoopForUI::current()->RemoveObserver(this);
57    is_observing_ = false;
58  }
59}
60
61base::EventStatus DeviceUMA::WillProcessEvent(
62    const base::NativeEvent& event) {
63  CheckIncomingEvent(event);
64  return base::EVENT_CONTINUE;
65}
66
67void DeviceUMA::DidProcessEvent(
68    const base::NativeEvent& event) {
69}
70
71void 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
98void 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