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 4e18e286f1d4f5db4a06d804ae4c4d226630f2e5..ace23c9b66122623779bf005fa68811a7f988e83 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/interstitial_page_impl.h" |
#include "content/browser/frame_host/render_frame_host_impl.h" |
#include "content/browser/renderer_host/render_view_host_delegate.h" |
@@ -26,12 +27,17 @@ |
#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" |
+#include "third_party/WebKit/public/web/WebTextSuggestionInfo.h" |
using base::android::AttachCurrentThread; |
using base::android::ConvertJavaStringToUTF16; |
+using base::android::ConvertUTF8ToJavaString; |
+using base::android::GetClass; |
+using base::android::MethodID; |
using base::android::JavaParamRef; |
using base::android::ScopedJavaLocalRef; |
@@ -94,6 +100,31 @@ void AppendBackgroundColorSpan(JNIEnv*, |
SK_ColorTRANSPARENT, false, static_cast<unsigned>(background_color))); |
} |
+// Callback from Java to convert SuggestionSpan data to a |
+// blink::WebCompositionUnderline instance, and append it to |underlines_ptr|. |
+void AppendSuggestionSpan(JNIEnv* env, |
+ const JavaParamRef<jclass>&, |
+ jlong underlines_ptr, |
+ jint start, |
+ jint end, |
+ jint underline_color, |
+ jint flags, |
+ const JavaParamRef<jobjectArray>& suggestions) { |
+ DCHECK_GE(start, 0); |
+ DCHECK_GE(end, 0); |
+ std::vector<blink::WebCompositionUnderline>* underlines = |
+ reinterpret_cast<std::vector<blink::WebCompositionUnderline>*>( |
+ underlines_ptr); |
+ |
+ std::vector<std::string> suggestions_vec; |
+ AppendJavaStringArrayToStringVector(env, suggestions, &suggestions_vec); |
+ |
+ underlines->push_back(blink::WebCompositionUnderline( |
+ static_cast<unsigned>(start), static_cast<unsigned>(end), |
+ static_cast<unsigned>(underline_color), true, SK_ColorTRANSPARENT, |
+ suggestions_vec)); |
+} |
+ |
// Callback from Java to convert UnderlineSpan data to a |
// blink::WebCompositionUnderline instance, and append it to |underlines_ptr|. |
void AppendUnderlineSpan(JNIEnv*, |
@@ -116,6 +147,13 @@ ImeAdapterAndroid::ImeAdapterAndroid(JNIEnv* env, |
WebContents* web_contents) |
: WebContentsObserver(web_contents), rwhva_(nullptr) { |
java_ime_adapter_ = JavaObjectWeakGlobalRef(env, obj); |
+ |
+ RenderFrameHost* rfh = GetFocusedFrame(); |
+ if (!rfh) |
+ return; |
+ |
+ rfh->GetInterfaceRegistry()->AddInterface( |
+ base::Bind(&TextSuggestionHostImpl::create, base::Unretained(this))); |
} |
ImeAdapterAndroid::~ImeAdapterAndroid() { |
@@ -285,6 +323,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) { |
+ rfh->GetInterfaceRegistry()->AddInterface( |
+ base::Bind(&TextSuggestionHostImpl::create, base::Unretained(this))); |
+ } |
} |
void ImeAdapterAndroid::SetEditableSelectionOffsets( |
@@ -323,6 +367,38 @@ void ImeAdapterAndroid::SetCharacterBounds( |
coordinates_array_size)); |
} |
+void ImeAdapterAndroid::ShowTextSuggestionMenu( |
+ const std::vector<blink::mojom::TextSuggestionInfoPtr>& suggestion_infos) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env); |
+ |
+ ScopedJavaLocalRef<jclass> clazz = |
+ GetClass(env, "org/chromium/content/browser/input/SuggestionInfo"); |
+ jmethodID constructor = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, clazz.obj(), "<init>", |
+ "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); |
+ ScopedJavaLocalRef<jobjectArray> suggestion_infos_for_java( |
+ env, env->NewObjectArray(suggestion_infos.size(), clazz.obj(), nullptr)); |
+ |
+ for (size_t i = 0; i < suggestion_infos.size(); i++) { |
+ const blink::mojom::TextSuggestionInfoPtr& suggestion_info_ptr = |
+ suggestion_infos[i]; |
+ |
+ ScopedJavaLocalRef<jobject> suggestion_info_for_java( |
+ env, |
+ env->NewObject( |
+ clazz.obj(), constructor, suggestion_info_ptr->suggestionID, |
+ suggestion_info_ptr->suggestionIndex, |
+ ConvertUTF8ToJavaString(env, suggestion_info_ptr->prefix).obj(), |
+ ConvertUTF8ToJavaString(env, suggestion_info_ptr->suggestion).obj(), |
+ ConvertUTF8ToJavaString(env, suggestion_info_ptr->suffix).obj())); |
+ env->SetObjectArrayElement(suggestion_infos_for_java.obj(), i, |
+ suggestion_info_for_java.obj()); |
+ } |
+ |
+ Java_ImeAdapter_showSuggestionMenu(env, obj, suggestion_infos_for_java.obj()); |
+} |
+ |
void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, |
const JavaParamRef<jobject>&, |
int start, |
@@ -382,6 +458,40 @@ void ImeAdapterAndroid::RequestCursorUpdate( |
rwhi->GetRoutingID(), immediate_request, monitor_request)); |
} |
+void ImeAdapterAndroid::ApplySuggestionReplacement(JNIEnv*, |
+ const JavaParamRef<jobject>&, |
+ long documentMarkerID, |
+ int suggestionIndex) { |
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend = |
+ GetTextSuggestionBackend(); |
+ if (!text_suggestion_backend) |
+ return; |
+ |
+ text_suggestion_backend->ApplySuggestionReplacement(documentMarkerID, |
+ suggestionIndex); |
+} |
+ |
+void ImeAdapterAndroid::DeleteSuggestionHighlight( |
+ JNIEnv*, |
+ const JavaParamRef<jobject>&) { |
+ const blink::mojom::TextSuggestionBackendPtr& text_suggestion_backend = |
+ GetTextSuggestionBackend(); |
+ if (!text_suggestion_backend) |
+ return; |
+ |
+ text_suggestion_backend->DeleteSuggestionHighlight(); |
+} |
+ |
+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; |
@@ -424,4 +534,17 @@ ImeAdapterAndroid::GetUnderlinesFromSpans( |
return underlines; |
} |
+const blink::mojom::TextSuggestionBackendPtr& |
+ImeAdapterAndroid::GetTextSuggestionBackend() { |
+ if (!text_suggestion_backend_) { |
+ RenderFrameHost* rfh = GetFocusedFrame(); |
+ if (rfh) { |
+ rfh->GetRemoteInterfaces()->GetInterface( |
+ mojo::MakeRequest(&text_suggestion_backend_)); |
+ } |
+ } |
+ |
+ return text_suggestion_backend_; |
+} |
+ |
} // namespace content |