Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: ui/touch_selection/touch_selection_controller.cc

Issue 2201853002: Blink handle selection handle visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed incorrect rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "ui/touch_selection/touch_selection_controller.h" 5 #include "ui/touch_selection/touch_selection_controller.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/metrics/user_metrics.h" 10 #include "base/metrics/user_metrics.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 enable_longpress_drag_selection(false) {} 49 enable_longpress_drag_selection(false) {}
50 50
51 TouchSelectionController::Config::~Config() { 51 TouchSelectionController::Config::~Config() {
52 } 52 }
53 53
54 TouchSelectionController::TouchSelectionController( 54 TouchSelectionController::TouchSelectionController(
55 TouchSelectionControllerClient* client, 55 TouchSelectionControllerClient* client,
56 const Config& config) 56 const Config& config)
57 : client_(client), 57 : client_(client),
58 config_(config), 58 config_(config),
59 force_next_update_(false),
60 response_pending_input_event_(INPUT_EVENT_TYPE_NONE), 59 response_pending_input_event_(INPUT_EVENT_TYPE_NONE),
61 start_orientation_(TouchHandleOrientation::UNDEFINED), 60 start_orientation_(TouchHandleOrientation::UNDEFINED),
62 end_orientation_(TouchHandleOrientation::UNDEFINED), 61 end_orientation_(TouchHandleOrientation::UNDEFINED),
63 active_status_(INACTIVE), 62 active_status_(INACTIVE),
64 activate_insertion_automatically_(false),
65 activate_selection_automatically_(false),
66 selection_empty_(false),
67 selection_editable_(false),
68 temporarily_hidden_(false), 63 temporarily_hidden_(false),
69 anchor_drag_to_selection_start_(false), 64 anchor_drag_to_selection_start_(false),
70 longpress_drag_selector_(this), 65 longpress_drag_selector_(this),
71 selection_handle_dragged_(false), 66 selection_handle_dragged_(false),
72 consume_touch_sequence_(false) { 67 consume_touch_sequence_(false),
68 show_touch_handles_(true)
69 {
73 DCHECK(client_); 70 DCHECK(client_);
74 } 71 }
75 72
76 TouchSelectionController::~TouchSelectionController() { 73 TouchSelectionController::~TouchSelectionController() {
77 } 74 }
78 75
79 void TouchSelectionController::OnSelectionBoundsChanged( 76 void TouchSelectionController::OnSelectionBoundsChanged(
80 const gfx::SelectionBound& start, 77 const gfx::SelectionBound& start,
81 const gfx::SelectionBound& end) { 78 const gfx::SelectionBound& end) {
82 if (!force_next_update_ && start == start_ && end_ == end) 79 if (start == start_ && end_ == end)
83 return; 80 return;
84 81
85 // Notify if selection bounds have just been established or dissolved. 82 if (start.type() == gfx::SelectionBound::EMPTY ||
86 if (start.type() != gfx::SelectionBound::EMPTY && 83 end.type() == gfx::SelectionBound::EMPTY ||
87 start_.type() == gfx::SelectionBound::EMPTY) { 84 !show_touch_handles_) {
88 client_->OnSelectionEvent(SELECTION_ESTABLISHED); 85 HideHandles();
89 } else if (start.type() == gfx::SelectionBound::EMPTY && 86 return;
90 start_.type() != gfx::SelectionBound::EMPTY) {
91 client_->OnSelectionEvent(SELECTION_DISSOLVED);
92 } 87 }
93 88
94 // Swap the Handles when the start and end selection points cross each other. 89 // Swap the Handles when the start and end selection points cross each other.
95 if (active_status_ == SELECTION_ACTIVE) { 90 if (active_status_ == SELECTION_ACTIVE) {
96 if ((start_selection_handle_->IsActive() && 91 if ((start_selection_handle_->IsActive() &&
97 end_.edge_bottom() == start.edge_bottom()) || 92 end_.edge_bottom() == start.edge_bottom()) ||
98 (end_selection_handle_->IsActive() && 93 (end_selection_handle_->IsActive() &&
99 end.edge_bottom() == start_.edge_bottom())) { 94 end.edge_bottom() == start_.edge_bottom())) {
100 start_selection_handle_.swap(end_selection_handle_); 95 start_selection_handle_.swap(end_selection_handle_);
101 } 96 }
102 } 97 }
103 98
104 start_ = start; 99 start_ = start;
105 end_ = end; 100 end_ = end;
106 start_orientation_ = ToTouchHandleOrientation(start_.type()); 101 start_orientation_ = ToTouchHandleOrientation(start_.type());
107 end_orientation_ = ToTouchHandleOrientation(end_.type()); 102 end_orientation_ = ToTouchHandleOrientation(end_.type());
108 force_next_update_ = false;
109
110 if (!activate_selection_automatically_ &&
111 !activate_insertion_automatically_) {
112 DCHECK_EQ(INACTIVE, active_status_);
113 DCHECK_EQ(INPUT_EVENT_TYPE_NONE, response_pending_input_event_);
114 return;
115 }
116 103
117 // Ensure that |response_pending_input_event_| is cleared after the method 104 // Ensure that |response_pending_input_event_| is cleared after the method
118 // completes, while also making its current value available for the duration 105 // completes, while also making its current value available for the duration
119 // of the call. 106 // of the call.
120 InputEventType causal_input_event = response_pending_input_event_; 107 InputEventType causal_input_event = response_pending_input_event_;
121 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 108 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
122 base::AutoReset<InputEventType> auto_reset_response_pending_input_event( 109 base::AutoReset<InputEventType> auto_reset_response_pending_input_event(
123 &response_pending_input_event_, causal_input_event); 110 &response_pending_input_event_, causal_input_event);
124 111
125 const bool is_selection_dragging = active_status_ == SELECTION_ACTIVE && 112 const bool is_selection_dragging = active_status_ == SELECTION_ACTIVE &&
(...skipping 10 matching lines...) Expand all
136 } 123 }
137 124
138 if (GetStartPosition() != GetEndPosition() || 125 if (GetStartPosition() != GetEndPosition() ||
139 (is_selection_dragging && 126 (is_selection_dragging &&
140 start_orientation_ != TouchHandleOrientation::UNDEFINED && 127 start_orientation_ != TouchHandleOrientation::UNDEFINED &&
141 end_orientation_ != TouchHandleOrientation::UNDEFINED)) { 128 end_orientation_ != TouchHandleOrientation::UNDEFINED)) {
142 OnSelectionChanged(); 129 OnSelectionChanged();
143 return; 130 return;
144 } 131 }
145 132
146 if (start_orientation_ == TouchHandleOrientation::CENTER && 133 if (start_orientation_ == TouchHandleOrientation::CENTER) {
147 selection_editable_) {
148 OnInsertionChanged(); 134 OnInsertionChanged();
149 return; 135 return;
150 } 136 }
151 137
152 HideAndDisallowShowingAutomatically(); 138 HideHandles();
153 } 139 }
154 140
155 void TouchSelectionController::OnViewportChanged( 141 void TouchSelectionController::OnViewportChanged(
156 const gfx::RectF viewport_rect) { 142 const gfx::RectF viewport_rect) {
157 // Trigger a force update if the viewport is changed, so that 143 // Trigger a force update if the viewport is changed, so that
158 // it triggers a call to change the mirror values if required. 144 // it triggers a call to change the mirror values if required.
159 if (viewport_rect_ == viewport_rect) 145 if (viewport_rect_ == viewport_rect)
160 return; 146 return;
161 147
162 viewport_rect_ = viewport_rect; 148 viewport_rect_ = viewport_rect;
(...skipping 21 matching lines...) Expand all
184 // too, regardless of value of |handled|. 170 // too, regardless of value of |handled|.
185 // TODO(mohsen): This will consume touch events until the next ACTION_DOWN. 171 // TODO(mohsen): This will consume touch events until the next ACTION_DOWN.
186 // Ideally we should consume until the final ACTION_UP/ACTION_CANCEL. 172 // Ideally we should consume until the final ACTION_UP/ACTION_CANCEL.
187 // But, apparently, we can't reliably determine the final ACTION_CANCEL in a 173 // But, apparently, we can't reliably determine the final ACTION_CANCEL in a
188 // multi-touch scenario. See https://crbug.com/653212. 174 // multi-touch scenario. See https://crbug.com/653212.
189 if (event.GetAction() == MotionEvent::ACTION_DOWN) 175 if (event.GetAction() == MotionEvent::ACTION_DOWN)
190 consume_touch_sequence_ = handled; 176 consume_touch_sequence_ = handled;
191 return handled || consume_touch_sequence_; 177 return handled || consume_touch_sequence_;
192 } 178 }
193 179
194 bool TouchSelectionController::WillHandleTapEvent(const gfx::PointF& location, 180 void TouchSelectionController::HandleTapEvent(const gfx::PointF& location,
195 int tap_count) { 181 int tap_count) {
196 if (WillHandleTapOrLongPress(location))
197 return true;
198
199 if (tap_count > 1) { 182 if (tap_count > 1) {
200 response_pending_input_event_ = REPEATED_TAP; 183 response_pending_input_event_ = REPEATED_TAP;
201 ShowSelectionHandlesAutomatically();
202 } else { 184 } else {
203 response_pending_input_event_ = TAP; 185 response_pending_input_event_ = TAP;
204 if (active_status_ != SELECTION_ACTIVE)
205 activate_selection_automatically_ = false;
206 } 186 }
207 ShowInsertionHandleAutomatically();
208 if (selection_empty_)
209 DeactivateInsertion();
210 ForceNextUpdateIfInactive();
211 return false;
212 } 187 }
213 188
214 bool TouchSelectionController::WillHandleLongPressEvent( 189 void TouchSelectionController::HandleLongPressEvent(
215 base::TimeTicks event_time, 190 base::TimeTicks event_time,
216 const gfx::PointF& location) { 191 const gfx::PointF& location) {
217 if (WillHandleTapOrLongPress(location))
218 return true;
219
220 longpress_drag_selector_.OnLongPressEvent(event_time, location); 192 longpress_drag_selector_.OnLongPressEvent(event_time, location);
221 response_pending_input_event_ = LONG_PRESS; 193 response_pending_input_event_ = LONG_PRESS;
222 ShowSelectionHandlesAutomatically();
223 ShowInsertionHandleAutomatically();
224 ForceNextUpdateIfInactive();
225 return false;
226 } 194 }
227 195
228 void TouchSelectionController::OnScrollBeginEvent() { 196 void TouchSelectionController::OnScrollBeginEvent() {
229 // When there is an active selection, if the user performs a long-press that 197 // When there is an active selection, if the user performs a long-press that
230 // does not trigger a new selection (e.g. a long-press on an empty area) and 198 // does not trigger a new selection (e.g. a long-press on an empty area) and
231 // then scrolls, the scroll will move the selection. In this case we will 199 // then scrolls, the scroll will move the selection. In this case we will
232 // think incorrectly that the selection change was due to the long-press and 200 // think incorrectly that the selection change was due to the long-press and
233 // will activate touch selection and start long-press drag gesture (see 201 // will activate touch selection and start long-press drag gesture (see
234 // ActivateInsertionIfNecessary()). To prevent this, we need to reset the 202 // ActivateInsertionIfNecessary()). To prevent this, we need to reset the
235 // state of touch selection controller and long-press drag selector. 203 // state of touch selection controller and long-press drag selector.
236 // TODO(mohsen): Remove this workaround when we have enough information about 204 // TODO(mohsen): Remove this workaround when we have enough information about
237 // the cause of a selection change (see https://crbug.com/571897). 205 // the cause of a selection change (see https://crbug.com/571897).
238 longpress_drag_selector_.OnScrollBeginEvent(); 206 longpress_drag_selector_.OnScrollBeginEvent();
239 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 207 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
240 if (active_status_ == INACTIVE) {
241 activate_insertion_automatically_ = false;
242 activate_selection_automatically_ = false;
243 }
244 } 208 }
245 209
246 void TouchSelectionController::AllowShowingFromCurrentSelection() { 210 void TouchSelectionController::HideHandles() {
247 if (active_status_ != INACTIVE) 211 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
248 return; 212 DeactivateInsertion();
249 213 DeactivateSelection();
250 activate_selection_automatically_ = true; 214 start_ = gfx::SelectionBound();
251 activate_insertion_automatically_ = true; 215 end_ = gfx::SelectionBound();
252 if (GetStartPosition() != GetEndPosition()) { 216 start_orientation_ = ToTouchHandleOrientation(start_.type());
253 OnSelectionChanged(); 217 end_orientation_ = ToTouchHandleOrientation(end_.type());
254 } else if (start_orientation_ == TouchHandleOrientation::CENTER &&
255 selection_editable_) {
256 OnInsertionChanged();
257 }
258 } 218 }
259 219
260 void TouchSelectionController::HideAndDisallowShowingAutomatically() { 220 void TouchSelectionController::HideAndDisallowShowingAutomatically() {
261 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 221 HideHandles();
262 DeactivateInsertion(); 222 show_touch_handles_ = false;
263 DeactivateSelection();
264 activate_insertion_automatically_ = false;
265 activate_selection_automatically_ = false;
266 } 223 }
267 224
268 void TouchSelectionController::SetTemporarilyHidden(bool hidden) { 225 void TouchSelectionController::SetTemporarilyHidden(bool hidden) {
269 if (temporarily_hidden_ == hidden) 226 if (temporarily_hidden_ == hidden)
270 return; 227 return;
271 temporarily_hidden_ = hidden; 228 temporarily_hidden_ = hidden;
272 RefreshHandleVisibility(); 229 RefreshHandleVisibility();
273 } 230 }
274 231
275 void TouchSelectionController::OnSelectionEditable(bool editable) {
276 if (selection_editable_ == editable)
277 return;
278 selection_editable_ = editable;
279 ForceNextUpdateIfInactive();
280 if (!selection_editable_)
281 DeactivateInsertion();
282 }
283
284 void TouchSelectionController::OnSelectionEmpty(bool empty) {
285 if (selection_empty_ == empty)
286 return;
287 selection_empty_ = empty;
288 ForceNextUpdateIfInactive();
289 }
290
291 bool TouchSelectionController::Animate(base::TimeTicks frame_time) { 232 bool TouchSelectionController::Animate(base::TimeTicks frame_time) {
292 if (active_status_ == INSERTION_ACTIVE) 233 if (active_status_ == INSERTION_ACTIVE)
293 return insertion_handle_->Animate(frame_time); 234 return insertion_handle_->Animate(frame_time);
294 235
295 if (active_status_ == SELECTION_ACTIVE) { 236 if (active_status_ == SELECTION_ACTIVE) {
296 bool needs_animate = start_selection_handle_->Animate(frame_time); 237 bool needs_animate = start_selection_handle_->Animate(frame_time);
297 needs_animate |= end_selection_handle_->Animate(frame_time); 238 needs_animate |= end_selection_handle_->Animate(frame_time);
298 return needs_animate; 239 return needs_animate;
299 } 240 }
300 241
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 const gfx::PointF& TouchSelectionController::GetStartPosition() const { 276 const gfx::PointF& TouchSelectionController::GetStartPosition() const {
336 return start_.edge_bottom(); 277 return start_.edge_bottom();
337 } 278 }
338 279
339 const gfx::PointF& TouchSelectionController::GetEndPosition() const { 280 const gfx::PointF& TouchSelectionController::GetEndPosition() const {
340 return end_.edge_bottom(); 281 return end_.edge_bottom();
341 } 282 }
342 283
343 bool TouchSelectionController::WillHandleTouchEventImpl( 284 bool TouchSelectionController::WillHandleTouchEventImpl(
344 const MotionEvent& event) { 285 const MotionEvent& event) {
286 show_touch_handles_ = true;
345 if (config_.enable_longpress_drag_selection && 287 if (config_.enable_longpress_drag_selection &&
346 longpress_drag_selector_.WillHandleTouchEvent(event)) { 288 longpress_drag_selector_.WillHandleTouchEvent(event)) {
347 return true; 289 return true;
348 } 290 }
349 291
350 if (active_status_ == INSERTION_ACTIVE) { 292 if (active_status_ == INSERTION_ACTIVE) {
351 DCHECK(insertion_handle_); 293 DCHECK(insertion_handle_);
352 return insertion_handle_->WillHandleTouchEvent(event); 294 return insertion_handle_->WillHandleTouchEvent(event);
353 } 295 }
354 296
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 411 }
470 412
471 gfx::PointF TouchSelectionController::GetSelectionStart() const { 413 gfx::PointF TouchSelectionController::GetSelectionStart() const {
472 return GetStartPosition(); 414 return GetStartPosition();
473 } 415 }
474 416
475 gfx::PointF TouchSelectionController::GetSelectionEnd() const { 417 gfx::PointF TouchSelectionController::GetSelectionEnd() const {
476 return GetEndPosition(); 418 return GetEndPosition();
477 } 419 }
478 420
479 void TouchSelectionController::ShowInsertionHandleAutomatically() {
480 if (activate_insertion_automatically_)
481 return;
482 activate_insertion_automatically_ = true;
483 ForceNextUpdateIfInactive();
484 }
485
486 void TouchSelectionController::ShowSelectionHandlesAutomatically() {
487 if (activate_selection_automatically_)
488 return;
489 activate_selection_automatically_ = true;
490 ForceNextUpdateIfInactive();
491 }
492
493 bool TouchSelectionController::WillHandleTapOrLongPress(
494 const gfx::PointF& location) {
495 // If there is an active selection that was not triggered by a user gesture,
496 // allow showing the handles for that selection if a gesture occurs within
497 // the selection rect. Note that this hit test is at best a crude
498 // approximation, and may swallow taps that actually fall outside the
499 // real selection.
500 if (active_status_ == INACTIVE &&
501 GetStartPosition() != GetEndPosition() &&
502 RectFBetweenSelectionBounds(start_, end_).Contains(location)) {
503 AllowShowingFromCurrentSelection();
504 return true;
505 }
506 return false;
507 }
508
509 void TouchSelectionController::OnInsertionChanged() { 421 void TouchSelectionController::OnInsertionChanged() {
510 DeactivateSelection(); 422 DeactivateSelection();
511 423
512 if ((response_pending_input_event_ == TAP ||
513 response_pending_input_event_ == REPEATED_TAP) &&
514 selection_empty_) {
515 HideAndDisallowShowingAutomatically();
516 return;
517 }
518
519 if (!activate_insertion_automatically_)
520 return;
521
522 const bool activated = ActivateInsertionIfNecessary(); 424 const bool activated = ActivateInsertionIfNecessary();
523 425
524 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated); 426 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);
525 insertion_handle_->SetFocus(start_.edge_top(), start_.edge_bottom()); 427 insertion_handle_->SetFocus(start_.edge_top(), start_.edge_bottom());
526 insertion_handle_->SetVisible(GetStartVisible(), animation); 428 insertion_handle_->SetVisible(GetStartVisible(), animation);
527 429
528 UpdateHandleLayoutIfNecessary(); 430 UpdateHandleLayoutIfNecessary();
529 431
530 client_->OnSelectionEvent(activated ? INSERTION_HANDLE_SHOWN 432 client_->OnSelectionEvent(activated ? INSERTION_HANDLE_SHOWN
531 : INSERTION_HANDLE_MOVED); 433 : INSERTION_HANDLE_MOVED);
532 } 434 }
533 435
534 void TouchSelectionController::OnSelectionChanged() { 436 void TouchSelectionController::OnSelectionChanged() {
535 DeactivateInsertion(); 437 DeactivateInsertion();
536 438
537 if (!activate_selection_automatically_)
538 return;
539
540 const bool activated = ActivateSelectionIfNecessary(); 439 const bool activated = ActivateSelectionIfNecessary();
541 440
542 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated); 441 const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);
543 442
544 start_selection_handle_->SetFocus(start_.edge_top(), start_.edge_bottom()); 443 start_selection_handle_->SetFocus(start_.edge_top(), start_.edge_bottom());
545 end_selection_handle_->SetFocus(end_.edge_top(), end_.edge_bottom()); 444 end_selection_handle_->SetFocus(end_.edge_top(), end_.edge_bottom());
546 445
547 start_selection_handle_->SetOrientation(start_orientation_); 446 start_selection_handle_->SetOrientation(start_orientation_);
548 end_selection_handle_->SetOrientation(end_orientation_); 447 end_selection_handle_->SetOrientation(end_orientation_);
549 448
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 DCHECK(start_selection_handle_); 527 DCHECK(start_selection_handle_);
629 DCHECK(end_selection_handle_); 528 DCHECK(end_selection_handle_);
630 LogSelectionEnd(); 529 LogSelectionEnd();
631 longpress_drag_selector_.OnSelectionDeactivated(); 530 longpress_drag_selector_.OnSelectionDeactivated();
632 start_selection_handle_->SetEnabled(false); 531 start_selection_handle_->SetEnabled(false);
633 end_selection_handle_->SetEnabled(false); 532 end_selection_handle_->SetEnabled(false);
634 active_status_ = INACTIVE; 533 active_status_ = INACTIVE;
635 client_->OnSelectionEvent(SELECTION_HANDLES_CLEARED); 534 client_->OnSelectionEvent(SELECTION_HANDLES_CLEARED);
636 } 535 }
637 536
638 void TouchSelectionController::ForceNextUpdateIfInactive() {
639 // Only force the update if the reported selection is non-empty but still
640 // considered "inactive", i.e., it wasn't preceded by a user gesture or
641 // the handles have since been explicitly hidden.
642 if (active_status_ == INACTIVE &&
643 start_.type() != gfx::SelectionBound::EMPTY &&
644 end_.type() != gfx::SelectionBound::EMPTY) {
645 force_next_update_ = true;
646 }
647 }
648
649 void TouchSelectionController::UpdateHandleLayoutIfNecessary() { 537 void TouchSelectionController::UpdateHandleLayoutIfNecessary() {
650 if (active_status_ == INSERTION_ACTIVE) { 538 if (active_status_ == INSERTION_ACTIVE) {
651 DCHECK(insertion_handle_); 539 DCHECK(insertion_handle_);
652 insertion_handle_->UpdateHandleLayout(); 540 insertion_handle_->UpdateHandleLayout();
653 } else if (active_status_ == SELECTION_ACTIVE) { 541 } else if (active_status_ == SELECTION_ACTIVE) {
654 DCHECK(start_selection_handle_); 542 DCHECK(start_selection_handle_);
655 DCHECK(end_selection_handle_); 543 DCHECK(end_selection_handle_);
656 start_selection_handle_->UpdateHandleLayout(); 544 start_selection_handle_->UpdateHandleLayout();
657 end_selection_handle_->UpdateHandleLayout(); 545 end_selection_handle_->UpdateHandleLayout();
658 } 546 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_; 597 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
710 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration", 598 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration",
711 duration, 599 duration,
712 base::TimeDelta::FromMilliseconds(500), 600 base::TimeDelta::FromMilliseconds(500),
713 base::TimeDelta::FromSeconds(60), 601 base::TimeDelta::FromSeconds(60),
714 60); 602 60);
715 } 603 }
716 } 604 }
717 605
718 } // namespace ui 606 } // namespace ui
OLDNEW
« no previous file with comments | « ui/touch_selection/touch_selection_controller.h ('k') | ui/touch_selection/touch_selection_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698