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

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

Issue 2884243003: Add a mojo channel for frame messages. (Closed)
Patch Set: Use WeakPtr inside FrameInputHandlerImpl, add comments 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
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_(
26 render_frame->GetRenderWidget()->GetInputEventQueue()) {
27 // Once the binding is connected the error handler will be set to
28 // Release.
29 AddRef();
30
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::BindOnCompositor,
37 this, std::move(request)));
38 } else {
39 // Mojo channel bound on main thread.
40 BindNow(std::move(request));
41 }
42 main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
dcheng 2017/05/25 00:03:58 Nit: bind this in the initializer list for consist
dtapuska 2017/05/26 14:02:06 Done.
43 }
44
45 FrameInputHandlerImpl::~FrameInputHandlerImpl() {}
46
47 // static
48 void FrameInputHandlerImpl::CreateMojoService(
49 base::WeakPtr<RenderFrameImpl> render_frame,
50 const service_manager::BindSourceInfo& source_info,
51 mojom::FrameInputHandlerRequest request) {
52 DCHECK(render_frame);
53
54 // Owns itself. Will be deleted when message pipe is destroyed.
55 new FrameInputHandlerImpl(render_frame, std::move(request));
56 }
57
58 void FrameInputHandlerImpl::RunOnMainThread(const base::Closure& closure) {
59 if (input_event_queue_) {
60 input_event_queue_->QueueClosure(closure);
61 } else {
62 closure.Run();
63 }
64 }
65
66 void FrameInputHandlerImpl::SetCompositionFromExistingText(
67 int32_t start,
68 int32_t end,
69 const std::vector<ui::CompositionUnderline>& ui_underlines) {
70 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
71 RunOnMainThread(
72 base::Bind(&FrameInputHandlerImpl::SetCompositionFromExistingText, this,
dcheng 2017/05/25 00:03:58 It's safe to vend weak pointers from another threa
dtapuska 2017/05/26 14:02:06 Done. Although I needed to clear the bindings in t
73 start, end, ui_underlines));
74 return;
75 }
76
77 if (!render_frame_)
78 return;
79
80 ImeEventGuard guard(render_frame_->GetRenderWidget());
81 std::vector<blink::WebCompositionUnderline> underlines;
82 for (const auto& underline : ui_underlines) {
83 blink::WebCompositionUnderline blink_underline(
84 underline.start_offset, underline.end_offset, underline.color,
85 underline.thick, underline.background_color);
86 underlines.push_back(blink_underline);
87 }
88
89 render_frame_->GetWebFrame()->SetCompositionFromExistingText(start, end,
90 underlines);
91 }
92
93 void FrameInputHandlerImpl::ExtendSelectionAndDelete(int32_t before,
94 int32_t after) {
95 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
96 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExtendSelectionAndDelete,
97 this, before, after));
98 return;
99 }
100 if (!render_frame_)
101 return;
102 render_frame_->GetWebFrame()->ExtendSelectionAndDelete(before, after);
103 }
104
105 void FrameInputHandlerImpl::DeleteSurroundingText(int32_t before,
106 int32_t after) {
107 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
108 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::DeleteSurroundingText,
109 this, before, after));
110 return;
111 }
112 if (!render_frame_)
113 return;
114 render_frame_->GetWebFrame()->DeleteSurroundingText(before, after);
115 }
116
117 void FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints(int32_t before,
118 int32_t after) {
119 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
120 RunOnMainThread(
121 base::Bind(&FrameInputHandlerImpl::DeleteSurroundingTextInCodePoints,
122 this, before, after));
123 return;
124 }
125 if (!render_frame_)
126 return;
127 render_frame_->GetWebFrame()->DeleteSurroundingTextInCodePoints(before,
128 after);
129 }
130
131 void FrameInputHandlerImpl::SetEditableSelectionOffsets(int32_t start,
132 int32_t end) {
133 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
134 RunOnMainThread(base::Bind(
135 &FrameInputHandlerImpl::SetEditableSelectionOffsets, 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, this,
148 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 this, "Undo", UpdateState::kNone));
167 }
168
169 void FrameInputHandlerImpl::Redo() {
170 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
171 this, "Redo", UpdateState::kNone));
172 }
173
174 void FrameInputHandlerImpl::Cut() {
175 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
176 this, "Cut", UpdateState::kIsSelectingRange));
177 }
178
179 void FrameInputHandlerImpl::Copy() {
180 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
181 this, "Copy", UpdateState::kIsSelectingRange));
182 }
183
184 void FrameInputHandlerImpl::CopyToFindPboard() {
185 #if defined(OS_MACOSX)
186 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
187 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::CopyToFindPboard, this));
188 return;
189 }
190 if (!render_frame_)
191 return;
192 render_frame_->OnCopyToFindPboard();
193 #endif
194 }
195
196 void FrameInputHandlerImpl::Paste() {
197 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
198 this, "Paste", UpdateState::kIsPasting));
199 }
200
201 void FrameInputHandlerImpl::PasteAndMatchStyle() {
202 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
203 this, "PasteAndMatchStyle",
204 UpdateState::kIsPasting));
205 }
206
207 void FrameInputHandlerImpl::Replace(const base::string16& word) {
208 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
209 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::Replace, this, word));
210 return;
211 }
212 if (!render_frame_)
213 return;
214 blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
215 if (frame->HasSelection())
216 frame->SelectWordAroundCaret();
217 frame->ReplaceSelection(blink::WebString::FromUTF16(word));
218 render_frame_->SyncSelectionIfRequired(true);
219 }
220
221 void FrameInputHandlerImpl::ReplaceMisspelling(const base::string16& word) {
222 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
223 RunOnMainThread(
224 base::Bind(&FrameInputHandlerImpl::ReplaceMisspelling, this, word));
225 return;
226 }
227 if (!render_frame_)
228 return;
229 blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
230 if (!frame->HasSelection())
231 return;
232 frame->ReplaceMisspelledRange(blink::WebString::FromUTF16(word));
233 }
234
235 void FrameInputHandlerImpl::Delete() {
236 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
237 this, "Delete", UpdateState::kNone));
238 }
239
240 void FrameInputHandlerImpl::SelectAll() {
241 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::ExecuteCommandOnMainThread,
242 this, "SelectAll",
243 UpdateState::kIsSelectingRange));
244 }
245
246 void FrameInputHandlerImpl::CollapseSelection() {
247 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
248 RunOnMainThread(
249 base::Bind(&FrameInputHandlerImpl::CollapseSelection, this));
250 return;
251 }
252
253 if (!render_frame_)
254 return;
255 const blink::WebRange& range =
256 render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
257 if (range.IsNull())
258 return;
259
260 HandlingState handling_state(render_frame_.get(),
261 UpdateState::kIsSelectingRange);
262 render_frame_->GetWebFrame()->SelectRange(
263 blink::WebRange(range.EndOffset(), 0));
264 }
265
266 void FrameInputHandlerImpl::SelectRange(const gfx::Point& base,
267 const gfx::Point& extent) {
268 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
269 // TODO(dtapuska): This event should be coalesced. Chrome IPC used
270 // and ack scheme for this. We should be able to clobber them in the
271 // main thread event queue.
272 RunOnMainThread(
273 base::Bind(&FrameInputHandlerImpl::SelectRange, this, base, extent));
274 return;
275 }
276
277 if (!render_frame_)
278 return;
279 RenderViewImpl* render_view = render_frame_->render_view();
280 HandlingState handling_state(render_frame_.get(),
281 UpdateState::kIsSelectingRange);
282 render_frame_->GetWebFrame()->SelectRange(
283 render_view->ConvertWindowPointToViewport(base),
284 render_view->ConvertWindowPointToViewport(extent));
285 }
286
287 void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(int32_t start,
288 int32_t end) {
289 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
290 RunOnMainThread(
291 base::Bind(&FrameInputHandlerImpl::AdjustSelectionByCharacterOffset,
292 this, start, end));
293 return;
294 }
295
296 if (!render_frame_)
297 return;
298 blink::WebRange range =
299 render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
300 if (range.IsNull())
301 return;
302
303 // Sanity checks to disallow empty and out of range selections.
304 if (start - end > range.length() || range.StartOffset() + start < 0)
305 return;
306
307 HandlingState handling_state(render_frame_.get(),
308 UpdateState::kIsSelectingRange);
309 // A negative adjust amount moves the selection towards the beginning of
310 // the document, a positive amount moves the selection towards the end of
311 // the document.
312 render_frame_->GetWebFrame()->SelectRange(
313 blink::WebRange(range.StartOffset() + start,
314 range.length() + end - start),
315 blink::WebLocalFrame::kPreserveHandleVisibility);
316 }
317
318 void FrameInputHandlerImpl::MoveRangeSelectionExtent(const gfx::Point& extent) {
319 if (!main_thread_task_runner_->BelongsToCurrentThread()) {
320 // TODO(dtapuska): This event should be coalesced. Chrome IPC used
321 // and ack scheme for this. We should be able to clobber them in the
322 // main thread event queue.
323 RunOnMainThread(base::Bind(&FrameInputHandlerImpl::MoveRangeSelectionExtent,
324 this, extent));
325 return;
326 }
327
328 if (!render_frame_)
329 return;
330 HandlingState handling_state(render_frame_.get(),
331 UpdateState::kIsSelectingRange);
332 render_frame_->GetWebFrame()->MoveRangeSelectionExtent(
333 render_frame_->render_view()->ConvertWindowPointToViewport(extent));
334 }
335
336 void FrameInputHandlerImpl::ExecuteCommandOnMainThread(
337 const std::string& command,
338 UpdateState update_state) {
339 if (!render_frame_)
340 return;
341
342 HandlingState handling_state(render_frame_.get(), update_state);
343 render_frame_->GetWebFrame()->ExecuteCommand(
344 blink::WebString::FromUTF8(command));
345 }
346
347 void FrameInputHandlerImpl::BindOnCompositor(
348 mojom::FrameInputHandlerRequest request) {
349 BindNow(std::move(request));
350 }
351
352 void FrameInputHandlerImpl::BindNow(mojom::FrameInputHandlerRequest request) {
353 binding_.Bind(std::move(request));
354
355 // This will Release the ref-counted AddRef that was added in the constructor.
356 binding_.set_connection_error_handler(
357 base::Bind(&FrameInputHandlerImpl::Release, this));
358 }
359
360 FrameInputHandlerImpl::HandlingState::HandlingState(
361 RenderFrameImpl* render_frame,
362 UpdateState state)
363 : render_frame_(render_frame),
364 original_select_range_value_(render_frame->handling_select_range()),
365 original_pasting_value_(render_frame->IsPasting()) {
366 switch (state) {
367 case UpdateState::kIsPasting:
368 render_frame->set_is_pasting(true);
369 case UpdateState::kIsSelectingRange:
370 render_frame->set_handling_select_range(true);
371 break;
372 case UpdateState::kNone:
373 break;
374 }
375 }
376
377 FrameInputHandlerImpl::HandlingState::~HandlingState() {
378 render_frame_->set_handling_select_range(original_select_range_value_);
379 render_frame_->set_is_pasting(original_pasting_value_);
380 }
381
382 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698