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

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

Issue 1087893003: Support longpress drag selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 7 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 10
(...skipping 29 matching lines...) Expand all
40 40
41 } // namespace 41 } // namespace
42 42
43 TouchSelectionController::TouchSelectionController( 43 TouchSelectionController::TouchSelectionController(
44 TouchSelectionControllerClient* client, 44 TouchSelectionControllerClient* client,
45 base::TimeDelta tap_timeout, 45 base::TimeDelta tap_timeout,
46 float tap_slop, 46 float tap_slop,
47 bool show_on_tap_for_empty_editable) 47 bool show_on_tap_for_empty_editable)
48 : client_(client), 48 : client_(client),
49 tap_timeout_(tap_timeout), 49 tap_timeout_(tap_timeout),
50 tap_slop_(tap_slop), 50 tap_slop_squared_(static_cast<double>(tap_slop) * tap_slop),
51 force_next_update_(false), 51 force_next_update_(false),
52 show_on_tap_for_empty_editable_(show_on_tap_for_empty_editable), 52 show_on_tap_for_empty_editable_(show_on_tap_for_empty_editable),
53 response_pending_input_event_(INPUT_EVENT_TYPE_NONE), 53 response_pending_input_event_(INPUT_EVENT_TYPE_NONE),
54 start_orientation_(TouchHandleOrientation::UNDEFINED), 54 start_orientation_(TouchHandleOrientation::UNDEFINED),
55 end_orientation_(TouchHandleOrientation::UNDEFINED), 55 end_orientation_(TouchHandleOrientation::UNDEFINED),
56 active_status_(INACTIVE), 56 active_status_(INACTIVE),
57 activate_insertion_automatically_(false), 57 activate_insertion_automatically_(false),
58 activate_selection_automatically_(false), 58 activate_selection_automatically_(false),
59 selection_empty_(false), 59 selection_empty_(false),
60 selection_editable_(false), 60 selection_editable_(false),
61 temporarily_hidden_(false), 61 temporarily_hidden_(false),
62 longpress_drag_selector_(this),
62 selection_handle_dragged_(false) { 63 selection_handle_dragged_(false) {
63 DCHECK(client_); 64 DCHECK(client_);
64 } 65 }
65 66
66 TouchSelectionController::~TouchSelectionController() { 67 TouchSelectionController::~TouchSelectionController() {
67 } 68 }
68 69
69 void TouchSelectionController::OnSelectionBoundsChanged( 70 void TouchSelectionController::OnSelectionBoundsChanged(
70 const SelectionBound& start, 71 const SelectionBound& start,
71 const SelectionBound& end) { 72 const SelectionBound& end) {
(...skipping 15 matching lines...) Expand all
87 88
88 // Ensure that |response_pending_input_event_| is cleared after the method 89 // Ensure that |response_pending_input_event_| is cleared after the method
89 // completes, while also making its current value available for the duration 90 // completes, while also making its current value available for the duration
90 // of the call. 91 // of the call.
91 InputEventType causal_input_event = response_pending_input_event_; 92 InputEventType causal_input_event = response_pending_input_event_;
92 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 93 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
93 base::AutoReset<InputEventType> auto_reset_response_pending_input_event( 94 base::AutoReset<InputEventType> auto_reset_response_pending_input_event(
94 &response_pending_input_event_, causal_input_event); 95 &response_pending_input_event_, causal_input_event);
95 96
96 const bool is_selection_dragging = active_status_ == SELECTION_ACTIVE && 97 const bool is_selection_dragging = active_status_ == SELECTION_ACTIVE &&
97 (start_selection_handle_->is_dragging() || 98 (start_selection_handle_->IsActive() ||
98 end_selection_handle_->is_dragging()); 99 end_selection_handle_->IsActive());
99 100
100 // It's possible that the bounds temporarily overlap while a selection handle 101 // It's possible that the bounds temporarily overlap while a selection handle
101 // is being dragged, incorrectly reporting a CENTER orientation. 102 // is being dragged, incorrectly reporting a CENTER orientation.
102 // TODO(jdduke): This safeguard is racy, as it's possible the delayed response 103 // TODO(jdduke): This safeguard is racy, as it's possible the delayed response
103 // from handle positioning occurs *after* the handle dragging has ceased. 104 // from handle positioning occurs *after* the handle dragging has ceased.
104 // Instead, prevent selection -> insertion transitions without an intervening 105 // Instead, prevent selection -> insertion transitions without an intervening
105 // action or selection clearing of some sort, crbug.com/392696. 106 // action or selection clearing of some sort, crbug.com/392696.
106 if (is_selection_dragging) { 107 if (is_selection_dragging) {
107 if (start_orientation_ == TouchHandleOrientation::CENTER) 108 if (start_orientation_ == TouchHandleOrientation::CENTER)
108 start_orientation_ = start_selection_handle_->orientation(); 109 start_orientation_ = start_selection_handle_->orientation();
(...skipping 12 matching lines...) Expand all
121 if (start_orientation_ == TouchHandleOrientation::CENTER && 122 if (start_orientation_ == TouchHandleOrientation::CENTER &&
122 selection_editable_) { 123 selection_editable_) {
123 OnInsertionChanged(); 124 OnInsertionChanged();
124 return; 125 return;
125 } 126 }
126 127
127 HideAndDisallowShowingAutomatically(); 128 HideAndDisallowShowingAutomatically();
128 } 129 }
129 130
130 bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) { 131 bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) {
132 if (longpress_drag_selector_.WillHandleTouchEvent(event))
133 return true;
134
131 if (active_status_ == INSERTION_ACTIVE) { 135 if (active_status_ == INSERTION_ACTIVE) {
132 DCHECK(insertion_handle_); 136 DCHECK(insertion_handle_);
133 return insertion_handle_->WillHandleTouchEvent(event); 137 return insertion_handle_->WillHandleTouchEvent(event);
134 } 138 }
135 139
136 if (active_status_ == SELECTION_ACTIVE) { 140 if (active_status_ == SELECTION_ACTIVE) {
137 DCHECK(start_selection_handle_); 141 DCHECK(start_selection_handle_);
138 DCHECK(end_selection_handle_); 142 DCHECK(end_selection_handle_);
139 if (start_selection_handle_->is_dragging()) 143 if (start_selection_handle_->IsActive())
140 return start_selection_handle_->WillHandleTouchEvent(event); 144 return start_selection_handle_->WillHandleTouchEvent(event);
141 145
142 if (end_selection_handle_->is_dragging()) 146 if (end_selection_handle_->IsActive())
143 return end_selection_handle_->WillHandleTouchEvent(event); 147 return end_selection_handle_->WillHandleTouchEvent(event);
144 148
145 const gfx::PointF event_pos(event.GetX(), event.GetY()); 149 const gfx::PointF event_pos(event.GetX(), event.GetY());
146 if ((event_pos - GetStartPosition()).LengthSquared() <= 150 if ((event_pos - GetStartPosition()).LengthSquared() <=
147 (event_pos - GetEndPosition()).LengthSquared()) { 151 (event_pos - GetEndPosition()).LengthSquared()) {
148 return start_selection_handle_->WillHandleTouchEvent(event); 152 return start_selection_handle_->WillHandleTouchEvent(event);
149 } 153 }
150 return end_selection_handle_->WillHandleTouchEvent(event); 154 return end_selection_handle_->WillHandleTouchEvent(event);
151 } 155 }
152 156
153 return false; 157 return false;
154 } 158 }
155 159
156 void TouchSelectionController::OnLongPressEvent() { 160 void TouchSelectionController::OnLongPressEvent(base::TimeTicks event_time,
161 const gfx::PointF& position) {
162 longpress_drag_selector_.OnLongPressEvent(event_time, position);
157 response_pending_input_event_ = LONG_PRESS; 163 response_pending_input_event_ = LONG_PRESS;
158 ShowSelectionHandlesAutomatically(); 164 ShowSelectionHandlesAutomatically();
159 ShowInsertionHandleAutomatically(); 165 ShowInsertionHandleAutomatically();
160 ForceNextUpdateIfInactive(); 166 ForceNextUpdateIfInactive();
161 } 167 }
162 168
163 void TouchSelectionController::AllowShowingFromCurrentSelection() { 169 void TouchSelectionController::AllowShowingFromCurrentSelection() {
164 if (active_status_ != INACTIVE) 170 if (active_status_ != INACTIVE)
165 return; 171 return;
166 172
(...skipping 22 matching lines...) Expand all
189 DeactivateInsertion(); 195 DeactivateInsertion();
190 DeactivateSelection(); 196 DeactivateSelection();
191 activate_insertion_automatically_ = false; 197 activate_insertion_automatically_ = false;
192 activate_selection_automatically_ = false; 198 activate_selection_automatically_ = false;
193 } 199 }
194 200
195 void TouchSelectionController::SetTemporarilyHidden(bool hidden) { 201 void TouchSelectionController::SetTemporarilyHidden(bool hidden) {
196 if (temporarily_hidden_ == hidden) 202 if (temporarily_hidden_ == hidden)
197 return; 203 return;
198 temporarily_hidden_ = hidden; 204 temporarily_hidden_ = hidden;
199 205 RefreshHandleVisibility();
200 TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true);
201 if (active_status_ == SELECTION_ACTIVE) {
202 start_selection_handle_->SetVisible(GetStartVisible(), animation_style);
203 end_selection_handle_->SetVisible(GetEndVisible(), animation_style);
204 } else if (active_status_ == INSERTION_ACTIVE) {
205 insertion_handle_->SetVisible(GetStartVisible(), animation_style);
206 }
207 } 206 }
208 207
209 void TouchSelectionController::OnSelectionEditable(bool editable) { 208 void TouchSelectionController::OnSelectionEditable(bool editable) {
210 if (selection_editable_ == editable) 209 if (selection_editable_ == editable)
211 return; 210 return;
212 selection_editable_ = editable; 211 selection_editable_ = editable;
213 ForceNextUpdateIfInactive(); 212 ForceNextUpdateIfInactive();
214 if (!selection_editable_) 213 if (!selection_editable_)
215 DeactivateInsertion(); 214 DeactivateInsertion();
216 } 215 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 266 }
268 267
269 const gfx::PointF& TouchSelectionController::GetStartPosition() const { 268 const gfx::PointF& TouchSelectionController::GetStartPosition() const {
270 return start_.edge_bottom(); 269 return start_.edge_bottom();
271 } 270 }
272 271
273 const gfx::PointF& TouchSelectionController::GetEndPosition() const { 272 const gfx::PointF& TouchSelectionController::GetEndPosition() const {
274 return end_.edge_bottom(); 273 return end_.edge_bottom();
275 } 274 }
276 275
277 void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) { 276 bool TouchSelectionController::GetStartVisibleForTesting() const {
278 if (&handle == insertion_handle_.get()) { 277 return GetStartVisible();
278 }
279
280 bool TouchSelectionController::GetEndVisibleForTesting() const {
281 return GetEndVisible();
282 }
283
284 void TouchSelectionController::OnDragBegin(
285 const TouchSelectionDraggable& draggable,
286 const gfx::PointF& drag_position) {
287 if (&draggable == insertion_handle_.get()) {
288 DCHECK_EQ(active_status_, INSERTION_ACTIVE);
279 client_->OnSelectionEvent(INSERTION_DRAG_STARTED); 289 client_->OnSelectionEvent(INSERTION_DRAG_STARTED);
290 drag_line_offset_ = GetStartLineOffset();
280 return; 291 return;
281 } 292 }
282 293
283 gfx::PointF base, extent; 294 DCHECK_EQ(active_status_, SELECTION_ACTIVE);
284 if (&handle == start_selection_handle_.get()) { 295
285 base = end_selection_handle_->position() + GetEndLineOffset(); 296 bool extend_selection_start = false;
286 extent = start_selection_handle_->position() + GetStartLineOffset(); 297 if (&draggable == start_selection_handle_.get()) {
298 extend_selection_start = true;
299 } else if (&draggable == end_selection_handle_.get()) {
300 extend_selection_start = false;
287 } else { 301 } else {
288 base = start_selection_handle_->position() + GetStartLineOffset(); 302 DCHECK_EQ(&draggable, &longpress_drag_selector_);
289 extent = end_selection_handle_->position() + GetEndLineOffset(); 303 extend_selection_start =
304 (drag_position - GetStartPosition()).LengthSquared() <
305 (drag_position - GetEndPosition()).LengthSquared();
290 } 306 }
307
308 gfx::PointF base = GetStartPosition() + GetStartLineOffset();
309 gfx::PointF extent = GetEndPosition() + GetEndLineOffset();
310 if (extend_selection_start) {
311 std::swap(base, extent);
312 drag_line_offset_ = GetStartLineOffset();
313 } else {
314 drag_line_offset_ = GetEndLineOffset();
315 }
316
291 selection_handle_dragged_ = true; 317 selection_handle_dragged_ = true;
292 318
293 // When moving the handle we want to move only the extent point. Before doing 319 // When moving the handle we want to move only the extent point. Before doing
294 // so we must make sure that the base point is set correctly. 320 // so we must make sure that the base point is set correctly.
295 client_->SelectBetweenCoordinates(base, extent); 321 client_->SelectBetweenCoordinates(base, extent);
296 client_->OnSelectionEvent(SELECTION_DRAG_STARTED); 322 client_->OnSelectionEvent(SELECTION_DRAG_STARTED);
297 } 323 }
298 324
299 void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle, 325 void TouchSelectionController::OnDragUpdate(
300 const gfx::PointF& position) { 326 const TouchSelectionDraggable& draggable,
327 const gfx::PointF& drag_position) {
301 // As the position corresponds to the bottom left point of the selection 328 // As the position corresponds to the bottom left point of the selection
302 // bound, offset it by half the corresponding line height. 329 // bound, offset it by half the corresponding line height.
303 gfx::Vector2dF line_offset = &handle == start_selection_handle_.get() 330 gfx::PointF line_position = drag_position + drag_line_offset_;
304 ? GetStartLineOffset() 331 if (&draggable == insertion_handle_.get())
305 : GetEndLineOffset();
306 gfx::PointF line_position = position + line_offset;
307 if (&handle == insertion_handle_.get())
308 client_->MoveCaret(line_position); 332 client_->MoveCaret(line_position);
309 else 333 else
310 client_->MoveRangeSelectionExtent(line_position); 334 client_->MoveRangeSelectionExtent(line_position);
311 } 335 }
312 336
313 void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) { 337 void TouchSelectionController::OnDragEnd(
314 if (&handle == insertion_handle_.get()) 338 const TouchSelectionDraggable& draggable) {
339 if (&draggable == insertion_handle_.get())
315 client_->OnSelectionEvent(INSERTION_DRAG_STOPPED); 340 client_->OnSelectionEvent(INSERTION_DRAG_STOPPED);
316 else 341 else
317 client_->OnSelectionEvent(SELECTION_DRAG_STOPPED); 342 client_->OnSelectionEvent(SELECTION_DRAG_STOPPED);
318 } 343 }
319 344
345 bool TouchSelectionController::IsWithinTapSlop(
346 const gfx::Vector2dF& delta) const {
347 return delta.LengthSquared() < tap_slop_squared_;
348 }
349
320 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) { 350 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) {
321 if (insertion_handle_ && &handle == insertion_handle_.get()) 351 if (insertion_handle_ && &handle == insertion_handle_.get())
322 client_->OnSelectionEvent(INSERTION_TAPPED); 352 client_->OnSelectionEvent(INSERTION_TAPPED);
323 } 353 }
324 354
325 void TouchSelectionController::SetNeedsAnimate() { 355 void TouchSelectionController::SetNeedsAnimate() {
326 client_->SetNeedsAnimate(); 356 client_->SetNeedsAnimate();
327 } 357 }
328 358
329 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() { 359 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() {
330 return client_->CreateDrawable(); 360 return client_->CreateDrawable();
331 } 361 }
332 362
333 base::TimeDelta TouchSelectionController::GetTapTimeout() const { 363 base::TimeDelta TouchSelectionController::GetTapTimeout() const {
334 return tap_timeout_; 364 return tap_timeout_;
335 } 365 }
336 366
337 float TouchSelectionController::GetTapSlop() const { 367 void TouchSelectionController::OnLongPressDragActiveStateChanged() {
338 return tap_slop_; 368 // The handles should remain hidden for the duration of a longpress drag,
369 // including the time between a longpress and the start of drag motion.
370 RefreshHandleVisibility();
371 }
372
373 gfx::PointF TouchSelectionController::GetSelectionStart() const {
374 return GetStartPosition();
375 }
376
377 gfx::PointF TouchSelectionController::GetSelectionEnd() const {
378 return GetEndPosition();
339 } 379 }
340 380
341 void TouchSelectionController::ShowInsertionHandleAutomatically() { 381 void TouchSelectionController::ShowInsertionHandleAutomatically() {
342 if (activate_insertion_automatically_) 382 if (activate_insertion_automatically_)
343 return; 383 return;
344 activate_insertion_automatically_ = true; 384 activate_insertion_automatically_ = true;
345 ForceNextUpdateIfInactive(); 385 ForceNextUpdateIfInactive();
346 } 386 }
347 387
348 void TouchSelectionController::ShowSelectionHandlesAutomatically() { 388 void TouchSelectionController::ShowSelectionHandlesAutomatically() {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 if (active_status_ == INACTIVE || 482 if (active_status_ == INACTIVE ||
443 response_pending_input_event_ == LONG_PRESS) { 483 response_pending_input_event_ == LONG_PRESS) {
444 if (active_status_ == SELECTION_ACTIVE) { 484 if (active_status_ == SELECTION_ACTIVE) {
445 // The active selection session finishes with the start of the new one. 485 // The active selection session finishes with the start of the new one.
446 LogSelectionEnd(); 486 LogSelectionEnd();
447 } 487 }
448 active_status_ = SELECTION_ACTIVE; 488 active_status_ = SELECTION_ACTIVE;
449 selection_handle_dragged_ = false; 489 selection_handle_dragged_ = false;
450 selection_start_time_ = base::TimeTicks::Now(); 490 selection_start_time_ = base::TimeTicks::Now();
451 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE; 491 response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
492 longpress_drag_selector_.OnSelectionActivated();
452 client_->OnSelectionEvent(SELECTION_SHOWN); 493 client_->OnSelectionEvent(SELECTION_SHOWN);
453 } 494 }
454 } 495 }
455 496
456 void TouchSelectionController::DeactivateSelection() { 497 void TouchSelectionController::DeactivateSelection() {
457 if (active_status_ != SELECTION_ACTIVE) 498 if (active_status_ != SELECTION_ACTIVE)
458 return; 499 return;
459 DCHECK(start_selection_handle_); 500 DCHECK(start_selection_handle_);
460 DCHECK(end_selection_handle_); 501 DCHECK(end_selection_handle_);
461 LogSelectionEnd(); 502 LogSelectionEnd();
503 longpress_drag_selector_.OnSelectionDeactivated();
462 start_selection_handle_->SetEnabled(false); 504 start_selection_handle_->SetEnabled(false);
463 end_selection_handle_->SetEnabled(false); 505 end_selection_handle_->SetEnabled(false);
464 active_status_ = INACTIVE; 506 active_status_ = INACTIVE;
465 client_->OnSelectionEvent(SELECTION_CLEARED); 507 client_->OnSelectionEvent(SELECTION_CLEARED);
466 } 508 }
467 509
468 void TouchSelectionController::ForceNextUpdateIfInactive() { 510 void TouchSelectionController::ForceNextUpdateIfInactive() {
469 if (active_status_ == INACTIVE) 511 if (active_status_ == INACTIVE)
470 force_next_update_ = true; 512 force_next_update_ = true;
471 } 513 }
472 514
515 void TouchSelectionController::RefreshHandleVisibility() {
516 TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true);
517 if (active_status_ == SELECTION_ACTIVE) {
518 start_selection_handle_->SetVisible(GetStartVisible(), animation_style);
519 end_selection_handle_->SetVisible(GetEndVisible(), animation_style);
520 }
521 if (active_status_ == INSERTION_ACTIVE)
522 insertion_handle_->SetVisible(GetStartVisible(), animation_style);
523 }
524
473 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const { 525 gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const {
474 return ComputeLineOffsetFromBottom(start_); 526 return ComputeLineOffsetFromBottom(start_);
475 } 527 }
476 528
477 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const { 529 gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const {
478 return ComputeLineOffsetFromBottom(end_); 530 return ComputeLineOffsetFromBottom(end_);
479 } 531 }
480 532
481 bool TouchSelectionController::GetStartVisible() const { 533 bool TouchSelectionController::GetStartVisible() const {
482 return start_.visible() && !temporarily_hidden_; 534 if (!start_.visible())
535 return false;
536
537 return !temporarily_hidden_ && !longpress_drag_selector_.IsActive();
483 } 538 }
484 539
485 bool TouchSelectionController::GetEndVisible() const { 540 bool TouchSelectionController::GetEndVisible() const {
486 return end_.visible() && !temporarily_hidden_; 541 if (!end_.visible())
542 return false;
543
544 return !temporarily_hidden_ && !longpress_drag_selector_.IsActive();
487 } 545 }
488 546
489 TouchHandle::AnimationStyle TouchSelectionController::GetAnimationStyle( 547 TouchHandle::AnimationStyle TouchSelectionController::GetAnimationStyle(
490 bool was_active) const { 548 bool was_active) const {
491 return was_active && client_->SupportsAnimation() 549 return was_active && client_->SupportsAnimation()
492 ? TouchHandle::ANIMATION_SMOOTH 550 ? TouchHandle::ANIMATION_SMOOTH
493 : TouchHandle::ANIMATION_NONE; 551 : TouchHandle::ANIMATION_NONE;
494 } 552 }
495 553
496 void TouchSelectionController::LogSelectionEnd() { 554 void TouchSelectionController::LogSelectionEnd() {
497 // TODO(mfomitchev): Once we are able to tell the difference between 555 // TODO(mfomitchev): Once we are able to tell the difference between
498 // 'successful' and 'unsuccessful' selections - log 556 // 'successful' and 'unsuccessful' selections - log
499 // Event.TouchSelection.Duration instead and get rid of 557 // Event.TouchSelection.Duration instead and get rid of
500 // Event.TouchSelectionD.WasDraggeduration. 558 // Event.TouchSelectionD.WasDraggeduration.
501 if (selection_handle_dragged_) { 559 if (selection_handle_dragged_) {
502 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_; 560 base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
503 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration", 561 UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration",
504 duration, 562 duration,
505 base::TimeDelta::FromMilliseconds(500), 563 base::TimeDelta::FromMilliseconds(500),
506 base::TimeDelta::FromSeconds(60), 564 base::TimeDelta::FromSeconds(60),
507 60); 565 60);
508 } 566 }
509 } 567 }
510 568
511 } // namespace ui 569 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698