Chromium Code Reviews| 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 |