| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/touch/touch_uma.h" | 5 #include "ash/touch/touch_uma.h" |
| 6 | 6 |
| 7 #include "ash/shell_delegate.h" | 7 #include "ash/shell_delegate.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "ui/aura/env.h" | 10 #include "ui/aura/env.h" |
| 11 #include "ui/aura/root_window.h" | 11 #include "ui/aura/root_window.h" |
| 12 #include "ui/aura/window.h" | 12 #include "ui/aura/window.h" |
| 13 #include "ui/aura/window_property.h" | 13 #include "ui/aura/window_property.h" |
| 14 #include "ui/base/events/event.h" | 14 #include "ui/base/events/event.h" |
| 15 #include "ui/base/events/event_utils.h" | 15 #include "ui/base/events/event_utils.h" |
| 16 #include "ui/gfx/point_conversions.h" | 16 #include "ui/gfx/point_conversions.h" |
| 17 | 17 |
| 18 #if defined(USE_XI2_MT) | 18 #if defined(USE_XI2_MT) |
| 19 #include <X11/extensions/XInput2.h> | 19 #include <X11/extensions/XInput2.h> |
| 20 #include <X11/Xlib.h> | 20 #include <X11/Xlib.h> |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 enum GestureActionType { | |
| 26 GESTURE_UNKNOWN, | |
| 27 GESTURE_OMNIBOX_PINCH, | |
| 28 GESTURE_OMNIBOX_SCROLL, | |
| 29 GESTURE_TABSTRIP_PINCH, | |
| 30 GESTURE_TABSTRIP_SCROLL, | |
| 31 GESTURE_BEZEL_SCROLL, | |
| 32 GESTURE_DESKTOP_SCROLL, | |
| 33 GESTURE_DESKTOP_PINCH, | |
| 34 GESTURE_WEBPAGE_PINCH, | |
| 35 GESTURE_WEBPAGE_SCROLL, | |
| 36 GESTURE_WEBPAGE_TAP, | |
| 37 GESTURE_TABSTRIP_TAP, | |
| 38 GESTURE_BEZEL_DOWN, | |
| 39 // NOTE: Add new action types only immediately above this line. Also, make sure | |
| 40 // the enum list in tools/histogram/histograms.xml is updated with any change in | |
| 41 // here. | |
| 42 GESTURE_ACTION_COUNT | |
| 43 }; | |
| 44 | |
| 45 enum UMAEventType { | 25 enum UMAEventType { |
| 46 UMA_ET_UNKNOWN, | 26 UMA_ET_UNKNOWN, |
| 47 UMA_ET_TOUCH_RELEASED, | 27 UMA_ET_TOUCH_RELEASED, |
| 48 UMA_ET_TOUCH_PRESSED, | 28 UMA_ET_TOUCH_PRESSED, |
| 49 UMA_ET_TOUCH_MOVED, | 29 UMA_ET_TOUCH_MOVED, |
| 50 UMA_ET_TOUCH_STATIONARY, | 30 UMA_ET_TOUCH_STATIONARY, |
| 51 UMA_ET_TOUCH_CANCELLED, | 31 UMA_ET_TOUCH_CANCELLED, |
| 52 UMA_ET_GESTURE_SCROLL_BEGIN, | 32 UMA_ET_GESTURE_SCROLL_BEGIN, |
| 53 UMA_ET_GESTURE_SCROLL_END, | 33 UMA_ET_GESTURE_SCROLL_END, |
| 54 UMA_ET_GESTURE_SCROLL_UPDATE, | 34 UMA_ET_GESTURE_SCROLL_UPDATE, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 // Stores the time of the last touch released on this window (if there was a | 75 // Stores the time of the last touch released on this window (if there was a |
| 96 // multi-touch gesture on the window, then this is the release-time of the | 76 // multi-touch gesture on the window, then this is the release-time of the |
| 97 // last touch on the window). | 77 // last touch on the window). |
| 98 base::TimeDelta last_mt_time_; | 78 base::TimeDelta last_mt_time_; |
| 99 }; | 79 }; |
| 100 | 80 |
| 101 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowTouchDetails, | 81 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowTouchDetails, |
| 102 kWindowTouchDetails, | 82 kWindowTouchDetails, |
| 103 NULL); | 83 NULL); |
| 104 | 84 |
| 105 GestureActionType FindGestureActionType(aura::Window* window, | |
| 106 const ui::GestureEvent& event) { | |
| 107 if (!window || window->GetRootWindow() == window) { | |
| 108 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) | |
| 109 return GESTURE_BEZEL_SCROLL; | |
| 110 if (event.type() == ui::ET_GESTURE_BEGIN) | |
| 111 return GESTURE_BEZEL_DOWN; | |
| 112 return GESTURE_UNKNOWN; | |
| 113 } | |
| 114 | |
| 115 std::string name = window ? window->name() : std::string(); | |
| 116 | |
| 117 const char kDesktopBackgroundView[] = "DesktopBackgroundView"; | |
| 118 if (name == kDesktopBackgroundView) { | |
| 119 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) | |
| 120 return GESTURE_DESKTOP_SCROLL; | |
| 121 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) | |
| 122 return GESTURE_DESKTOP_PINCH; | |
| 123 return GESTURE_UNKNOWN; | |
| 124 } | |
| 125 | |
| 126 const char kWebPage[] = "RenderWidgetHostViewAura"; | |
| 127 if (name == kWebPage) { | |
| 128 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) | |
| 129 return GESTURE_WEBPAGE_PINCH; | |
| 130 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) | |
| 131 return GESTURE_WEBPAGE_SCROLL; | |
| 132 if (event.type() == ui::ET_GESTURE_TAP) | |
| 133 return GESTURE_WEBPAGE_TAP; | |
| 134 return GESTURE_UNKNOWN; | |
| 135 } | |
| 136 | |
| 137 views::Widget* widget = views::Widget::GetWidgetForNativeView(window); | |
| 138 if (!widget) | |
| 139 return GESTURE_UNKNOWN; | |
| 140 | |
| 141 views::View* view = widget->GetRootView()-> | |
| 142 GetEventHandlerForPoint(event.location()); | |
| 143 if (!view) | |
| 144 return GESTURE_UNKNOWN; | |
| 145 | |
| 146 name = view->GetClassName(); | |
| 147 | |
| 148 const char kTabStrip[] = "TabStrip"; | |
| 149 const char kTab[] = "BrowserTab"; | |
| 150 if (name == kTabStrip || name == kTab) { | |
| 151 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) | |
| 152 return GESTURE_TABSTRIP_SCROLL; | |
| 153 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) | |
| 154 return GESTURE_TABSTRIP_PINCH; | |
| 155 if (event.type() == ui::ET_GESTURE_TAP) | |
| 156 return GESTURE_TABSTRIP_TAP; | |
| 157 return GESTURE_UNKNOWN; | |
| 158 } | |
| 159 | |
| 160 const char kOmnibox[] = "BrowserOmniboxViewViews"; | |
| 161 if (name == kOmnibox) { | |
| 162 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) | |
| 163 return GESTURE_OMNIBOX_SCROLL; | |
| 164 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) | |
| 165 return GESTURE_OMNIBOX_PINCH; | |
| 166 return GESTURE_UNKNOWN; | |
| 167 } | |
| 168 | |
| 169 return GESTURE_UNKNOWN; | |
| 170 } | |
| 171 | 85 |
| 172 UMAEventType UMAEventTypeFromEvent(const ui::Event& event) { | 86 UMAEventType UMAEventTypeFromEvent(const ui::Event& event) { |
| 173 switch (event.type()) { | 87 switch (event.type()) { |
| 174 case ui::ET_TOUCH_RELEASED: | 88 case ui::ET_TOUCH_RELEASED: |
| 175 return UMA_ET_TOUCH_RELEASED; | 89 return UMA_ET_TOUCH_RELEASED; |
| 176 case ui::ET_TOUCH_PRESSED: | 90 case ui::ET_TOUCH_PRESSED: |
| 177 return UMA_ET_TOUCH_PRESSED; | 91 return UMA_ET_TOUCH_PRESSED; |
| 178 case ui::ET_TOUCH_MOVED: | 92 case ui::ET_TOUCH_MOVED: |
| 179 return UMA_ET_TOUCH_MOVED; | 93 return UMA_ET_TOUCH_MOVED; |
| 180 case ui::ET_TOUCH_STATIONARY: | 94 case ui::ET_TOUCH_STATIONARY: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 case ui::ET_SCROLL_FLING_CANCEL: | 164 case ui::ET_SCROLL_FLING_CANCEL: |
| 251 return UMA_ET_SCROLL_FLING_CANCEL; | 165 return UMA_ET_SCROLL_FLING_CANCEL; |
| 252 default: | 166 default: |
| 253 return UMA_ET_UNKNOWN; | 167 return UMA_ET_UNKNOWN; |
| 254 } | 168 } |
| 255 } | 169 } |
| 256 | 170 |
| 257 } | 171 } |
| 258 | 172 |
| 259 namespace ash { | 173 namespace ash { |
| 260 namespace internal { | |
| 261 | 174 |
| 262 TouchUMA::TouchUMA() | 175 // static |
| 263 : touch_in_progress_(false), | 176 TouchUMA* TouchUMA::GetInstance() { |
| 264 burst_length_(0) { | 177 return Singleton<TouchUMA>::get(); |
| 265 } | |
| 266 | |
| 267 TouchUMA::~TouchUMA() { | |
| 268 } | 178 } |
| 269 | 179 |
| 270 void TouchUMA::RecordGestureEvent(aura::Window* target, | 180 void TouchUMA::RecordGestureEvent(aura::Window* target, |
| 271 const ui::GestureEvent& event) { | 181 const ui::GestureEvent& event) { |
| 272 UMA_HISTOGRAM_ENUMERATION("Ash.GestureCreated", | 182 UMA_HISTOGRAM_ENUMERATION("Ash.GestureCreated", |
| 273 UMAEventTypeFromEvent(event), | 183 UMAEventTypeFromEvent(event), |
| 274 UMA_ET_COUNT); | 184 UMA_ET_COUNT); |
| 275 | 185 |
| 276 GestureActionType action = FindGestureActionType(target, event); | 186 GestureActionType action = FindGestureActionType(target, event); |
| 277 if (action != GESTURE_UNKNOWN) { | 187 RecordGestureAction(action); |
| 278 UMA_HISTOGRAM_ENUMERATION("Ash.GestureTarget", | |
| 279 action, | |
| 280 GESTURE_ACTION_COUNT); | |
| 281 } | |
| 282 | 188 |
| 283 if (event.type() == ui::ET_GESTURE_END && | 189 if (event.type() == ui::ET_GESTURE_END && |
| 284 event.details().touch_points() == 2) { | 190 event.details().touch_points() == 2) { |
| 285 WindowTouchDetails* details = target->GetProperty(kWindowTouchDetails); | 191 WindowTouchDetails* details = target->GetProperty(kWindowTouchDetails); |
| 286 if (!details) { | 192 if (!details) { |
| 287 LOG(ERROR) << "Window received gesture events without receiving any touch" | 193 LOG(ERROR) << "Window received gesture events without receiving any touch" |
| 288 " events"; | 194 " events"; |
| 289 return; | 195 return; |
| 290 } | 196 } |
| 291 details->last_mt_time_ = event.time_stamp(); | 197 details->last_mt_time_ = event.time_stamp(); |
| 292 } | 198 } |
| 293 } | 199 } |
| 294 | 200 |
| 201 void TouchUMA::RecordGestureAction(GestureActionType action) { |
| 202 if (action == GESTURE_UNKNOWN || action >= GESTURE_ACTION_COUNT) |
| 203 return; |
| 204 UMA_HISTOGRAM_ENUMERATION("Ash.GestureTarget", action, |
| 205 GESTURE_ACTION_COUNT); |
| 206 } |
| 207 |
| 295 void TouchUMA::RecordTouchEvent(aura::Window* target, | 208 void TouchUMA::RecordTouchEvent(aura::Window* target, |
| 296 const ui::TouchEvent& event) { | 209 const ui::TouchEvent& event) { |
| 297 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchRadius", | 210 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchRadius", |
| 298 static_cast<int>(std::max(event.radius_x(), event.radius_y())), | 211 static_cast<int>(std::max(event.radius_x(), event.radius_y())), |
| 299 1, 500, 100); | 212 1, 500, 100); |
| 300 | 213 |
| 301 UpdateBurstData(event); | 214 UpdateBurstData(event); |
| 302 | 215 |
| 303 WindowTouchDetails* details = target->GetProperty(kWindowTouchDetails); | 216 WindowTouchDetails* details = target->GetProperty(kWindowTouchDetails); |
| 304 if (!details) { | 217 if (!details) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 1, 50, 25); | 329 1, 50, 25); |
| 417 } | 330 } |
| 418 | 331 |
| 419 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchMoveSteps", distance, 1, 1000, 50); | 332 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.TouchMoveSteps", distance, 1, 1000, 50); |
| 420 | 333 |
| 421 details->last_move_time_[event.touch_id()] = event.time_stamp(); | 334 details->last_move_time_[event.touch_id()] = event.time_stamp(); |
| 422 details->last_touch_position_[event.touch_id()] = event.location(); | 335 details->last_touch_position_[event.touch_id()] = event.location(); |
| 423 } | 336 } |
| 424 } | 337 } |
| 425 | 338 |
| 339 TouchUMA::TouchUMA() |
| 340 : touch_in_progress_(false), |
| 341 burst_length_(0) { |
| 342 } |
| 343 |
| 344 TouchUMA::~TouchUMA() { |
| 345 } |
| 346 |
| 426 void TouchUMA::UpdateBurstData(const ui::TouchEvent& event) { | 347 void TouchUMA::UpdateBurstData(const ui::TouchEvent& event) { |
| 427 if (event.type() == ui::ET_TOUCH_PRESSED) { | 348 if (event.type() == ui::ET_TOUCH_PRESSED) { |
| 428 if (!touch_in_progress_) { | 349 if (!touch_in_progress_) { |
| 429 base::TimeDelta difference = event.time_stamp() - last_touch_down_time_; | 350 base::TimeDelta difference = event.time_stamp() - last_touch_down_time_; |
| 430 if (difference > base::TimeDelta::FromMilliseconds(250)) { | 351 if (difference > base::TimeDelta::FromMilliseconds(250)) { |
| 431 if (burst_length_) { | 352 if (burst_length_) { |
| 432 UMA_HISTOGRAM_COUNTS_100("Ash.TouchStartBurst", | 353 UMA_HISTOGRAM_COUNTS_100("Ash.TouchStartBurst", |
| 433 std::min(burst_length_, 100)); | 354 std::min(burst_length_, 100)); |
| 434 } | 355 } |
| 435 burst_length_ = 1; | 356 burst_length_ = 1; |
| 436 } else { | 357 } else { |
| 437 ++burst_length_; | 358 ++burst_length_; |
| 438 } | 359 } |
| 439 } | 360 } |
| 440 touch_in_progress_ = true; | 361 touch_in_progress_ = true; |
| 441 last_touch_down_time_ = event.time_stamp(); | 362 last_touch_down_time_ = event.time_stamp(); |
| 442 } else if (event.type() == ui::ET_TOUCH_RELEASED) { | 363 } else if (event.type() == ui::ET_TOUCH_RELEASED) { |
| 443 if (!aura::Env::GetInstance()->is_touch_down()) | 364 if (!aura::Env::GetInstance()->is_touch_down()) |
| 444 touch_in_progress_ = false; | 365 touch_in_progress_ = false; |
| 445 } | 366 } |
| 446 } | 367 } |
| 447 | 368 |
| 448 } // namespace internal | 369 TouchUMA::GestureActionType TouchUMA::FindGestureActionType( |
| 370 aura::Window* window, |
| 371 const ui::GestureEvent& event) { |
| 372 if (!window || window->GetRootWindow() == window) { |
| 373 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) |
| 374 return GESTURE_BEZEL_SCROLL; |
| 375 if (event.type() == ui::ET_GESTURE_BEGIN) |
| 376 return GESTURE_BEZEL_DOWN; |
| 377 return GESTURE_UNKNOWN; |
| 378 } |
| 379 |
| 380 std::string name = window ? window->name() : std::string(); |
| 381 |
| 382 const char kDesktopBackgroundView[] = "DesktopBackgroundView"; |
| 383 if (name == kDesktopBackgroundView) { |
| 384 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) |
| 385 return GESTURE_DESKTOP_SCROLL; |
| 386 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) |
| 387 return GESTURE_DESKTOP_PINCH; |
| 388 return GESTURE_UNKNOWN; |
| 389 } |
| 390 |
| 391 const char kWebPage[] = "RenderWidgetHostViewAura"; |
| 392 if (name == kWebPage) { |
| 393 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) |
| 394 return GESTURE_WEBPAGE_PINCH; |
| 395 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) |
| 396 return GESTURE_WEBPAGE_SCROLL; |
| 397 if (event.type() == ui::ET_GESTURE_TAP) |
| 398 return GESTURE_WEBPAGE_TAP; |
| 399 return GESTURE_UNKNOWN; |
| 400 } |
| 401 |
| 402 views::Widget* widget = views::Widget::GetWidgetForNativeView(window); |
| 403 if (!widget) |
| 404 return GESTURE_UNKNOWN; |
| 405 |
| 406 views::View* view = widget->GetRootView()-> |
| 407 GetEventHandlerForPoint(event.location()); |
| 408 if (!view) |
| 409 return GESTURE_UNKNOWN; |
| 410 |
| 411 name = view->GetClassName(); |
| 412 |
| 413 const char kTabStrip[] = "TabStrip"; |
| 414 const char kTab[] = "BrowserTab"; |
| 415 if (name == kTabStrip || name == kTab) { |
| 416 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) |
| 417 return GESTURE_TABSTRIP_SCROLL; |
| 418 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) |
| 419 return GESTURE_TABSTRIP_PINCH; |
| 420 if (event.type() == ui::ET_GESTURE_TAP) |
| 421 return GESTURE_TABSTRIP_TAP; |
| 422 return GESTURE_UNKNOWN; |
| 423 } |
| 424 |
| 425 const char kOmnibox[] = "BrowserOmniboxViewViews"; |
| 426 if (name == kOmnibox) { |
| 427 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) |
| 428 return GESTURE_OMNIBOX_SCROLL; |
| 429 if (event.type() == ui::ET_GESTURE_PINCH_BEGIN) |
| 430 return GESTURE_OMNIBOX_PINCH; |
| 431 return GESTURE_UNKNOWN; |
| 432 } |
| 433 |
| 434 return GESTURE_UNKNOWN; |
| 435 } |
| 436 |
| 449 } // namespace ash | 437 } // namespace ash |
| OLD | NEW |