| 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..933654ef5c9331f44b2999d65016be01ae4410e0 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 {
|
|
|
| +const int kDoubleTapTimeoutInMilliseconds = 300;
|
| +
|
| // 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,13 @@ void ImeAdapterAndroid::FocusedNodeChanged(bool is_editable_node) {
|
| if (!obj.is_null()) {
|
| Java_ImeAdapter_focusedNodeChanged(env, obj, is_editable_node);
|
| }
|
| +
|
| + RenderFrameHost* rfh = GetFocusedFrame();
|
| + if (!rfh)
|
| + return;
|
| +
|
| + rfh->GetInterfaceRegistry()->AddInterface(
|
| + base::Bind(&TextSuggestionHostImpl::Create, base::Unretained(this)));
|
| }
|
|
|
| void ImeAdapterAndroid::SetEditableSelectionOffsets(
|
| @@ -319,6 +342,32 @@ 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 auto& suggestion_ptr : 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,24 @@ ImeAdapterAndroid::GetUnderlinesFromSpans(
|
| return underlines;
|
| }
|
|
|
| +const blink::mojom::TextSuggestionBackendPtr&
|
| +ImeAdapterAndroid::GetTextSuggestionBackend() {
|
| + if (!text_suggestion_backend_) {
|
| + if (RenderFrameHost* rfh = GetFocusedFrame()) {
|
| + 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
|
|
|