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

Side by Side Diff: content/browser/renderer_host/input/input_queue.cc

Issue 19220002: [WIP] BufferedInputRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix client assignment Created 7 years, 3 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
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/input/input_queue.h"
6
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "content/browser/renderer_host/input/browser_input_event.h"
10 #include "content/browser/renderer_host/input/input_queue_client.h"
11 #include "content/common/input/event_packet.h"
12 #include "content/common/input/input_event.h"
13
14 namespace content {
15
16 // A specialized EventPacket with utility methods for dispatched event handling.
17 class InputQueue::BrowserEventPacket : public EventPacket {
18 public:
19 typedef ScopedVector<BrowserInputEvent> BrowserInputEvents;
20
21 BrowserEventPacket() : weak_factory_(this) {}
22 virtual ~BrowserEventPacket() {}
23
24 // Validate the response and signal dispatch to the processed events.
25 // Undelivered events will be re-enqueued, and any generated followup events
26 // will be inserted at the same relative order as their generating event.
27 AckResult ValidateAndDispatchAck(int64 packet_id,
28 const InputEventDispositions& dispositions) {
29 if (!Validate(packet_id, dispositions))
30 return ACK_INVALID;
31
32 // Empty the packet; events will be re-enqueued as necessary.
33 InputEvents dispatched_events;
34 events_.swap(dispatched_events);
35
36 // The packet could be deleted as a result of event dispatch; use a local
37 // weak ref to ensure proper shutdown.
38 base::WeakPtr<EventPacket> weak_ref_this = weak_factory_.GetWeakPtr();
39
40 BrowserInputEvents followup_events;
41 for (size_t i = 0; i < dispatched_events.size(); ++i) {
42 // Take ownership of the event.
43 scoped_ptr<BrowserInputEvent> event(
44 static_cast<BrowserInputEvent*>(dispatched_events[i]));
45 dispatched_events[i] = NULL;
46
47 // Re-enqueue undelivered events.
48 InputEventDisposition disposition = dispositions[i];
49 if (disposition == INPUT_EVENT_COULD_NOT_DELIVER) {
50 Add(event.PassAs<InputEvent>());
51 continue;
52 }
53
54 event->OnDispatched(disposition, &followup_events);
55
56 // TODO(jdduke): http://crbug.com/274029
57 if (!weak_ref_this.get())
58 return ACK_SHUTDOWN;
59
60 AddAll(&followup_events);
61 }
62 return ACK_OK;
63 }
64
65 protected:
66 // Add and take ownership of events in |followup_events|.
67 void AddAll(BrowserInputEvents* followup_events) {
68 for (BrowserInputEvents::iterator iter = followup_events->begin();
69 iter != followup_events->end();
70 ++iter) {
71 Add(scoped_ptr<InputEvent>(*iter));
72 }
73 followup_events->weak_clear();
74 }
75
76 // Perform a sanity check of the ack against the current packet.
77 // |packet_id| should match that of this packet, and |dispositions| should
78 // be of size equal to the number of events in this packet.
79 bool Validate(int64 packet_id,
80 const InputEventDispositions& dispositions) const {
81 if (packet_id != id())
82 return false;
83
84 if (dispositions.size() != size())
85 return false;
86
87 return true;
88 }
89
90 private:
91 base::WeakPtrFactory<EventPacket> weak_factory_;
92 };
93
94 InputQueue::InputQueue(InputQueueClient* client)
95 : client_(client),
96 next_packet_id_(1),
97 flush_requested_(false),
98 in_flush_packet_(new BrowserEventPacket()),
99 pending_flush_packet_(new BrowserEventPacket()) {
100 DCHECK(client_);
101 }
102
103 InputQueue::~InputQueue() {}
104
105 void InputQueue::QueueEvent(scoped_ptr<BrowserInputEvent> event) {
106 DCHECK(event);
107 DCHECK(event->valid());
108 pending_flush_packet_->Add(event.PassAs<InputEvent>());
109 RequestFlushIfNecessary();
110 }
111
112 void InputQueue::BeginFlush() {
113 // Ignore repeated flush attempts.
114 if (!flush_requested_)
115 return;
116
117 DCHECK(!FlushInProgress());
118 DCHECK(!pending_flush_packet_->empty());
119
120 flush_requested_ = false;
121 in_flush_packet_.swap(pending_flush_packet_);
122 DeliverInFlushPacket();
123 }
124
125 InputQueue::AckResult InputQueue::OnEventPacketAck(
126 int64 packet_id,
127 const InputEventDispositions& dispositions) {
128 if (!FlushInProgress())
129 return ACK_UNEXPECTED;
130
131 TRACE_EVENT_ASYNC_STEP1("input", "InputQueueFlush", this, "AckPacket",
132 "id", packet_id);
133
134 AckResult ack_result =
135 in_flush_packet_->ValidateAndDispatchAck(packet_id, dispositions);
136
137 if (ack_result != ACK_OK)
138 return ack_result;
139
140 if (FlushInProgress()) {
141 DeliverInFlushPacket();
142 } else {
143 TRACE_EVENT_ASYNC_END0("input", "InputQueueFlush", this);
144 client_->DidFinishFlush();
145 RequestFlushIfNecessary();
146 }
147
148 return ACK_OK;
149 }
150
151 size_t InputQueue::QueuedEventCount() const {
152 return in_flush_packet_->size() + pending_flush_packet_->size();
153 }
154
155 void InputQueue::DeliverInFlushPacket() {
156 DCHECK(FlushInProgress());
157 TRACE_EVENT_ASYNC_STEP1("input", "InputQueueFlush", this, "DeliverPacket",
158 "id", next_packet_id_);
159 in_flush_packet_->set_id(next_packet_id_++);
160 client_->Deliver(*in_flush_packet_);
161 }
162
163 void InputQueue::RequestFlushIfNecessary() {
164 if (flush_requested_)
165 return;
166
167 // Defer flush requests until the current flush has finished.
168 if (FlushInProgress())
169 return;
170
171 // No additional events to flush.
172 if (pending_flush_packet_->empty())
173 return;
174
175 TRACE_EVENT_ASYNC_BEGIN0("input", "InputQueueFlush", this);
176 TRACE_EVENT_ASYNC_STEP0("input", "InputQueueFlush", this, "Request");
177 flush_requested_ = true;
178 client_->SetNeedsFlush();
179 }
180
181 bool InputQueue::FlushInProgress() const { return !in_flush_packet_->empty(); }
182
183 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/input_queue.h ('k') | content/browser/renderer_host/input/input_queue_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698