diff options
Diffstat (limited to 'chromium/content/browser/renderer_host/ime_adapter_android.cc')
-rw-r--r-- | chromium/content/browser/renderer_host/ime_adapter_android.cc | 188 |
1 files changed, 139 insertions, 49 deletions
diff --git a/chromium/content/browser/renderer_host/ime_adapter_android.cc b/chromium/content/browser/renderer_host/ime_adapter_android.cc index 92d972f22c6..afbc43400f7 100644 --- a/chromium/content/browser/renderer_host/ime_adapter_android.cc +++ b/chromium/content/browser/renderer_host/ime_adapter_android.cc @@ -4,17 +4,27 @@ #include "content/browser/renderer_host/ime_adapter_android.h" +#include <algorithm> #include <android/input.h> +#include <vector> #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "content/browser/frame_host/frame_tree.h" +#include "content/browser/frame_host/frame_tree_node.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_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" +#include "content/common/frame_messages.h" #include "content/common/view_messages.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/web_contents.h" #include "jni/ImeAdapter_jni.h" #include "third_party/WebKit/public/web/WebCompositionUnderline.h" #include "third_party/WebKit/public/web/WebInputEvent.h" @@ -46,7 +56,7 @@ NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent( else if (action == AKEY_EVENT_ACTION_UP) type = blink::WebInputEvent::KeyUp; return NativeWebKeyboardEvent(java_key_event, type, modifiers, - time_ms, key_code, unicode_char, is_system_key); + time_ms / 1000.0, key_code, unicode_char, is_system_key); } } // anonymous namespace @@ -79,6 +89,48 @@ bool RegisterImeAdapter(JNIEnv* env) { return true; } +// Callback from Java to convert BackgroundColorSpan data to a +// blink::WebCompositionUnderline instance, and append it to |underlines_ptr|. +void AppendBackgroundColorSpan(JNIEnv*, + jclass, + jlong underlines_ptr, + jint start, + jint end, + jint background_color) { + DCHECK(start >= 0); + DCHECK(end >= 0); + // Do not check |background_color|. + std::vector<blink::WebCompositionUnderline>* underlines = + reinterpret_cast<std::vector<blink::WebCompositionUnderline>*>( + underlines_ptr); + underlines->push_back( + blink::WebCompositionUnderline(static_cast<unsigned>(start), + static_cast<unsigned>(end), + SK_ColorTRANSPARENT, + false, + static_cast<unsigned>(background_color))); +} + +// Callback from Java to convert UnderlineSpan data to a +// blink::WebCompositionUnderline instance, and append it to |underlines_ptr|. +void AppendUnderlineSpan(JNIEnv*, + jclass, + jlong underlines_ptr, + jint start, + jint end) { + DCHECK(start >= 0); + DCHECK(end >= 0); + std::vector<blink::WebCompositionUnderline>* underlines = + reinterpret_cast<std::vector<blink::WebCompositionUnderline>*>( + underlines_ptr); + underlines->push_back( + blink::WebCompositionUnderline(static_cast<unsigned>(start), + static_cast<unsigned>(end), + SK_ColorBLACK, + false, + SK_ColorTRANSPARENT)); +} + ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva) : rwhva_(rwhva) { } @@ -122,7 +174,7 @@ bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject, // Send a Char event, but without an os_event since we don't want to // roundtrip back to java such synthetic event. NativeWebKeyboardEvent char_event(blink::WebInputEvent::Char, modifiers, - time_ms, key_code, unicode_char, + time_ms / 1000.0, key_code, unicode_char, is_system_key); char_event.skip_in_browser = key_down_text_insertion; rwhva_->SendKeyEvent(char_event); @@ -130,17 +182,32 @@ bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject, return true; } -void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text, +void ImeAdapterAndroid::SetComposingText(JNIEnv* env, + jobject obj, + jobject text, + jstring text_str, int new_cursor_pos) { RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); if (!rwhi) return; - base::string16 text16 = ConvertJavaStringToUTF16(env, text); + base::string16 text16 = ConvertJavaStringToUTF16(env, text_str); + std::vector<blink::WebCompositionUnderline> underlines; - underlines.push_back( - blink::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK, - false)); + // Iterate over spans in |text|, dispatch those that we care about (e.g., + // BackgroundColorSpan) to a matching callback (e.g., + // AppendBackgroundColorSpan()), and populate |underlines|. + Java_ImeAdapter_populateUnderlinesFromSpans( + env, obj, text, reinterpret_cast<jlong>(&underlines)); + + // Default to plain underline if we didn't find any span that we care about. + if (underlines.empty()) { + underlines.push_back(blink::WebCompositionUnderline( + 0, text16.length(), SK_ColorBLACK, false, SK_ColorTRANSPARENT)); + } + // Sort spans by |.startOffset|. + std::sort(underlines.begin(), underlines.end()); + // new_cursor_position is as described in the Android API for // InputConnection#setComposingText, whereas the parameters for // ImeSetComposition are relative to the start of the composition. @@ -150,12 +217,12 @@ void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text, rwhi->ImeSetComposition(text16, underlines, new_cursor_pos, new_cursor_pos); } -void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text) { +void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text_str) { RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); if (!rwhi) return; - base::string16 text16 = ConvertJavaStringToUTF16(env, text); + base::string16 text16 = ConvertJavaStringToUTF16(env, text_str); rwhi->ImeConfirmComposition(text16, gfx::Range::InvalidRange(), false); } @@ -179,78 +246,76 @@ void ImeAdapterAndroid::CancelComposition() { Java_ImeAdapter_cancelComposition(AttachCurrentThread(), obj.obj()); } +void ImeAdapterAndroid::FocusedNodeChanged(bool is_editable_node) { + base::android::ScopedJavaLocalRef<jobject> obj = + java_ime_adapter_.get(AttachCurrentThread()); + if (!obj.is_null()) { + Java_ImeAdapter_focusedNodeChanged(AttachCurrentThread(), + obj.obj(), + is_editable_node); + } +} + void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject, int start, int end) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) + RenderFrameHost* rfh = GetFocusedFrame(); + if (!rfh) return; - rwhi->Send(new ViewMsg_SetEditableSelectionOffsets(rwhi->GetRoutingID(), + rfh->Send(new FrameMsg_SetEditableSelectionOffsets(rfh->GetRoutingID(), start, end)); } void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject, int start, int end) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) + RenderFrameHost* rfh = GetFocusedFrame(); + if (!rfh) return; std::vector<blink::WebCompositionUnderline> underlines; - underlines.push_back( - blink::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false)); + underlines.push_back(blink::WebCompositionUnderline( + 0, end - start, SK_ColorBLACK, false, SK_ColorTRANSPARENT)); - rwhi->Send(new ViewMsg_SetCompositionFromExistingText( - rwhi->GetRoutingID(), start, end, underlines)); + rfh->Send(new FrameMsg_SetCompositionFromExistingText( + rfh->GetRoutingID(), start, end, underlines)); } void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, jobject, int before, int after) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->Send(new ViewMsg_ExtendSelectionAndDelete(rwhi->GetRoutingID(), - before, after)); + RenderFrameHostImpl* rfh = + static_cast<RenderFrameHostImpl*>(GetFocusedFrame()); + if (rfh) + rfh->ExtendSelectionAndDelete(before, after); } void ImeAdapterAndroid::Unselect(JNIEnv* env, jobject) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->Unselect(); + WebContents* wc = GetWebContents(); + if (wc) + wc->Unselect(); } void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->SelectAll(); + WebContents* wc = GetWebContents(); + if (wc) + wc->SelectAll(); } void ImeAdapterAndroid::Cut(JNIEnv* env, jobject) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->Cut(); + WebContents* wc = GetWebContents(); + if (wc) + wc->Cut(); } void ImeAdapterAndroid::Copy(JNIEnv* env, jobject) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->Copy(); + WebContents* wc = GetWebContents(); + if (wc) + wc->Copy(); } void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) { - RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); - if (!rwhi) - return; - - rwhi->Paste(); + WebContents* wc = GetWebContents(); + if (wc) + wc->Paste(); } void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) { @@ -258,6 +323,7 @@ void ImeAdapterAndroid::ResetImeAdapter(JNIEnv* env, jobject) { } RenderWidgetHostImpl* ImeAdapterAndroid::GetRenderWidgetHostImpl() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(rwhva_); RenderWidgetHost* rwh = rwhva_->GetRenderWidgetHost(); if (!rwh) @@ -266,4 +332,28 @@ RenderWidgetHostImpl* ImeAdapterAndroid::GetRenderWidgetHostImpl() { return RenderWidgetHostImpl::From(rwh); } +RenderFrameHost* ImeAdapterAndroid::GetFocusedFrame() { + RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl(); + if (!rwh) + return NULL; + if (!rwh->IsRenderView()) + return NULL; + RenderViewHost* rvh = RenderViewHost::From(rwh); + FrameTreeNode* focused_frame = + rvh->GetDelegate()->GetFrameTree()->GetFocusedFrame(); + if (!focused_frame) + return NULL; + + return focused_frame->current_frame_host(); +} + +WebContents* ImeAdapterAndroid::GetWebContents() { + RenderWidgetHostImpl* rwh = GetRenderWidgetHostImpl(); + if (!rwh) + return NULL; + if (!rwh->IsRenderView()) + return NULL; + return WebContents::FromRenderViewHost(RenderViewHost::From(rwh)); +} + } // namespace content |