summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc14
-rw-r--r--chrome/browser/chromeos/device_uma.cc111
-rw-r--r--chrome/browser/chromeos/device_uma.h53
-rw-r--r--chrome/chrome_browser_chromeos.gypi8
-rw-r--r--tools/metrics/histograms/histograms.xml17
-rw-r--r--ui/aura/root_window_host_x11.cc2
-rw-r--r--ui/base/events/event.cc1
-rw-r--r--ui/base/events/event_constants.h4
-rw-r--r--ui/base/x/device_data_manager.cc46
-rw-r--r--ui/base/x/device_data_manager.h19
-rw-r--r--ui/base/x/events_x.cc3
11 files changed, 277 insertions, 1 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index d34fd61..dd0ad54 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -120,6 +120,11 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_getter.h"
+// Exclude X11 dependents for ozone
+#if defined(USE_X11)
+#include "chrome/browser/chromeos/device_uma.h"
+#endif
+
namespace chromeos {
namespace {
@@ -721,6 +726,11 @@ void ChromeBrowserMainPartsChromeos::PreBrowserStart() {
// reasons, see http://crosbug.com/24833.
XInputHierarchyChangedEventListener::GetInstance();
+#if defined(USE_X11)
+ // Start the CrOS input device UMA watcher
+ DeviceUMA::GetInstance();
+#endif
+
// -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
// -- immediately after ChildProcess::WaitForDebugger().
@@ -791,6 +801,10 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() {
// Singletons are finally destroyed in AtExitManager.
XInputHierarchyChangedEventListener::GetInstance()->Stop();
+#if defined(USE_X11)
+ DeviceUMA::GetInstance()->Stop();
+#endif
+
// SystemKeyEventListener::Shutdown() is always safe to call,
// even if Initialize() wasn't called.
SystemKeyEventListener::Shutdown();
diff --git a/chrome/browser/chromeos/device_uma.cc b/chrome/browser/chromeos/device_uma.cc
new file mode 100644
index 0000000..2f852bb
--- /dev/null
+++ b/chrome/browser/chromeos/device_uma.cc
@@ -0,0 +1,111 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/device_uma.h"
+
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XInput2.h>
+
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/metrics/histogram.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/events/event_utils.h"
+#include "ui/base/x/device_data_manager.h"
+
+// Enum type for CrOS gesture lib UMA
+enum UMACrosGestureMetricsType{
+ // To give an estimated number of all interested events.
+ UMA_CROS_GESTURE_METRICS_ALL_EVENTS,
+ UMA_CROS_GESTURE_METRICS_NOISY_GROUND,
+ // NOTE: Add states only immediately above this line. Make sure to
+ // update the enum list in tools/metrics/histograms/histograms.xml
+ // accordingly.
+ UMA_CROS_GESTURE_METRICS_COUNT
+};
+
+namespace chromeos {
+
+DeviceUMA* DeviceUMA::GetInstance() {
+ return Singleton<DeviceUMA>::get();
+}
+
+DeviceUMA::DeviceUMA()
+ :is_observing_(false) {
+ AddMessageLoopObserver();
+}
+
+DeviceUMA::~DeviceUMA() {
+ RemoveMessageLoopObserver();
+}
+
+void DeviceUMA::Stop() {
+ RemoveMessageLoopObserver();
+}
+
+void DeviceUMA::AddMessageLoopObserver() {
+ if (!is_observing_) {
+ base::MessageLoopForUI::current()->AddObserver(this);
+ is_observing_ = true;
+ }
+}
+
+void DeviceUMA::RemoveMessageLoopObserver() {
+ if (is_observing_) {
+ base::MessageLoopForUI::current()->RemoveObserver(this);
+ is_observing_ = false;
+ }
+}
+
+base::EventStatus DeviceUMA::WillProcessEvent(
+ const base::NativeEvent& event) {
+ CheckIncomingEvent(event);
+ return base::EVENT_CONTINUE;
+}
+
+void DeviceUMA::DidProcessEvent(
+ const base::NativeEvent& event) {
+}
+
+void DeviceUMA::CheckTouchpadEvent(const base::NativeEvent& native_event) {
+ XIDeviceEvent* xiev =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ // We take only the slave event since there is no need to count twice.
+ if (xiev->deviceid != xiev->sourceid)
+ return;
+ UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics",
+ UMA_CROS_GESTURE_METRICS_ALL_EVENTS,
+ UMA_CROS_GESTURE_METRICS_COUNT);
+
+ // Check for the CrOS touchpad metrics gesture
+ ui::DeviceDataManager *manager = ui::DeviceDataManager::GetInstance();
+ if (manager->IsCMTMetricsEvent(native_event)) {
+ ui::GestureMetricsType type;
+ float data1, data2;
+ manager->GetMetricsData(native_event, &type, &data1, &data2);
+
+ // We currently track only the noisy ground issue. Please see
+ // http://crbug.com/237683.
+ if (type == ui::kGestureMetricsTypeNoisyGround) {
+ UMA_HISTOGRAM_ENUMERATION("Touchpad.Metrics",
+ UMA_CROS_GESTURE_METRICS_NOISY_GROUND,
+ UMA_CROS_GESTURE_METRICS_COUNT);
+ }
+ }
+}
+
+void DeviceUMA::CheckIncomingEvent(const base::NativeEvent& event) {
+ switch (event->type) {
+ case GenericEvent: {
+ if (ui::IsTouchpadEvent(event))
+ CheckTouchpadEvent(event);
+ break;
+ }
+ default:
+ break;
+ }
+ return;
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/device_uma.h b/chrome/browser/chromeos/device_uma.h
new file mode 100644
index 0000000..77f7543
--- /dev/null
+++ b/chrome/browser/chromeos/device_uma.h
@@ -0,0 +1,53 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DEVICE_UMA_H_
+#define CHROME_BROWSER_CHROMEOS_DEVICE_UMA_H_
+
+#include "base/basictypes.h"
+#include "base/event_types.h"
+#include "base/message_loop.h"
+
+template <typename T> struct DefaultSingletonTraits;
+
+namespace chromeos {
+
+// A class to record devices' input event details via the UMA system
+class DeviceUMA : public base::MessageLoopForUI::Observer {
+ public:
+ // Getting instance starts the class automatically if it hasn't been
+ // started before.
+ static DeviceUMA* GetInstance();
+
+ void Stop();
+
+ private:
+ friend struct DefaultSingletonTraits<DeviceUMA>;
+
+ DeviceUMA();
+ virtual ~DeviceUMA();
+
+ // Start and stop observing events.
+ void AddMessageLoopObserver();
+ void RemoveMessageLoopObserver();
+
+ // MessageLoopForUI::Observer overrides.
+ virtual base::EventStatus WillProcessEvent(
+ const base::NativeEvent& event) OVERRIDE;
+ virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
+
+ // Check CrOS touchpad events to see if the metrics gesture is present
+ void CheckTouchpadEvent(const base::NativeEvent& event);
+
+ // Check the incoming events for interesting patterns that we care about.
+ void CheckIncomingEvent(const base::NativeEvent& event);
+
+ bool is_observing_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceUMA);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_DEVICE_UMA_H_
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 6872360..9bbfca7 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -211,6 +211,8 @@
'browser/chromeos/dbus/proxy_resolution_service_provider.cc',
'browser/chromeos/dbus/proxy_resolution_service_provider.h',
'browser/chromeos/device_hierarchy_observer.h',
+ 'browser/chromeos/device_uma.cc',
+ 'browser/chromeos/device_uma.h',
'browser/chromeos/drive/change_list_loader.cc',
'browser/chromeos/drive/change_list_loader.h',
'browser/chromeos/drive/change_list_loader_observer.h',
@@ -823,6 +825,12 @@
'browser/chromeos/extensions/wallpaper_private_api.h',
],
}],
+ ['use_x11==0', {
+ 'sources!': [
+ 'browser/chromeos/device_uma.cc',
+ 'browser/chromeos/device_uma.h',
+ ],
+ }],
['use_cras==1', {
'cflags': [
'<!@(<(pkg-config) --cflags libcras)',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 454e7c7..27b364f 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -11167,6 +11167,13 @@ other types of suffix sets.
<summary>Tracks touchpad device state.</summary>
</histogram>
+<histogram name="Touchpad.Metrics" enum="TouchpadProblemType">
+ <summary>
+ Tracks unusual CrOS touchpad operational states (e.g. running into the noisy
+ ground issue). This is sampled at every touchpad event.
+ </summary>
+</histogram>
+
<histogram name="Touchpad.NaturalScroll.Changed" enum="BooleanEnabled">
<summary>Tracks touchpad natural scroll setting changes by the user.</summary>
</histogram>
@@ -17882,6 +17889,16 @@ other types of suffix sets.
</int>
</enum>
+<enum name="TouchpadProblemType" type="int">
+ <int value="0" label="All events">
+ All observed input events from touchpad. Serves as a reference.
+ </int>
+ <int value="1" label="Noisy Ground">
+ The touchpad noise events (e.g. abrupt cursor jumps) caused by the noisy
+ ground.
+ </int>
+</enum>
+
<enum name="TranslateError" type="int">
<int value="0" label="No error"/>
<int value="1" label="Network error"/>
diff --git a/ui/aura/root_window_host_x11.cc b/ui/aura/root_window_host_x11.cc
index f827373..6606ea2 100644
--- a/ui/aura/root_window_host_x11.cc
+++ b/ui/aura/root_window_host_x11.cc
@@ -1027,6 +1027,8 @@ void RootWindowHostX11::DispatchXI2Event(const base::NativeEvent& event) {
delegate_->OnHostScrollEvent(&scrollev);
break;
}
+ case ui::ET_UMA_DATA:
+ break;
case ui::ET_UNKNOWN:
break;
default:
diff --git a/ui/base/events/event.cc b/ui/base/events/event.cc
index 40b5639..b69780c 100644
--- a/ui/base/events/event.cc
+++ b/ui/base/events/event.cc
@@ -95,6 +95,7 @@ std::string EventTypeName(ui::EventType type) {
CASE_TYPE(ET_SCROLL_FLING_START);
CASE_TYPE(ET_SCROLL_FLING_CANCEL);
CASE_TYPE(ET_CANCEL_MODE);
+ CASE_TYPE(ET_UMA_DATA);
case ui::ET_LAST: NOTREACHED(); return std::string();
// Don't include default, so that we get an error when new type is added.
}
diff --git a/ui/base/events/event_constants.h b/ui/base/events/event_constants.h
index e91c779..481579e 100644
--- a/ui/base/events/event_constants.h
+++ b/ui/base/events/event_constants.h
@@ -58,6 +58,10 @@ enum EventType {
// drop or menus, should stop.
ET_CANCEL_MODE,
+ // Sent by the CrOS gesture library for interesting patterns that we want
+ // to track with the UMA system.
+ ET_UMA_DATA,
+
// Must always be last. User namespace starts above this value.
// See ui::RegisterCustomEventType().
ET_LAST
diff --git a/ui/base/x/device_data_manager.cc b/ui/base/x/device_data_manager.cc
index 0332d75..7707518 100644
--- a/ui/base/x/device_data_manager.cc
+++ b/ui/base/x/device_data_manager.cc
@@ -41,6 +41,11 @@
#define AXIS_LABEL_PROP_ABS_FINGER_COUNT "Abs Finger Count"
+// Cros metrics gesture from touchpad
+#define AXIS_LABEL_PROP_ABS_METRICS_TYPE "Abs Metrics Type"
+#define AXIS_LABEL_PROP_ABS_DBL_METRICS_DATA1 "Abs Dbl Metrics Data 1"
+#define AXIS_LABEL_PROP_ABS_DBL_METRICS_DATA2 "Abs Dbl Metrics Data 2"
+
// Touchscreen multi-touch
#define AXIS_LABEL_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major"
#define AXIS_LABEL_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor"
@@ -63,6 +68,9 @@ const char* kCachedAtoms[] = {
AXIS_LABEL_PROP_ABS_DBL_FLING_VX,
AXIS_LABEL_PROP_ABS_DBL_FLING_VY,
AXIS_LABEL_PROP_ABS_FLING_STATE,
+ AXIS_LABEL_PROP_ABS_METRICS_TYPE,
+ AXIS_LABEL_PROP_ABS_DBL_METRICS_DATA1,
+ AXIS_LABEL_PROP_ABS_DBL_METRICS_DATA2,
AXIS_LABEL_PROP_ABS_FINGER_COUNT,
AXIS_LABEL_ABS_MT_TOUCH_MAJOR,
AXIS_LABEL_ABS_MT_TOUCH_MINOR,
@@ -285,7 +293,8 @@ bool DeviceDataManager::IsCMTDeviceEvent(
bool DeviceDataManager::IsCMTGestureEvent(
const base::NativeEvent& native_event) const {
return (IsScrollEvent(native_event) ||
- IsFlingEvent(native_event));
+ IsFlingEvent(native_event) ||
+ IsCMTMetricsEvent(native_event));
}
bool DeviceDataManager::HasEventData(
@@ -317,6 +326,18 @@ bool DeviceDataManager::IsFlingEvent(
HasEventData(xiev, DT_CMT_FLING_STATE));
}
+bool DeviceDataManager::IsCMTMetricsEvent(
+ const base::NativeEvent& native_event) const {
+ if (!IsCMTDeviceEvent(native_event))
+ return false;
+
+ XIDeviceEvent* xiev =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ return (HasEventData(xiev, DT_CMT_METRICS_TYPE) &&
+ HasEventData(xiev, DT_CMT_METRICS_DATA1) &&
+ HasEventData(xiev, DT_CMT_METRICS_DATA2));
+}
+
bool DeviceDataManager::HasGestureTimes(
const base::NativeEvent& native_event) const {
if (!IsCMTDeviceEvent(native_event))
@@ -385,6 +406,29 @@ void DeviceDataManager::GetFlingData(const base::NativeEvent& native_event,
*vy_ordinal = data[DT_CMT_ORDINAL_Y] * natural_scroll_factor;
}
+void DeviceDataManager::GetMetricsData(const base::NativeEvent& native_event,
+ GestureMetricsType* type,
+ float* data1, float* data2) {
+ *type = kGestureMetricsTypeUnknown;
+ *data1 = 0;
+ *data2 = 0;
+
+ EventData data;
+ GetEventRawData(*native_event, &data);
+
+ if (data.find(DT_CMT_METRICS_TYPE) != data.end()) {
+ int val = static_cast<int>(data[DT_CMT_METRICS_TYPE]);
+ if (val == 0)
+ *type = kGestureMetricsTypeNoisyGround;
+ else
+ *type = kGestureMetricsTypeUnknown;
+ }
+ if (data.find(DT_CMT_METRICS_DATA1) != data.end())
+ *data1 = data[DT_CMT_METRICS_DATA1];
+ if (data.find(DT_CMT_METRICS_DATA2) != data.end())
+ *data2 = data[DT_CMT_METRICS_DATA2];
+}
+
void DeviceDataManager::GetGestureTimes(const base::NativeEvent& native_event,
double* start_time,
double* end_time) {
diff --git a/ui/base/x/device_data_manager.h b/ui/base/x/device_data_manager.h
index 27f468a..950cca1 100644
--- a/ui/base/x/device_data_manager.h
+++ b/ui/base/x/device_data_manager.h
@@ -23,6 +23,12 @@ typedef union _XEvent XEvent;
namespace ui {
+// CrOS touchpad metrics gesture types
+enum GestureMetricsType {
+ kGestureMetricsTypeNoisyGround = 0,
+ kGestureMetricsTypeUnknown,
+};
+
// A class that extracts and tracks the input events data. It currently handles
// mouse, touchpad and touchscreen devices.
class UI_EXPORT DeviceDataManager {
@@ -47,6 +53,11 @@ class UI_EXPORT DeviceDataManager {
DT_CMT_FLING_Y, // Fling amount on the Y (vertical) direction.
DT_CMT_FLING_STATE, // The state of fling gesture (whether the user just
// start flinging or that he/she taps down).
+ DT_CMT_METRICS_TYPE, // Metrics type of the metrics gesture, which are
+ // used to wrap interesting patterns that we would
+ // like to track via the UMA system.
+ DT_CMT_METRICS_DATA1, // Complementary data 1 of the metrics gesture.
+ DT_CMT_METRICS_DATA2, // Complementary data 2 of the metrics gesture.
DT_CMT_FINGER_COUNT, // Finger counts in the current gesture. A same type
// of gesture can have very different meanings based
// on that (e.g. 2f scroll v.s. 3f swipe).
@@ -140,6 +151,7 @@ class UI_EXPORT DeviceDataManager {
// Returns true if the event is of the specific type, false if not.
bool IsScrollEvent(const base::NativeEvent& native_event) const;
bool IsFlingEvent(const base::NativeEvent& native_event) const;
+ bool IsCMTMetricsEvent(const base::NativeEvent& native_event) const;
// Returns true if the event has CMT start/end timestamps.
bool HasGestureTimes(const base::NativeEvent& native_event) const;
@@ -163,6 +175,13 @@ class UI_EXPORT DeviceDataManager {
float* vy_ordinal,
bool* is_cancel);
+ // Extract data from a CrOS metrics gesture event. User must first verify
+ // the event type with IsCMTMetricsEvent. Pointers shouldn't be NULL.
+ void GetMetricsData(const base::NativeEvent& native_event,
+ GestureMetricsType* type,
+ float* data1,
+ float* data2);
+
// Extract the start/end timestamps from CMT events. User must first verify
// the event with HasGestureTimes. Pointers shouldn't be NULL.
void GetGestureTimes(const base::NativeEvent& native_event,
diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc
index c625ec9..ed26b93 100644
--- a/ui/base/x/events_x.cc
+++ b/ui/base/x/events_x.cc
@@ -344,6 +344,9 @@ EventType EventTypeFromNative(const base::NativeEvent& native_event) {
} else if (DeviceDataManager::GetInstance()->IsScrollEvent(
native_event)) {
return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL;
+ } else if (DeviceDataManager::GetInstance()->IsCMTMetricsEvent(
+ native_event)) {
+ return ET_UMA_DATA;
} else if (GetButtonMaskForX2Event(xievent)) {
return ET_MOUSE_DRAGGED;
} else {