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

Unified Diff: content/browser/android/ime_adapter_android.cc

Issue 2931443003: Add support for Android spellcheck menu in Chrome/WebViews (Closed)
Patch Set: Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/android/ime_adapter_android.cc
diff --git a/content/browser/android/ime_adapter_android.cc b/content/browser/android/ime_adapter_android.cc
index 2b5904cf30830150e7df663f6d050f9e227020dd..c745a1f437590088c1a7ad6c6f910303afd71154 100644
--- a/content/browser/android/ime_adapter_android.cc
+++ b/content/browser/android/ime_adapter_android.cc
@@ -14,6 +14,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "content/browser/android/text_suggestion_host_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -24,6 +25,7 @@
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents.h"
#include "jni/ImeAdapter_jni.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebTextInputType.h"
#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
@@ -37,6 +39,8 @@ using base::android::ScopedJavaLocalRef;
namespace content {
namespace {
+int kDoubleTapTimeoutInMilliseconds = 300;
yosin_UTC9 2017/06/07 01:34:14 nit: s/int/const int/
+
// Maps a java KeyEvent into a NativeWebKeyboardEvent.
// |java_key_event| is used to maintain a globalref for KeyEvent.
// |type| will determine the WebInputEvent type.
@@ -114,8 +118,20 @@ void AppendUnderlineSpan(JNIEnv*,
ImeAdapterAndroid::ImeAdapterAndroid(JNIEnv* env,
const JavaParamRef<jobject>& obj,
WebContents* web_contents)
- : RenderWidgetHostConnector(web_contents), rwhva_(nullptr) {
+ : RenderWidgetHostConnector(web_contents),
+ rwhva_(nullptr),
+ java_ime_adapter_(JavaObjectWeakGlobalRef(env, obj)),
+ spellcheck_menu_timeout_(
+ base::Bind(&ImeAdapterAndroid::OnSpellCheckMenuTimeout,
+ base::Unretained(this))) {
java_ime_adapter_ = JavaObjectWeakGlobalRef(env, obj);
+
+ RenderFrameHost* rfh = GetFocusedFrame();
+ if (!rfh)
+ return;
+
+ rfh->GetInterfaceRegistry()->AddInterface(
+ base::Bind(&TextSuggestionHostImpl::Create, base::Unretained(this)));
}
ImeAdapterAndroid::~ImeAdapterAndroid() {
@@ -282,6 +298,12 @@ void ImeAdapterAndroid::FocusedNodeChanged(bool is_editable_node) {
if (!obj.is_null()) {
Java_ImeAdapter_focusedNodeChanged(env, obj, is_editable_node);
}
+
+ RenderFrameHost* rfh = GetFocusedFrame();
+ if (rfh) {
yosin_UTC9 2017/06/07 01:34:15 nit: early-return style is better as L130. Or chan
+ rfh->GetInterfaceRegistry()->AddInterface(
+ base::Bind(&TextSuggestionHostImpl::Create, base::Unretained(this)));
+ }
}
void ImeAdapterAndroid::SetEditableSelectionOffsets(
@@ -319,6 +341,33 @@ void ImeAdapterAndroid::SetCharacterBounds(
coordinates_array_size));
}
+void ImeAdapterAndroid::StartSpellCheckMenuTimer() {
+ spellcheck_menu_timeout_.Stop();
+ spellcheck_menu_timeout_.Start(
+ base::TimeDelta::FromMilliseconds(kDoubleTapTimeoutInMilliseconds));
+}
+
+void ImeAdapterAndroid::StopSpellCheckMenuTimer() {
+ spellcheck_menu_timeout_.Stop();
+}
+
+void ImeAdapterAndroid::ShowSpellCheckSuggestionMenu(
+ double caret_x,
+ double caret_y,
+ const std::string& marked_text,
+ const std::vector<blink::mojom::SpellCheckSuggestionPtr>& suggestions) {
+ std::vector<std::string> suggestion_strings;
+ for (const blink::mojom::SpellCheckSuggestionPtr& suggestion_ptr :
yosin_UTC9 2017/06/07 01:34:14 I think |const auto&| is enough since we know the
+ suggestions)
+ suggestion_strings.push_back(suggestion_ptr->suggestion);
+
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
+ Java_ImeAdapter_showSpellCheckSuggestionMenu(
+ env, obj, caret_x, caret_y, ConvertUTF8ToJavaString(env, marked_text),
+ base::android::ToJavaArrayOfStrings(env, suggestion_strings));
+}
+
void ImeAdapterAndroid::SetComposingRegion(JNIEnv*,
const JavaParamRef<jobject>&,
int start,
@@ -380,6 +429,49 @@ void ImeAdapterAndroid::RequestCursorUpdate(
rwhi->GetRoutingID(), immediate_request, monitor_request));
}
+void ImeAdapterAndroid::ApplySpellCheckSuggestion(
+ JNIEnv* env,
+ const JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jstring>& replacement) {
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
+ GetTextSuggestionBackend();
+ if (!text_suggestion_backend)
+ return;
+ text_suggestion_backend->ApplySpellCheckSuggestion(
+ ConvertJavaStringToUTF8(env, replacement));
+}
+
+void ImeAdapterAndroid::DeleteActiveSuggestionRange(
+ JNIEnv*,
+ const JavaParamRef<jobject>&) {
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
+ GetTextSuggestionBackend();
+ if (!text_suggestion_backend)
+ return;
+ text_suggestion_backend->DeleteActiveSuggestionRange();
+}
+
+void ImeAdapterAndroid::NewWordAddedToDictionary(
+ JNIEnv* env,
+ const JavaParamRef<jobject>&,
+ const base::android::JavaParamRef<jstring>& word) {
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
+ GetTextSuggestionBackend();
+ if (!text_suggestion_backend)
+ return;
+ text_suggestion_backend->NewWordAddedToDictionary(
+ ConvertJavaStringToUTF8(env, word));
+}
+
+void ImeAdapterAndroid::SuggestionMenuClosed(JNIEnv*,
+ const JavaParamRef<jobject>&) {
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
+ GetTextSuggestionBackend();
+ if (!text_suggestion_backend)
+ return;
+ text_suggestion_backend->SuggestionMenuClosed();
+}
+
RenderWidgetHostImpl* ImeAdapterAndroid::GetFocusedWidget() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return rwhva_ ? rwhva_->GetFocusedWidget() : nullptr;
@@ -422,4 +514,25 @@ ImeAdapterAndroid::GetUnderlinesFromSpans(
return underlines;
}
+const blink::mojom::TextSuggestionBackendPtr&
+ImeAdapterAndroid::GetTextSuggestionBackend() {
+ if (!text_suggestion_backend_) {
+ RenderFrameHost* rfh = GetFocusedFrame();
yosin_UTC9 2017/06/07 01:34:14 nit: We can put |rfh| in if-statement. if (Render
+ if (rfh) {
+ rfh->GetRemoteInterfaces()->GetInterface(
+ mojo::MakeRequest(&text_suggestion_backend_));
+ }
+ }
+
+ return text_suggestion_backend_;
+}
+
+void ImeAdapterAndroid::OnSpellCheckMenuTimeout() {
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend =
+ GetTextSuggestionBackend();
+ if (!text_suggestion_backend)
+ return;
+ text_suggestion_backend->SpellCheckMenuTimeoutCallback();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698