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

Side by Side Diff: content/browser/android/text_suggestion_host_android.cc

Issue 2931443003: Add support for Android spellcheck menu in Chrome/WebViews (Closed)
Patch Set: Simplify Mojo binding based on rockot@'s advice Created 3 years, 4 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/browser/android/text_suggestion_host_android.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "content/browser/android/text_suggestion_host_mojo_impl_android.h"
11 #include "content/browser/renderer_host/render_widget_host_impl.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "jni/TextSuggestionHost_jni.h"
16 #include "services/service_manager/public/cpp/interface_provider.h"
17 #include "ui/gfx/android/view_configuration.h"
18
19 using base::android::AttachCurrentThread;
20 using base::android::ConvertUTF8ToJavaString;
21 using base::android::JavaParamRef;
22 using base::android::ScopedJavaLocalRef;
23 using base::android::ToJavaArrayOfStrings;
24
25 namespace content {
26
27 bool RegisterTextSuggestionHost(JNIEnv* env) {
28 return RegisterNativesImpl(env);
29 }
30
31 jlong Init(JNIEnv* env,
32 const JavaParamRef<jobject>& obj,
33 const JavaParamRef<jobject>& jweb_contents) {
34 WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
35 DCHECK(web_contents);
36 auto* text_suggestion_host =
37 new TextSuggestionHostAndroid(env, obj, web_contents);
38 text_suggestion_host->Initialize();
39 return reinterpret_cast<intptr_t>(text_suggestion_host);
40 }
41
42 TextSuggestionHostAndroid::TextSuggestionHostAndroid(
43 JNIEnv* env,
44 const JavaParamRef<jobject>& obj,
45 WebContents* web_contents)
46 : RenderWidgetHostConnector(web_contents),
47 WebContentsObserver(web_contents),
48 rwhva_(nullptr),
49 java_text_suggestion_host_(JavaObjectWeakGlobalRef(env, obj)),
50 spellcheck_menu_timeout_(
51 base::Bind(&TextSuggestionHostAndroid::OnSpellCheckMenuTimeout,
52 base::Unretained(this))) {
53 registry_.AddInterface(base::Bind(&TextSuggestionHostMojoImplAndroid::Create,
54 base::Unretained(this)));
55 }
56
57 TextSuggestionHostAndroid::~TextSuggestionHostAndroid() {
58 JNIEnv* env = AttachCurrentThread();
59 ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
60 if (!obj.is_null())
61 Java_TextSuggestionHost_destroy(env, obj);
62 }
63
64 void TextSuggestionHostAndroid::UpdateRenderProcessConnection(
65 RenderWidgetHostViewAndroid* old_rwhva,
66 RenderWidgetHostViewAndroid* new_rwhva) {
67 text_suggestion_backend_ = nullptr;
68 if (old_rwhva)
69 old_rwhva->set_text_suggestion_host(nullptr);
70 if (new_rwhva)
71 new_rwhva->set_text_suggestion_host(this);
72 rwhva_ = new_rwhva;
73 }
74
75 void TextSuggestionHostAndroid::ApplySpellCheckSuggestion(
76 JNIEnv* env,
77 const JavaParamRef<jobject>&,
78 const base::android::JavaParamRef<jstring>& replacement) {
79 const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
80 GetTextSuggestionBackend();
81 if (!text_suggestion_backend)
82 return;
83 text_suggestion_backend->ApplySpellCheckSuggestion(
84 ConvertJavaStringToUTF8(env, replacement));
85 }
86
87 void TextSuggestionHostAndroid::DeleteActiveSuggestionRange(
88 JNIEnv*,
89 const JavaParamRef<jobject>&) {
90 const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
91 GetTextSuggestionBackend();
92 if (!text_suggestion_backend)
93 return;
94 text_suggestion_backend->DeleteActiveSuggestionRange();
95 }
96
97 void TextSuggestionHostAndroid::NewWordAddedToDictionary(
98 JNIEnv* env,
99 const JavaParamRef<jobject>&,
100 const base::android::JavaParamRef<jstring>& word) {
101 const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
102 GetTextSuggestionBackend();
103 if (!text_suggestion_backend)
104 return;
105 text_suggestion_backend->NewWordAddedToDictionary(
106 ConvertJavaStringToUTF8(env, word));
107 }
108
109 void TextSuggestionHostAndroid::SuggestionMenuClosed(
110 JNIEnv*,
111 const JavaParamRef<jobject>&) {
112 const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
113 GetTextSuggestionBackend();
114 if (!text_suggestion_backend)
115 return;
116 text_suggestion_backend->SuggestionMenuClosed();
117 }
118
119 void TextSuggestionHostAndroid::ShowSpellCheckSuggestionMenu(
120 double caret_x,
121 double caret_y,
122 const std::string& marked_text,
123 const std::vector<blink::mojom::SpellCheckSuggestionPtr>& suggestions) {
124 std::vector<std::string> suggestion_strings;
125 for (const auto& suggestion_ptr : suggestions)
126 suggestion_strings.push_back(suggestion_ptr->suggestion);
127 JNIEnv* env = AttachCurrentThread();
128 ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
129 if (obj.is_null())
130 return;
131
132 Java_TextSuggestionHost_showSpellCheckSuggestionMenu(
133 env, obj, caret_x, caret_y, ConvertUTF8ToJavaString(env, marked_text),
134 ToJavaArrayOfStrings(env, suggestion_strings));
135 }
136
137 void TextSuggestionHostAndroid::StartSpellCheckMenuTimer() {
138 spellcheck_menu_timeout_.Stop();
139 spellcheck_menu_timeout_.Start(base::TimeDelta::FromMilliseconds(
140 gfx::ViewConfiguration::GetDoubleTapTimeoutInMs()));
141 }
142
143 void TextSuggestionHostAndroid::OnKeyEvent() {
144 spellcheck_menu_timeout_.Stop();
145
146 JNIEnv* env = AttachCurrentThread();
147 ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
148 if (obj.is_null())
149 return;
150
151 Java_TextSuggestionHost_hidePopups(env, obj);
152 }
153
154 void TextSuggestionHostAndroid::StopSpellCheckMenuTimer() {
155 spellcheck_menu_timeout_.Stop();
156 }
157
158 void TextSuggestionHostAndroid::OnInterfaceRequestFromFrame(
159 content::RenderFrameHost* render_frame_host,
160 const std::string& interface_name,
161 mojo::ScopedMessagePipeHandle* interface_pipe) {
162 registry_.TryBindInterface(interface_name, interface_pipe);
163 }
164
165 RenderFrameHost* TextSuggestionHostAndroid::GetFocusedFrame() {
166 DCHECK_CURRENTLY_ON(BrowserThread::UI);
167 // We get the focused frame from the WebContents of the page. Although
168 // |rwhva_->GetFocusedWidget()| does a similar thing, there is no direct way
169 // to get a RenderFrameHost from its RWH.
170 if (!rwhva_)
171 return nullptr;
172 RenderWidgetHostImpl* rwh =
173 RenderWidgetHostImpl::From(rwhva_->GetRenderWidgetHost());
174 if (!rwh || !rwh->delegate())
175 return nullptr;
176
177 if (auto* contents = rwh->delegate()->GetAsWebContents())
178 return contents->GetFocusedFrame();
179
180 return nullptr;
181 }
182
183 const blink::mojom::TextSuggestionBackendPtr&
184 TextSuggestionHostAndroid::GetTextSuggestionBackend() {
185 if (!text_suggestion_backend_) {
186 if (RenderFrameHost* rfh = GetFocusedFrame()) {
187 rfh->GetRemoteInterfaces()->GetInterface(
188 mojo::MakeRequest(&text_suggestion_backend_));
189 }
190 }
191 return text_suggestion_backend_;
192 }
193
194 void TextSuggestionHostAndroid::OnSpellCheckMenuTimeout() {
195 const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
196 GetTextSuggestionBackend();
197 if (!text_suggestion_backend)
198 return;
199 text_suggestion_backend->SpellCheckMenuTimeoutCallback();
200 }
201
202 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698