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

Side by Side Diff: content/renderer/input/frame_input_handler_impl.cc

Issue 2884243003: Add a mojo channel for frame messages. (Closed)
Patch Set: Fix presubmit warning I ignored Created 3 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
« no previous file with comments | « content/renderer/input/frame_input_handler_impl.h ('k') | content/renderer/render_frame_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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/renderer/input/frame_input_handler_impl.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/debug/stack_trace.h"
11 #include "base/logging.h"
12 #include "content/renderer/ime_event_guard.h"
13 #include "content/renderer/render_thread_impl.h"
14 #include "content/renderer/render_view_impl.h"
15 #include "content/renderer/render_widget.h"
16 #include "third_party/WebKit/public/web/WebLocalFrame.h"
17
18 namespace content {
19
20 FrameInputHandlerImpl::FrameInputHandlerImpl(
21 base::WeakPtr<RenderFrameImpl> render_frame,
22 mojom::FrameInputHandlerRequest request)
23 : binding_(this),
24 render_frame_(render_frame),
25 input_event_queue_(render_frame->GetRenderWidget()->GetInputEventQueue()),
26 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
27 weak_ptr_factory_(this)
28
29 {
30 weak_this_ = weak_ptr_factory_.GetWeakPtr();
31 // If we have created an input event queue move the mojo request over to the
32 // compositor thread.
33 if (input_event_queue_) {
34 // Mojo channel bound on compositor thread.
35 RenderThreadImpl::current()->compositor_task_runner()->PostTask(
36 FROM_HERE, base::BindOnce(&FrameInputHandlerImpl::BindNow,
37 base::Unretained(this), std::move(request)));
38 } else {
39 // Mojo channel bound on main thread.
40 BindNow(std::move(request));
41 }
42 }
43
44 FrameInputHandlerImpl::~FrameInputHandlerImpl() {}
45
46 // static
47 void FrameInputHandlerImpl::CreateMojoService(
48 base::WeakPtr<RenderFrameImpl> render_frame,
49 const service_manager::BindSourceInfo& source_info,
50 mojom::FrameInputHandlerRequest request) {
51 DCHECK(render_frame);
52
53 // Owns itself. Will be deleted when message pipe is destroyed.
54 new FrameInputHandlerImpl(render_frame, std::move(request));
55 }
56
57 void FrameInputHandlerImpl::RunOnMainThread(const base::Closure& closure) {
58 if (input_event_queue_) {
59 input_event_queue_->QueueClosure(closure);
60 } else {
61 closure.Run();
62 }
63 }
64
65 void FrameInputHandlerImpl::SetCompositionFromExistingText(
66 int32_t start,
67 int32_t end,
68 const std::vector<ui::CompositionUnderline>& ui_underlines) {
69 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
70 RunOnMainThread(
71 base::Bind(&FrameInputHandlerImpl::SetCompositionFromExistingText,
72 weak_this_, start, end, ui_underlines));
73 return;
74 }
75
76 if (!render_frame_)
77 return;
78
79 ImeEventGuard guard(render_frame_->GetRenderWidget());
80 std::vector<blink::WebCompositionUnderline> underlines;
81 for (const auto& underline : ui_underlines) {
82 blink::WebCompositionUnderline blink_underline(
83 underline.start_offset, underline.end_offset, underline.color,
84 underline.thick, underline.background_color);
85 underlines.push_back(blink_underline);
86 }
87
88 render_frame_->GetWebFrame()->SetCompositionFromExistingText(start, end,
89 underlines);
90 }
91
92 void FrameInputHandlerImpl::ExtendSelectionAndDelete(int32_t before,
93 int32_t after) {
94 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
95 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExtendSelectionAndDelete,
96 weak_this_, before, after));
97 return;
98 }
99 if (!render_frame_)
100 return;
101 render_frame_->GetWebFrame()->ExtendSelectionAndDelete(before, after);
102 }
103
104 void FrameInputHandlerImpl::DeleteSurroundingText(int32_t before,
105 int32_t after) {
106 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
107 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::DeleteSurroundingText,
108 weak_this_, before, after));
109 return;
110 }
111 if (!render_frame_)
112 return;
113 render_frame_->GetWebFrame()->DeleteSurroundingText(before, after);
114 }
115
116 void FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints(int32_t before,
117 int32_t after) {
118 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
119 RunOnMainThread(
120 base::Bind(&FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints,
121 weak_this_, before, after));
122 return;
123 }
124 if (!render_frame_)
125 return;
126 render_frame_->GetWebFrame()->DeleteSurroundingTextInCodePoints(before,
127 after);
128 }
129
130 void FrameInputHandlerImpl::SetEditableSelectionOffsets(int32_t start,
131 int32_t end) {
132 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
133 RunOnMainThread(
134 base::Bind(&FrameInputHandlerImpl::SetEditableSelectionOffsets,
135 weak_this_, start, end));
136 return;
137 }
138 if (!render_frame_)
139 return;
140 render_frame_->GetWebFrame()->SetEditableSelectionOffsets(start, end);
141 }
142
143 void FrameInputHandlerImpl::ExecuteEditCommand(
144 const std::string& command,
145 const base::Optional<base::string16>& value) {
146 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
147 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteEditCommand,
148 weak_this_, command, value));
149 return;
150 }
151 if (!render_frame_)
152 return;
153 if (value) {
154 render_frame_->GetWebFrame()->ExecuteCommand(
155 blink::WebString::FromUTF8(command),
156 blink::WebString::FromUTF16(value.value()));
157 return;
158 }
159
160 render_frame_->GetWebFrame()->ExecuteCommand(
161 blink::WebString::FromUTF8(command));
162 }
163
164 void FrameInputHandlerImpl::Undo() {
165 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
166 weak_this_, "Undo", UpdateState::kNone));
167 }
168
169 void FrameInputHandlerImpl::Redo() {
170 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
171 weak_this_, "Redo", UpdateState::kNone));
172 }
173
174 void FrameInputHandlerImpl::Cut() {
175 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
176 weak_this_, "Cut",
177 UpdateState::kIsSelectingRange));
178 }
179
180 void FrameInputHandlerImpl::Copy() {
181 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
182 weak_this_, "Copy",
183 UpdateState::kIsSelectingRange));
184 }
185
186 void FrameInputHandlerImpl::CopyToFindPboard() {
187 #if defined(OS_MACOSX)
188 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
189 RunOnMainThread(
190 base::Bind(&FrameInputHandlerImpl::CopyToFindPboard, weak_this_));
191 return;
192 }
193 if (!render_frame_)
194 return;
195 render_frame_->OnCopyToFindPboard();
196 #endif
197 }
198
199 void FrameInputHandlerImpl::Paste() {
200 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
201 weak_this_, "Paste", UpdateState::kIsPasting));
202 }
203
204 void FrameInputHandlerImpl::PasteAndMatchStyle() {
205 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
206 weak_this_, "PasteAndMatchStyle",
207 UpdateState::kIsPasting));
208 }
209
210 void FrameInputHandlerImpl::Replace(const base::string16& word) {
211 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
212 RunOnMainThread(
213 base::Bind(&FrameInputHandlerImpl::Replace, weak_this_, word));
214 return;
215 }
216 if (!render_frame_)
217 return;
218 blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
219 if (frame->HasSelection())
220 frame->SelectWordAroundCaret();
221 frame->ReplaceSelection(blink::WebString::FromUTF16(word));
222 render_frame_->SyncSelectionIfRequired();
223 }
224
225 void FrameInputHandlerImpl::ReplaceMisspelling(const base::string16& word) {
226 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
227 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ReplaceMisspelling,
228 weak_this_, word));
229 return;
230 }
231 if (!render_frame_)
232 return;
233 blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
234 if (!frame->HasSelection())
235 return;
236 frame->ReplaceMisspelledRange(blink::WebString::FromUTF16(word));
237 }
238
239 void FrameInputHandlerImpl::Delete() {
240 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
241 weak_this_, "Delete", UpdateState::kNone));
242 }
243
244 void FrameInputHandlerImpl::SelectAll() {
245 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
246 weak_this_, "SelectAll",
247 UpdateState::kIsSelectingRange));
248 }
249
250 void FrameInputHandlerImpl::CollapseSelection() {
251 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
252 RunOnMainThread(
253 base::Bind(&FrameInputHandlerImpl::CollapseSelection, weak_this_));
254 return;
255 }
256
257 if (!render_frame_)
258 return;
259 const blink::WebRange& range =
260 render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
261 if (range.IsNull())
262 return;
263
264 HandlingState handling_state(render_frame_.get(),
265 UpdateState::kIsSelectingRange);
266 render_frame_->GetWebFrame()->SelectRange(
267 blink::WebRange(range.EndOffset(), 0));
268 }
269
270 void FrameInputHandlerImpl::SelectRange(const gfx::Point& base,
271 const gfx::Point& extent) {
272 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
273 // TODO(dtapuska): This event should be coalesced. Chrome IPC uses
274 // one outstanding event and an ACK to handle coalescing on the browser
275 // side. We should be able to clobber them in the main thread event queue.
276 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::SelectRange, weak_this_,
277 base, extent));
278 return;
279 }
280
281 if (!render_frame_)
282 return;
283 RenderViewImpl* render_view = render_frame_->render_view();
284 HandlingState handling_state(render_frame_.get(),
285 UpdateState::kIsSelectingRange);
286 render_frame_->GetWebFrame()->SelectRange(
287 render_view->ConvertWindowPointToViewport(base),
288 render_view->ConvertWindowPointToViewport(extent));
289 }
290
291 void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(int32_t start,
292 int32_t end) {
293 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
294 RunOnMainThread(
295 base::Bind(&FrameInputHandlerImpl::AdjustSelectionByCharacterOffset,
296 weak_this_, start, end));
297 return;
298 }
299
300 if (!render_frame_)
301 return;
302 blink::WebRange range =
303 render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
304 if (range.IsNull())
305 return;
306
307 // Sanity checks to disallow empty and out of range selections.
308 if (start - end > range.length() || range.StartOffset() + start < 0)
309 return;
310
311 HandlingState handling_state(render_frame_.get(),
312 UpdateState::kIsSelectingRange);
313 // A negative adjust amount moves the selection towards the beginning of
314 // the document, a positive amount moves the selection towards the end of
315 // the document.
316 render_frame_->GetWebFrame()->SelectRange(
317 blink::WebRange(range.StartOffset() + start,
318 range.length() + end - start),
319 blink::WebLocalFrame::kPreserveHandleVisibility);
320 }
321
322 void FrameInputHandlerImpl::MoveRangeSelectionExtent(const gfx::Point& extent) {
323 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
324 // TODO(dtapuska): This event should be coalesced. Chrome IPC uses
325 // one outstanding event and an ACK to handle coalescing on the browser
326 // side. We should be able to clobber them in the main thread event queue.
327 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::MoveRangeSelectionExtent,
328 weak_this_, extent));
329 return;
330 }
331
332 if (!render_frame_)
333 return;
334 HandlingState handling_state(render_frame_.get(),
335 UpdateState::kIsSelectingRange);
336 render_frame_->GetWebFrame()->MoveRangeSelectionExtent(
337 render_frame_->render_view()->ConvertWindowPointToViewport(extent));
338 }
339
340 void FrameInputHandlerImpl::ExecuteCommandOnMainThread(
341 const std::string& command,
342 UpdateState update_state) {
343 if (!render_frame_)
344 return;
345
346 HandlingState handling_state(render_frame_.get(), update_state);
347 render_frame_->GetWebFrame()->ExecuteCommand(
348 blink::WebString::FromUTF8(command));
349 }
350
351 void FrameInputHandlerImpl::Release() {
352 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
353 // Close the binding on the compositor thread first before telling the main
354 // thread to delete this object.
355 binding_.Close();
356 main_thread_task_runner_->PostTask(
357 FROM_HERE, base::Bind(&FrameInputHandlerImpl::Release, weak_this_));
358 return;
359 }
360 delete this;
361 }
362
363 void FrameInputHandlerImpl::BindNow(mojom::FrameInputHandlerRequest request) {
364 binding_.Bind(std::move(request));
365 binding_.set_connection_error_handler(
366 base::Bind(&FrameInputHandlerImpl::Release, base::Unretained(this)));
367 }
368
369 FrameInputHandlerImpl::HandlingState::HandlingState(
370 RenderFrameImpl* render_frame,
371 UpdateState state)
372 : render_frame_(render_frame),
373 original_select_range_value_(render_frame->handling_select_range()),
374 original_pasting_value_(render_frame->IsPasting()) {
375 switch (state) {
376 case UpdateState::kIsPasting:
377 render_frame->set_is_pasting(true);
378 case UpdateState::kIsSelectingRange:
379 render_frame->set_handling_select_range(true);
380 break;
381 case UpdateState::kNone:
382 break;
383 }
384 }
385
386 FrameInputHandlerImpl::HandlingState::~HandlingState() {
387 render_frame_->set_handling_select_range(original_select_range_value_);
388 render_frame_->set_is_pasting(original_pasting_value_);
389 }
390
391 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/input/frame_input_handler_impl.h ('k') | content/renderer/render_frame_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698