| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/ime_adapter_android.h" | 5 #include "content/browser/renderer_host/ime_adapter_android.h" |
| 6 | 6 |
| 7 #include <android/input.h> |
| 8 |
| 7 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
| 8 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
| 11 #include "base/time.h" |
| 12 #include "base/utf_string_conversions.h" |
| 9 #include "content/browser/renderer_host/render_widget_host_impl.h" | 13 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 10 #include "content/browser/renderer_host/render_widget_host_view_android.h" | 14 #include "content/browser/renderer_host/render_widget_host_view_android.h" |
| 11 #include "content/common/view_messages.h" | 15 #include "content/common/view_messages.h" |
| 16 #include "content/public/browser/native_web_keyboard_event.h" |
| 12 #include "jni/ImeAdapter_jni.h" | 17 #include "jni/ImeAdapter_jni.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderli
ne.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 20 |
| 21 using base::android::AttachCurrentThread; |
| 22 using base::android::ConvertJavaStringToUTF16; |
| 23 using content::NativeWebKeyboardEvent; |
| 24 using content::RenderWidgetHostImpl; |
| 25 |
| 26 namespace { |
| 27 |
| 28 // Maps a java KeyEvent into a NativeWebKeyboardEvent. |
| 29 // |java_key_event| is used to maintain a globalref for KeyEvent. |
| 30 // |action| will help determine the WebInputEvent type. |
| 31 // type, |modifiers|, |time_ms|, |key_code|, |unicode_char| is used to create |
| 32 // WebKeyboardEvent. |key_code| is also needed ad need to treat the enter key |
| 33 // as a key press of character \r. |
| 34 NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent( |
| 35 JNIEnv* env, |
| 36 jobject java_key_event, |
| 37 int action, |
| 38 int modifiers, |
| 39 long time_ms, |
| 40 int key_code, |
| 41 bool is_system_key, |
| 42 int unicode_char) { |
| 43 WebKit::WebInputEvent::Type type = WebKit::WebInputEvent::Undefined; |
| 44 if (action == AKEY_EVENT_ACTION_DOWN) |
| 45 type = WebKit::WebInputEvent::RawKeyDown; |
| 46 else if (action == AKEY_EVENT_ACTION_UP) |
| 47 type = WebKit::WebInputEvent::KeyUp; |
| 48 return NativeWebKeyboardEvent(java_key_event, type, modifiers, |
| 49 time_ms, key_code, unicode_char, is_system_key); |
| 50 } |
| 51 |
| 52 } // anonymous namespace |
| 13 | 53 |
| 14 namespace content { | 54 namespace content { |
| 15 | 55 |
| 16 bool RegisterImeAdapter(JNIEnv* env) { | 56 bool RegisterImeAdapter(JNIEnv* env) { |
| 17 if (!RegisterNativesImpl(env)) | 57 if (!RegisterNativesImpl(env)) |
| 18 return false; | 58 return false; |
| 19 | 59 |
| 60 Java_ImeAdapter_initializeWebInputEvents(env, |
| 61 WebKit::WebInputEvent::RawKeyDown, |
| 62 WebKit::WebInputEvent::KeyUp, |
| 63 WebKit::WebInputEvent::Char, |
| 64 WebKit::WebInputEvent::ShiftKey, |
| 65 WebKit::WebInputEvent::AltKey, |
| 66 WebKit::WebInputEvent::ControlKey, |
| 67 WebKit::WebInputEvent::CapsLockOn, |
| 68 WebKit::WebInputEvent::NumLockOn); |
| 69 Java_ImeAdapter_initializeTextInputTypes( |
| 70 env, |
| 71 ui::TEXT_INPUT_TYPE_NONE, |
| 72 ui::TEXT_INPUT_TYPE_TEXT, |
| 73 ui::TEXT_INPUT_TYPE_TEXT_AREA, |
| 74 ui::TEXT_INPUT_TYPE_PASSWORD, |
| 75 ui::TEXT_INPUT_TYPE_SEARCH, |
| 76 ui::TEXT_INPUT_TYPE_URL, |
| 77 ui::TEXT_INPUT_TYPE_EMAIL, |
| 78 ui::TEXT_INPUT_TYPE_TELEPHONE, |
| 79 ui::TEXT_INPUT_TYPE_NUMBER, |
| 80 ui::TEXT_INPUT_TYPE_DATE, |
| 81 ui::TEXT_INPUT_TYPE_DATE_TIME, |
| 82 ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL, |
| 83 ui::TEXT_INPUT_TYPE_MONTH, |
| 84 ui::TEXT_INPUT_TYPE_TIME, |
| 85 ui::TEXT_INPUT_TYPE_WEEK, |
| 86 ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE); |
| 20 return true; | 87 return true; |
| 21 } | 88 } |
| 22 | 89 |
| 23 ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva) | 90 ImeAdapterAndroid::ImeAdapterAndroid(RenderWidgetHostViewAndroid* rwhva) |
| 24 : rwhva_(rwhva), | 91 : rwhva_(rwhva), |
| 25 java_ime_adapter_(NULL) { | 92 java_ime_adapter_(NULL) { |
| 26 } | 93 } |
| 27 | 94 |
| 28 ImeAdapterAndroid::~ImeAdapterAndroid() { | 95 ImeAdapterAndroid::~ImeAdapterAndroid() { |
| 29 if (java_ime_adapter_) { | 96 if (java_ime_adapter_) { |
| 30 JNIEnv* env = base::android::AttachCurrentThread(); | 97 JNIEnv* env = base::android::AttachCurrentThread(); |
| 31 Java_ImeAdapter_detach(env, java_ime_adapter_); | 98 Java_ImeAdapter_detach(env, java_ime_adapter_); |
| 32 env->DeleteGlobalRef(java_ime_adapter_); | 99 env->DeleteGlobalRef(java_ime_adapter_); |
| 33 } | 100 } |
| 34 } | 101 } |
| 35 | 102 |
| 103 bool ImeAdapterAndroid::SendSyntheticKeyEvent(JNIEnv*, |
| 104 jobject, |
| 105 int type, |
| 106 long time_ms, |
| 107 int key_code, |
| 108 int text) { |
| 109 NativeWebKeyboardEvent event(static_cast<WebKit::WebInputEvent::Type>(type), |
| 110 0 /* modifiers */, time_ms / 1000.0, key_code, |
| 111 text, false /* is_system_key */); |
| 112 rwhva_->SendKeyEvent(event); |
| 113 return true; |
| 114 } |
| 115 |
| 116 bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject, |
| 117 jobject original_key_event, |
| 118 int action, int modifiers, |
| 119 long time_ms, int key_code, |
| 120 bool is_system_key, int unicode_char) { |
| 121 NativeWebKeyboardEvent event = NativeWebKeyboardEventFromKeyEvent( |
| 122 env, original_key_event, action, modifiers, |
| 123 time_ms, key_code, is_system_key, unicode_char); |
| 124 rwhva_->SendKeyEvent(event); |
| 125 if (event.type == WebKit::WebInputEvent::RawKeyDown && event.text[0]) { |
| 126 // Send a Char event, but without an os_event since we don't want to |
| 127 // roundtrip back to java such synthetic event. |
| 128 NativeWebKeyboardEvent char_event(event); |
| 129 char_event.os_event = NULL; |
| 130 event.type = WebKit::WebInputEvent::Char; |
| 131 rwhva_->SendKeyEvent(event); |
| 132 } |
| 133 return true; |
| 134 } |
| 135 |
| 136 void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text, |
| 137 int new_cursor_pos) { |
| 138 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 139 rwhva_->GetRenderWidgetHost()); |
| 140 if (!rwhi) |
| 141 return; |
| 142 |
| 143 string16 text16 = ConvertJavaStringToUTF16(env, text); |
| 144 std::vector<WebKit::WebCompositionUnderline> underlines; |
| 145 underlines.push_back( |
| 146 WebKit::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK, |
| 147 false)); |
| 148 // new_cursor_position is as described in the Android API for |
| 149 // InputConnection#setComposingText, whereas the parameters for |
| 150 // ImeSetComposition are relative to the start of the composition. |
| 151 if (new_cursor_pos > 0) |
| 152 new_cursor_pos = text16.length() + new_cursor_pos - 1; |
| 153 |
| 154 rwhi->ImeSetComposition(text16, underlines, new_cursor_pos, new_cursor_pos); |
| 155 } |
| 156 |
| 157 |
| 158 void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text) { |
| 159 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 160 rwhva_->GetRenderWidgetHost()); |
| 161 if (!rwhi) |
| 162 return; |
| 163 |
| 164 string16 text16 = ConvertJavaStringToUTF16(env, text); |
| 165 rwhi->ImeConfirmComposition(text16); |
| 166 } |
| 167 |
| 168 void ImeAdapterAndroid::AttachImeAdapter(JNIEnv* env, jobject java_object) { |
| 169 java_ime_adapter_ = AttachCurrentThread()->NewGlobalRef(java_object); |
| 170 } |
| 171 |
| 172 void ImeAdapterAndroid::CancelComposition() { |
| 173 Java_ImeAdapter_cancelComposition(AttachCurrentThread(), java_ime_adapter_); |
| 174 } |
| 175 |
| 176 void ImeAdapterAndroid::ReplaceText(JNIEnv* env, jobject, jstring text) { |
| 177 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 178 rwhva_->GetRenderWidgetHost()); |
| 179 if (!rwhi) |
| 180 return; |
| 181 |
| 182 string16 text16 = ConvertJavaStringToUTF16(env, text); |
| 183 rwhi->Send(new ViewMsg_ReplaceAll(rwhi->GetRoutingID(), text16)); |
| 184 } |
| 185 |
| 186 void ImeAdapterAndroid::ClearFocus(JNIEnv* env, jobject) { |
| 187 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 188 rwhva_->GetRenderWidgetHost()); |
| 189 if (!rwhi) |
| 190 return; |
| 191 |
| 192 rwhi->Send(new ViewMsg_ClearFocusedNode(rwhi->GetRoutingID())); |
| 193 } |
| 194 |
| 195 void ImeAdapterAndroid::SetEditableSelectionOffsets(JNIEnv*, jobject, |
| 196 int start, int end) { |
| 197 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 198 rwhva_->GetRenderWidgetHost()); |
| 199 if (!rwhi) |
| 200 return; |
| 201 |
| 202 rwhi->Send(new ViewMsg_SetEditableSelectionOffsets(rwhi->GetRoutingID(), |
| 203 start, end)); |
| 204 } |
| 205 |
| 206 void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject, |
| 207 int start, int end) { |
| 208 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 209 rwhva_->GetRenderWidgetHost()); |
| 210 if (!rwhi) |
| 211 return; |
| 212 |
| 213 std::vector<WebKit::WebCompositionUnderline> underlines; |
| 214 underlines.push_back( |
| 215 WebKit::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false)); |
| 216 |
| 217 rwhi->Send(new ViewMsg_SetCompositionFromExistingText( |
| 218 rwhi->GetRoutingID(), start, end, underlines)); |
| 219 } |
| 220 |
| 221 void ImeAdapterAndroid::DeleteSurroundingText(JNIEnv*, jobject, |
| 222 int before, int after) { |
| 223 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 224 rwhva_->GetRenderWidgetHost()); |
| 225 if (!rwhi) |
| 226 return; |
| 227 |
| 228 rwhi->Send(new ViewMsg_ExtendSelectionAndDelete(rwhi->GetRoutingID(), |
| 229 before, after)); |
| 230 } |
| 231 |
| 36 void ImeAdapterAndroid::Unselect(JNIEnv* env, jobject) { | 232 void ImeAdapterAndroid::Unselect(JNIEnv* env, jobject) { |
| 37 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( | 233 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 38 rwhva_->GetRenderWidgetHost()); | 234 rwhva_->GetRenderWidgetHost()); |
| 39 if (!rwhi) | 235 if (!rwhi) |
| 40 return; | 236 return; |
| 41 | 237 |
| 42 rwhi->Send(new ViewMsg_Unselect(rwhi->GetRoutingID())); | 238 rwhi->Send(new ViewMsg_Unselect(rwhi->GetRoutingID())); |
| 43 } | 239 } |
| 44 | 240 |
| 45 void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) { | 241 void ImeAdapterAndroid::SelectAll(JNIEnv* env, jobject) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 71 | 267 |
| 72 void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) { | 268 void ImeAdapterAndroid::Paste(JNIEnv* env, jobject) { |
| 73 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( | 269 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( |
| 74 rwhva_->GetRenderWidgetHost()); | 270 rwhva_->GetRenderWidgetHost()); |
| 75 if (!rwhi) | 271 if (!rwhi) |
| 76 return; | 272 return; |
| 77 | 273 |
| 78 rwhi->Send(new ViewMsg_Paste(rwhi->GetRoutingID())); | 274 rwhi->Send(new ViewMsg_Paste(rwhi->GetRoutingID())); |
| 79 } | 275 } |
| 80 | 276 |
| 81 } // namespace content | 277 } // namespace content |
| OLD | NEW |