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 "chrome/browser/vr/content_input_delegate.h"
6
7 #include <utility>
8
9 #include "base/time/time.h"
10 #include "chrome/browser/vr/platform_input_handler.h"
11
12 namespace vr {
13
ContentInputDelegate()14 ContentInputDelegate::ContentInputDelegate() {}
15
ContentInputDelegate(PlatformInputHandler * input_handler)16 ContentInputDelegate::ContentInputDelegate(PlatformInputHandler* input_handler)
17 : PlatformUiInputDelegate(input_handler) {}
18
19 ContentInputDelegate::~ContentInputDelegate() = default;
20
OnFocusChanged(bool focused)21 void ContentInputDelegate::OnFocusChanged(bool focused) {
22 // The call below tells the renderer to clear the focused element. Note that
23 // we don't need to do anything when focused is true because the renderer
24 // already knows about the focused element.
25 if (!focused)
26 input_handler()->ClearFocusedElement();
27 }
28
OnWebInputEdited(const EditedText & info,bool commit)29 void ContentInputDelegate::OnWebInputEdited(const EditedText& info,
30 bool commit) {
31 if (!input_handler())
32 return;
33
34 last_keyboard_edit_ = info;
35
36 if (commit) {
37 input_handler()->SubmitWebInput();
38 return;
39 }
40
41 input_handler()->OnWebInputEdited(info.GetDiff());
42 }
43
OnSwapContents(int new_content_id)44 void ContentInputDelegate::OnSwapContents(int new_content_id) {
45 content_id_ = new_content_id;
46 }
47
SendGestureToTarget(std::unique_ptr<InputEvent> event)48 void ContentInputDelegate::SendGestureToTarget(
49 std::unique_ptr<InputEvent> event) {
50 if (!event || !input_handler() || ContentGestureIsLocked(event->type()))
51 return;
52
53 input_handler()->ForwardEventToContent(std::move(event), content_id_);
54 }
55
ContentGestureIsLocked(InputEvent::Type type)56 bool ContentInputDelegate::ContentGestureIsLocked(InputEvent::Type type) {
57 // TODO (asimjour) create a new HoverEnter event when we swap webcontents and
58 // pointer is on the content quad.
59 if (type == InputEvent::kScrollBegin || type == InputEvent::kHoverMove ||
60 type == InputEvent::kButtonDown || type == InputEvent::kHoverEnter)
61 locked_content_id_ = content_id_;
62
63 return locked_content_id_ != content_id_;
64 }
65
OnWebInputIndicesChanged(int selection_start,int selection_end,int composition_start,int composition_end,TextInputUpdateCallback callback)66 void ContentInputDelegate::OnWebInputIndicesChanged(
67 int selection_start,
68 int selection_end,
69 int composition_start,
70 int composition_end,
71 TextInputUpdateCallback callback) {
72 // The purpose of this method is to determine if we need to query content for
73 // the text surrounding the currently focused web input field.
74
75 // If the changed indices match with that from the last keyboard edit, then
76 // this is called in response to the user entering text using the keyboard, so
77 // we already know the text and don't need to ask content for it.
78 TextInputInfo i = last_keyboard_edit_.current;
79 if (i.selection_start == selection_start &&
80 i.selection_end == selection_end &&
81 i.composition_start == composition_start &&
82 i.composition_end == composition_end) {
83 std::move(callback).Run(i);
84 return;
85 }
86
87 // Otherwise, queue up the callback
88 update_state_callbacks_.emplace(std::move(callback));
89
90 // If there's no current request, create one
91 if (pending_text_request_state_ == kNoPendingRequest) {
92 TextInputInfo pending_text_input_info;
93 pending_text_input_info.selection_start = selection_start;
94 pending_text_input_info.selection_end = selection_end;
95 pending_text_input_info.composition_start = composition_start;
96 pending_text_input_info.composition_end = composition_end;
97 input_handler()->RequestWebInputText(base::BindOnce(
98 &ContentInputDelegate::OnWebInputTextChanged, base::Unretained(this),
99 std::move(pending_text_input_info)));
100 pending_text_request_state_ = kRequested;
101 }
102 }
103
ClearTextInputState()104 void ContentInputDelegate::ClearTextInputState() {
105 pending_text_request_state_ = kNoPendingRequest;
106 last_keyboard_edit_ = EditedText();
107 }
108
OnWebInputTextChanged(TextInputInfo pending_input_info,const base::string16 & text)109 void ContentInputDelegate::OnWebInputTextChanged(
110 TextInputInfo pending_input_info,
111 const base::string16& text) {
112 pending_input_info.text = text;
113 DCHECK(!update_state_callbacks_.empty());
114
115 while (!update_state_callbacks_.empty()) {
116 auto update_state_callback = std::move(update_state_callbacks_.front());
117 update_state_callbacks_.pop();
118 std::move(update_state_callback).Run(pending_input_info);
119 }
120
121 pending_text_request_state_ = kNoPendingRequest;
122 }
123
124 } // namespace vr
125