Index: athena/virtual_keyboard/virtual_keyboard_bindings_impl.cc |
diff --git a/athena/virtual_keyboard/virtual_keyboard_bindings_impl.cc b/athena/virtual_keyboard/virtual_keyboard_bindings_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..55fdfc95d839460550f72dcf12f5b7ce21f971d6 |
--- /dev/null |
+++ b/athena/virtual_keyboard/virtual_keyboard_bindings_impl.cc |
@@ -0,0 +1,191 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "athena/virtual_keyboard/public/virtual_keyboard_bindings.h" |
+ |
+#include "base/json/json_string_value_serializer.h" |
+#include "base/logging.h" |
+#include "base/macros.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "base/values.h" |
+#include "content/public/common/bindings_policy.h" |
+#include "content/public/renderer/render_frame.h" |
+#include "content/public/renderer/render_view.h" |
+#include "content/public/renderer/render_view_observer.h" |
+#include "gin/handle.h" |
+#include "gin/object_template_builder.h" |
+#include "gin/wrappable.h" |
+#include "third_party/WebKit/public/web/WebKit.h" |
+#include "third_party/WebKit/public/web/WebLocalFrame.h" |
+#include "ui/keyboard/keyboard_constants.h" |
+ |
+namespace { |
+ |
+struct VKEvent { |
+ std::string event_type; |
+ int char_value; |
+ int key_code; |
+ std::string key_name; |
+ int modifiers; |
+}; |
+ |
+} // namespace |
+ |
+namespace gin { |
+ |
+template <> |
+struct Converter<VKEvent> { |
+ static bool FromV8(v8::Isolate* isolate, |
+ v8::Handle<v8::Value> val, |
+ VKEvent* event) { |
+ if (!val->IsObject()) |
+ return false; |
+ v8::Handle<v8::Object> dict(v8::Handle<v8::Object>::Cast(val)); |
+ |
+ if (!Converter<std::string>::FromV8( |
+ isolate, |
+ dict->Get(v8::String::NewFromUtf8(isolate, "type")), |
+ &event->event_type)) |
+ return false; |
+ if (!Converter<int32_t>::FromV8( |
+ isolate, |
+ dict->Get(v8::String::NewFromUtf8(isolate, "charValue")), |
+ &event->char_value)) |
+ return false; |
+ if (!Converter<int32_t>::FromV8( |
+ isolate, |
+ dict->Get(v8::String::NewFromUtf8(isolate, "keyCode")), |
+ &event->key_code)) |
+ return false; |
+ if (!Converter<std::string>::FromV8( |
+ isolate, |
+ dict->Get(v8::String::NewFromUtf8(isolate, "keyName")), |
+ &event->key_name)) |
+ return false; |
+ if (!Converter<int32_t>::FromV8( |
+ isolate, |
+ dict->Get(v8::String::NewFromUtf8(isolate, "modifiers")), |
+ &event->modifiers)) |
+ return false; |
+ |
+ return true; |
+ } |
+}; |
+ |
+} // namespace gin |
+ |
+namespace athena { |
+ |
+namespace { |
+ |
+class VKBindings : public gin::Wrappable<VKBindings> { |
+ public: |
+ static gin::WrapperInfo kWrapperInfo; |
+ |
+ static void Install(content::RenderView* render_view) { |
+ blink::WebFrame* web_frame = |
+ render_view->GetMainRenderFrame()->GetWebFrame(); |
+ v8::Isolate* isolate = blink::mainThreadIsolate(); |
+ v8::HandleScope handle_scope(isolate); |
+ v8::Handle<v8::Context> context = web_frame->mainWorldScriptContext(); |
+ if (context.IsEmpty()) |
+ return; |
+ |
+ v8::Context::Scope context_scope(context); |
+ |
+ v8::Handle<v8::Object> global = context->Global(); |
+ v8::Handle<v8::Object> chrome = |
+ global->Get(gin::StringToV8(isolate, "chrome"))->ToObject(); |
+ CHECK(!chrome.IsEmpty()); |
+ |
+ gin::Handle<VKBindings> controller = |
+ gin::CreateHandle(isolate, new VKBindings(render_view)); |
+ if (controller.IsEmpty()) |
+ return; |
+ chrome->Set(gin::StringToSymbol(isolate, "virtualKeyboardPrivate"), |
+ controller.ToV8()); |
+ } |
+ |
+ private: |
+ explicit VKBindings(content::RenderView* render_view) |
+ : render_view_(render_view) {} |
+ virtual ~VKBindings() {} |
+ |
+ // gin::WrappableBase |
+ virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( |
+ v8::Isolate* isolate) OVERRIDE { |
+ return gin::Wrappable<VKBindings>::GetObjectTemplateBuilder(isolate) |
+ .SetMethod("moveCursor", &VKBindings::NotImplemented) |
+ .SetMethod("sendKeyEvent", &VKBindings::SendKeyEvent) |
+ .SetMethod("hideKeyboard", &VKBindings::HideKeyboard) |
+ .SetMethod("lockKeyboard", &VKBindings::NotImplemented) |
+ .SetMethod("keyboardLoaded", &VKBindings::NotImplemented) |
+ .SetMethod("getKeyboardConfig", &VKBindings::NotImplemented); |
+ } |
+ |
+ void SendKeyEvent(gin::Arguments* args) { |
+ VKEvent event; |
+ if (!args->GetNext(&event)) { |
+ LOG(ERROR) << "Failed to get the type"; |
+ return; |
+ } |
+ base::ListValue params; |
+ params.Set(0, base::Value::CreateStringValue(event.event_type)); |
+ params.Set(1, base::Value::CreateIntegerValue(event.char_value)); |
+ params.Set(2, base::Value::CreateIntegerValue(event.key_code)); |
+ params.Set(3, base::Value::CreateStringValue(event.key_name)); |
+ params.Set(4, base::Value::CreateIntegerValue(event.modifiers)); |
+ |
+ std::string params_json; |
+ JSONStringValueSerializer serializer(¶ms_json); |
+ if (!serializer.Serialize(params)) |
+ return; |
+ |
+ render_view_->GetMainRenderFrame()->ExecuteJavaScript( |
+ base::UTF8ToUTF16("chrome.send('sendKeyEvent', " + params_json + ")")); |
+ } |
+ |
+ void HideKeyboard() { |
+ render_view_->GetMainRenderFrame()->ExecuteJavaScript( |
+ base::UTF8ToUTF16("chrome.send('hideKeyboard', [])")); |
+ } |
+ |
+ void NotImplemented(gin::Arguments* args) { NOTIMPLEMENTED(); } |
+ |
+ content::RenderView* render_view_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(VKBindings); |
+}; |
+ |
+gin::WrapperInfo VKBindings::kWrapperInfo = {gin::kEmbedderNativeGin}; |
+ |
+class VirtualKeyboardBindingsImpl : public VirtualKeyboardBindings, |
+ public content::RenderViewObserver { |
+ public: |
+ explicit VirtualKeyboardBindingsImpl(content::RenderView* render_view) |
+ : content::RenderViewObserver(render_view) {} |
+ |
+ virtual ~VirtualKeyboardBindingsImpl() {} |
+ |
+ private: |
+ // content::RenderViewObserver: |
+ virtual void Navigate(const GURL& url) OVERRIDE { |
+ bool enabled_bindings = render_view()->GetEnabledBindings(); |
+ if (!(enabled_bindings & content::BINDINGS_POLICY_WEB_UI)) |
+ return; |
+ if (url.GetOrigin() == GURL(keyboard::kKeyboardURL)) |
+ VKBindings::Install(render_view()); |
+ } |
+ DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardBindingsImpl); |
+}; |
+ |
+} // namespace |
+ |
+VirtualKeyboardBindings* VirtualKeyboardBindings::Create( |
+ content::RenderView* render_view) { |
+ return new VirtualKeyboardBindingsImpl(render_view); |
+} |
+ |
+} // namespace athena |