Home | History | Annotate | Download | only in chromeos
      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/platform/platform_event_source.h"
     16 #include "ui/events/x/device_data_manager_x11.h"
     17 
     18 // Enum type for CrOS gesture lib UMA
     19 enum UMACrosGestureMetricsType{
     20   // To give an estimated number of all interested events.
     21   UMA_CROS_GESTURE_METRICS_ALL_EVENTS,
     22   UMA_CROS_GESTURE_METRICS_NOISY_GROUND,
     23   // NOTE: Add states only immediately above this line. Make sure to
     24   // update the enum list in tools/metrics/histograms/histograms.xml
     25   // accordingly.
     26   UMA_CROS_GESTURE_METRICS_COUNT
     27 };
     28 
     29 namespace chromeos {
     30 
     31 DeviceUMA* DeviceUMA::GetInstance() {
     32   return Singleton<DeviceUMA>::get();
     33 }
     34 
     35 DeviceUMA::DeviceUMA()
     36     : stopped_(false) {
     37   ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
     38 }
     39 
     40 DeviceUMA::~DeviceUMA() {
     41   Stop();
     42 }
     43 
     44 void DeviceUMA::Stop() {
     45   if (stopped_)
     46     return;
     47   ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
     48   stopped_ = true;
     49 }
     50 
     51 void DeviceUMA::WillProcessEvent(const ui::PlatformEvent& event) {
     52   CheckIncomingEvent(event);
     53 }
     54 
     55 void DeviceUMA::DidProcessEvent(const ui::PlatformEvent& event) {
     56 }
     57 
     58 void DeviceUMA::CheckTouchpadEvent(XEvent* native_event) {
     59   XIDeviceEvent* xiev =
     60       static_cast<XIDeviceEvent*>(native_event->xcookie.data);
     61   // We take only the slave event since there is no need to count twice.
     62   if (xiev->deviceid != xiev->sourceid)
     63     return;
     64   UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics",
     65                             UMA_CROS_GESTURE_METRICS_ALL_EVENTS,
     66                             UMA_CROS_GESTURE_METRICS_COUNT);
     67 
     68   // Check for the CrOS touchpad metrics gesture
     69   ui::DeviceDataManagerX11 *manager = ui::DeviceDataManagerX11::GetInstance();
     70   if (manager->IsCMTMetricsEvent(native_event)) {
     71     ui::GestureMetricsType type;
     72     float data1, data2;
     73     manager->GetMetricsData(native_event, &type, &data1, &data2);
     74 
     75     // We currently track only the noisy ground issue. Please see
     76     // http://crbug.com/237683.
     77     if (type == ui::kGestureMetricsTypeNoisyGround) {
     78       UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics",
     79                                 UMA_CROS_GESTURE_METRICS_NOISY_GROUND,
     80                                 UMA_CROS_GESTURE_METRICS_COUNT);
     81     }
     82   }
     83 }
     84 
     85 void DeviceUMA::CheckIncomingEvent(XEvent* event) {
     86   switch (event->type) {
     87     case GenericEvent: {
     88       ui::DeviceDataManagerX11* devices =
     89           ui::DeviceDataManagerX11::GetInstance();
     90       if (devices->IsXIDeviceEvent(event) &&
     91           devices->IsTouchpadXInputEvent(event)) {
     92         CheckTouchpadEvent(event);
     93       }
     94       break;
     95     }
     96     default:
     97       break;
     98   }
     99   return;
    100 }
    101 
    102 }  // namespace chromeos
    103