1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/debug/trace_event.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input_messages.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/render_widget_host.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyntheticGestureController::SyntheticGestureController(
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SyntheticGestureTarget> gesture_target)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : gesture_target_(gesture_target.Pass()) {}
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SyntheticGestureController::~SyntheticGestureController() {}
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyntheticGestureController::QueueSyntheticGesture(
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<SyntheticGesture> synthetic_gesture,
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const OnGestureCompleteCallback& completion_callback) {
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(synthetic_gesture);
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool was_empty = pending_gesture_queue_.IsEmpty();
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pending_gesture_queue_.Push(synthetic_gesture.Pass(), completion_callback);
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (was_empty)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    StartGesture(*pending_gesture_queue_.FrontGesture());
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyntheticGestureController::Flush(base::TimeTicks timestamp) {
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0("input", "SyntheticGestureController::Flush");
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (pending_gesture_queue_.IsEmpty())
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (pending_gesture_result_)
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SyntheticGesture* gesture = pending_gesture_queue_.FrontGesture();
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SyntheticGesture::Result result =
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      gesture->ForwardInputEvents(timestamp, gesture_target_.get());
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (result == SyntheticGesture::GESTURE_RUNNING) {
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_target_->SetNeedsFlush();
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // It's possible that all events generated by the gesture have been fully
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // dispatched at this point, in which case |OnDidFlushInput()| was called
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // before |pending_gesture_result_| was initialized. Requesting another flush
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // will trigger the necessary gesture-ending call to |OnDidFlushInput()|.
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  pending_gesture_result_.reset(new SyntheticGesture::Result(result));
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  gesture_target_->SetNeedsFlush();
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SyntheticGestureController::OnDidFlushInput() {
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!pending_gesture_result_)
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(!pending_gesture_queue_.IsEmpty());
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  StopGesture(*pending_gesture_queue_.FrontGesture(),
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              pending_gesture_queue_.FrontCallback(),
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              *pending_gesture_result_.Pass());
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pending_gesture_queue_.Pop();
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!pending_gesture_queue_.IsEmpty())
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    StartGesture(*pending_gesture_queue_.FrontGesture());
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyntheticGestureController::StartGesture(const SyntheticGesture& gesture) {
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT_ASYNC_BEGIN0("input,benchmark",
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           "SyntheticGestureController::running",
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           &gesture);
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gesture_target_->SetNeedsFlush();
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SyntheticGestureController::StopGesture(
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const SyntheticGesture& gesture,
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const OnGestureCompleteCallback& completion_callback,
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SyntheticGesture::Result result) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_NE(result, SyntheticGesture::GESTURE_RUNNING);
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT_ASYNC_END0("input,benchmark",
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         "SyntheticGestureController::running",
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         &gesture);
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  completion_callback.Run(result);
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SyntheticGestureController::GestureAndCallbackQueue::GestureAndCallbackQueue() {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SyntheticGestureController::GestureAndCallbackQueue::
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ~GestureAndCallbackQueue() {
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
100