diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-20 13:01:14 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-20 13:01:14 +0000 |
commit | 4f440830ce391024ae2a5981d26b44890d236032 (patch) | |
tree | 1964f29815ddeb90c5443abfca2cd43f647be8dd | |
parent | a0fb77a84519d63b34271b5fca95c2ffaa31d4a1 (diff) | |
download | chromium_src-4f440830ce391024ae2a5981d26b44890d236032.zip chromium_src-4f440830ce391024ae2a5981d26b44890d236032.tar.gz chromium_src-4f440830ce391024ae2a5981d26b44890d236032.tar.bz2 |
athena: Add support for virtual keyboard.
The virtual keyboard used on Chrome OS (in ash) is provided by an
extension. For athena, we cannot yet use the extension version of the
keyboard. As a short-term workaround, this patch introduces a web-ui
version of the keyboard for initial use. This patch provides a
simplistic implementation of some of the virtualKeyboardPrivate API
(sendKeyEvent, hideKeyboard) over WebUI.
This patch installs a webui controller (VKWebUIController) for the
keyboard URL (chrome://keyboard), and a message-handler (VKMessageHandler)
to process the incoming messages from the keyboard. These are installed
in the browser process. In the renderer process, this patch installs a
RenderViewObserver implementation (VirtualKeyboardBindingsImpl) which
provides the necessary bindings for the virtualKeyboardPrivate API
(VKBindings), and generates the appropriate webui messages by calling
chrome.send(). This lets us use the same HTML/JS/Polymer version of the
keyboard as in Chrome OS under ash/chrome.
For the keyboard to be completely functional, an implementation of
onTextInputBoxFocused will also be necessary. That will be provided in a
follow up CL.
BUG=380125
R=ben@chromium.org, bshe@chromium.org, oshima@chromium.org
Review URL: https://codereview.chromium.org/335793005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278687 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | athena/athena.gyp | 26 | ||||
-rw-r--r-- | athena/common/DEPS | 4 | ||||
-rw-r--r-- | athena/common/fill_layout_manager.cc | 46 | ||||
-rw-r--r-- | athena/common/fill_layout_manager.h | 36 | ||||
-rw-r--r-- | athena/main/DEPS | 1 | ||||
-rw-r--r-- | athena/main/athena_main.cc | 8 | ||||
-rw-r--r-- | athena/main/athena_main.gyp | 1 | ||||
-rw-r--r-- | athena/screen/screen_manager_impl.cc | 38 | ||||
-rw-r--r-- | athena/virtual_keyboard/DEPS | 9 | ||||
-rw-r--r-- | athena/virtual_keyboard/public/DEPS | 4 | ||||
-rw-r--r-- | athena/virtual_keyboard/public/virtual_keyboard_bindings.h | 25 | ||||
-rw-r--r-- | athena/virtual_keyboard/public/virtual_keyboard_manager.h | 29 | ||||
-rw-r--r-- | athena/virtual_keyboard/virtual_keyboard_bindings_impl.cc | 191 | ||||
-rw-r--r-- | athena/virtual_keyboard/virtual_keyboard_manager_impl.cc | 125 | ||||
-rw-r--r-- | athena/virtual_keyboard/vk_message_handler.cc | 57 | ||||
-rw-r--r-- | athena/virtual_keyboard/vk_message_handler.h | 36 | ||||
-rw-r--r-- | athena/virtual_keyboard/vk_webui_controller.cc | 101 | ||||
-rw-r--r-- | athena/virtual_keyboard/vk_webui_controller.h | 52 |
18 files changed, 745 insertions, 44 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp index 6bdc07b..65ed34e 100644 --- a/athena/athena.gyp +++ b/athena/athena.gyp @@ -31,8 +31,10 @@ 'activity/public/activity_manager.h', 'activity/public/activity_view_manager.h', 'activity/public/activity_view_model.h', - # move athena_export.h to common/ + # move athena_export.h to common/ 'athena_export.h', + 'common/fill_layout_manager.cc', + 'common/fill_layout_manager.h', 'common/switches.cc', 'common/switches.h', 'home/app_list_view_delegate.cc', @@ -40,11 +42,11 @@ 'home/home_card_impl.cc', 'home/public/app_model_builder.h', 'home/public/home_card.h', - 'input/public/input_manager.h', - 'input/public/accelerator_manager.h', - 'input/input_manager_impl.cc', - 'input/accelerator_manager_impl.cc', - 'input/accelerator_manager_impl.h', + 'input/accelerator_manager_impl.cc', + 'input/accelerator_manager_impl.h', + 'input/input_manager_impl.cc', + 'input/public/input_manager.h', + 'input/public/accelerator_manager.h', 'screen/background_controller.cc', 'screen/background_controller.h', 'screen/public/screen_manager.h', @@ -62,8 +64,12 @@ 'type': 'static_library', 'dependencies': [ 'athena_lib', + '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../content/content.gyp:content_browser', '../ui/app_list/app_list.gyp:app_list', + '../ui/keyboard/keyboard.gyp:keyboard', + '../ui/keyboard/keyboard.gyp:keyboard_resources', + '../third_party/WebKit/public/blink.gyp:blink', '../ui/views/controls/webview/webview.gyp:webview', '../skia/skia.gyp:skia', ], @@ -79,6 +85,14 @@ 'content/app_activity.cc', 'content/web_activity.h', 'content/web_activity.cc', + 'virtual_keyboard/public/virtual_keyboard_bindings.h', + 'virtual_keyboard/public/virtual_keyboard_manager.h', + 'virtual_keyboard/virtual_keyboard_bindings_impl.cc', + 'virtual_keyboard/virtual_keyboard_manager_impl.cc', + 'virtual_keyboard/vk_message_handler.cc', + 'virtual_keyboard/vk_message_handler.h', + 'virtual_keyboard/vk_webui_controller.cc', + 'virtual_keyboard/vk_webui_controller.h', ], }, { diff --git a/athena/common/DEPS b/athena/common/DEPS new file mode 100644 index 0000000..716fe60 --- /dev/null +++ b/athena/common/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+athena/athena_export.h", + "+ui/aura", +] diff --git a/athena/common/fill_layout_manager.cc b/athena/common/fill_layout_manager.cc new file mode 100644 index 0000000..aa5517b --- /dev/null +++ b/athena/common/fill_layout_manager.cc @@ -0,0 +1,46 @@ +// 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/common/fill_layout_manager.h" + +#include "base/logging.h" +#include "ui/aura/window.h" + +namespace athena { + +FillLayoutManager::FillLayoutManager(aura::Window* container) + : container_(container) { + DCHECK(container_); +} + +FillLayoutManager::~FillLayoutManager() { +} + +void FillLayoutManager::OnWindowResized() { + gfx::Rect full_bounds = gfx::Rect(container_->bounds().size()); + for (aura::Window::Windows::const_iterator iter = + container_->children().begin(); + iter != container_->children().end(); + ++iter) { + SetChildBoundsDirect(*iter, full_bounds); + } +} + +void FillLayoutManager::OnWindowAddedToLayout(aura::Window* child) { + SetChildBoundsDirect(child, (gfx::Rect(container_->bounds().size()))); +} + +void FillLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { +} +void FillLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { +} +void FillLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, + bool visible) { +} +void FillLayoutManager::SetChildBounds(aura::Window* child, + const gfx::Rect& requested_bounds) { + // Ignore SetBounds request. +} + +} // namespace athena diff --git a/athena/common/fill_layout_manager.h b/athena/common/fill_layout_manager.h new file mode 100644 index 0000000..a5df2d4 --- /dev/null +++ b/athena/common/fill_layout_manager.h @@ -0,0 +1,36 @@ +// 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. + +#ifndef ATHENA_COMMON_FILL_LAYOUT_MANAGER_H_ +#define ATHENA_COMMON_FILL_LAYOUT_MANAGER_H_ + +#include "athena/athena_export.h" +#include "ui/aura/layout_manager.h" + +namespace athena { + +class ATHENA_EXPORT FillLayoutManager : public aura::LayoutManager { + public: + explicit FillLayoutManager(aura::Window* container); + virtual ~FillLayoutManager(); + + // aura::LayoutManager: + virtual void OnWindowResized() OVERRIDE; + virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE; + virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE; + virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE; + virtual void OnChildWindowVisibilityChanged(aura::Window* child, + bool visible) OVERRIDE; + virtual void SetChildBounds(aura::Window* child, + const gfx::Rect& requested_bounds) OVERRIDE; + + private: + aura::Window* container_; + + DISALLOW_COPY_AND_ASSIGN(FillLayoutManager); +}; + +} // namespace athena + +#endif // ATHENA_COMMON_FILL_LAYOUT_MANAGER_H_ diff --git a/athena/main/DEPS b/athena/main/DEPS index b03fcf4..afb6950 100644 --- a/athena/main/DEPS +++ b/athena/main/DEPS @@ -5,6 +5,7 @@ include_rules = [ "+athena/input/public", "+athena/screen/public", "+athena/task/public", + "+athena/virtual_keyboard/public", "+athena/wm/public", "+content/public", "+ui/aura", diff --git a/athena/main/athena_main.cc b/athena/main/athena_main.cc index dd6673c..6968187 100644 --- a/athena/main/athena_main.cc +++ b/athena/main/athena_main.cc @@ -14,6 +14,8 @@ #include "athena/main/athena_launcher.h" #include "athena/main/placeholder.h" #include "athena/main/url_search_provider.h" +#include "athena/virtual_keyboard/public/virtual_keyboard_bindings.h" +#include "athena/virtual_keyboard/public/virtual_keyboard_manager.h" #include "base/command_line.h" #include "base/file_util.h" #include "content/public/app/content_main.h" @@ -56,6 +58,8 @@ class AthenaBrowserMainDelegate : public apps::ShellBrowserMainDelegate { new athena::ContentAppModelBuilder(context)); athena::HomeCard::Get()->RegisterSearchProvider( new athena::UrlSearchProvider(context)); + athena::VirtualKeyboardManager::Create(context); + CreateTestPages(context); } @@ -82,7 +86,9 @@ class AthenaRendererMainDelegate : public apps::ShellRendererMainDelegate { // apps::ShellRendererMainDelegate: virtual void OnThreadStarted(content::RenderThread* thread) OVERRIDE {} - virtual void OnViewCreated(content::RenderView* render_view) OVERRIDE {} + virtual void OnViewCreated(content::RenderView* render_view) OVERRIDE { + athena::VirtualKeyboardBindings::Create(render_view); + } DISALLOW_COPY_AND_ASSIGN(AthenaRendererMainDelegate); }; diff --git a/athena/main/athena_main.gyp b/athena/main/athena_main.gyp index 09dc197..0b0e718 100644 --- a/athena/main/athena_main.gyp +++ b/athena/main/athena_main.gyp @@ -17,6 +17,7 @@ '../../skia/skia.gyp:skia', '../../ui/accessibility/accessibility.gyp:ax_gen', '../../ui/app_list/app_list.gyp:app_list', + '../../ui/keyboard/keyboard.gyp:keyboard', '../../ui/views/views.gyp:views', '../../url/url.gyp:url_lib', ], diff --git a/athena/screen/screen_manager_impl.cc b/athena/screen/screen_manager_impl.cc index 6ea40ae..4fd24e5 100644 --- a/athena/screen/screen_manager_impl.cc +++ b/athena/screen/screen_manager_impl.cc @@ -4,6 +4,7 @@ #include "athena/screen/public/screen_manager.h" +#include "athena/common/fill_layout_manager.h" #include "athena/input/public/accelerator_manager.h" #include "athena/screen/background_controller.h" #include "athena/screen/screen_accelerator_handler.h" @@ -21,43 +22,6 @@ namespace { ScreenManager* instance = NULL; -// TODO(oshima): There seems to be a couple of private implementation which does -// the same. -// Consider consolidating and reuse it. -class FillLayoutManager : public aura::LayoutManager { - public: - explicit FillLayoutManager(aura::Window* container) : container_(container) { - DCHECK(container_); - } - - // aura::LayoutManager: - virtual void OnWindowResized() OVERRIDE { - gfx::Rect full_bounds = gfx::Rect(container_->bounds().size()); - for (aura::Window::Windows::const_iterator iter = - container_->children().begin(); - iter != container_->children().end(); - ++iter) { - SetChildBoundsDirect(*iter, full_bounds); - } - } - virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { - SetChildBoundsDirect(child, (gfx::Rect(container_->bounds().size()))); - } - virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} - virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} - virtual void OnChildWindowVisibilityChanged(aura::Window* child, - bool visible) OVERRIDE {} - virtual void SetChildBounds(aura::Window* child, - const gfx::Rect& requested_bounds) OVERRIDE { - // Ignore SetBounds request. - } - - private: - aura::Window* container_; - - DISALLOW_COPY_AND_ASSIGN(FillLayoutManager); -}; - class AthenaWindowTreeClient : public aura::client::WindowTreeClient { public: explicit AthenaWindowTreeClient(aura::Window* container) diff --git a/athena/virtual_keyboard/DEPS b/athena/virtual_keyboard/DEPS new file mode 100644 index 0000000..371e353 --- /dev/null +++ b/athena/virtual_keyboard/DEPS @@ -0,0 +1,9 @@ +include_rules = [ + "+athena/screen", + "+content/public", + "+gin", + "+grit", + "+ui/aura", + "+ui/keyboard", + "+third_party/WebKit", +] diff --git a/athena/virtual_keyboard/public/DEPS b/athena/virtual_keyboard/public/DEPS new file mode 100644 index 0000000..12385bd --- /dev/null +++ b/athena/virtual_keyboard/public/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+athena/athena_export.h", + "-athena/virtual_keyboard", +] diff --git a/athena/virtual_keyboard/public/virtual_keyboard_bindings.h b/athena/virtual_keyboard/public/virtual_keyboard_bindings.h new file mode 100644 index 0000000..921699f --- /dev/null +++ b/athena/virtual_keyboard/public/virtual_keyboard_bindings.h @@ -0,0 +1,25 @@ +// 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. + +#ifndef ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_BINDINGS_H_ +#define ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_BINDINGS_H_ + +#include "athena/athena_export.h" + +namespace content { +class RenderView; +} + +namespace athena { + +// This provides the necessary bindings for the virtualKeyboardPrivate API. +class ATHENA_EXPORT VirtualKeyboardBindings { + public: + // Creates the bindings for |render_view|. + static VirtualKeyboardBindings* Create(content::RenderView* render_view); +}; + +} // namespace athena + +#endif // ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_BINDINGS_H_ diff --git a/athena/virtual_keyboard/public/virtual_keyboard_manager.h b/athena/virtual_keyboard/public/virtual_keyboard_manager.h new file mode 100644 index 0000000..4446697 --- /dev/null +++ b/athena/virtual_keyboard/public/virtual_keyboard_manager.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_MANAGER_H_ +#define ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_MANAGER_H_ + +#include "athena/athena_export.h" + +namespace aura { +class Window; +} + +namespace content { +class BrowserContext; +} + +namespace athena { + +class ATHENA_EXPORT VirtualKeyboardManager { + public: + static VirtualKeyboardManager* Create(content::BrowserContext* context); + static VirtualKeyboardManager* Get(); + static void Shutdown(); +}; + +} // namespace athena + +#endif // ATHENA_VIRTUAL_KEYBOARD_PUBLIC_VIRTUAL_KEYBOARD_MANAGER_H_ 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 0000000..55fdfc9 --- /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 diff --git a/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc b/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc new file mode 100644 index 0000000..d6bea69 --- /dev/null +++ b/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc @@ -0,0 +1,125 @@ +// 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_manager.h" + +#include "athena/common/fill_layout_manager.h" +#include "athena/screen/public/screen_manager.h" +#include "athena/virtual_keyboard/vk_webui_controller.h" +#include "base/bind.h" +#include "base/memory/singleton.h" +#include "base/values.h" +#include "content/public/browser/browser_context.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/layout_manager.h" +#include "ui/aura/window.h" +#include "ui/keyboard/keyboard.h" +#include "ui/keyboard/keyboard_constants.h" +#include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_controller_proxy.h" +#include "ui/keyboard/keyboard_util.h" + +namespace athena { + +namespace { + +VirtualKeyboardManager* instance; + +// A very basic and simple implementation of KeyboardControllerProxy. +class BasicKeyboardControllerProxy : public keyboard::KeyboardControllerProxy { + public: + BasicKeyboardControllerProxy(content::BrowserContext* context, + aura::Window* root_window) + : browser_context_(context), root_window_(root_window) {} + virtual ~BasicKeyboardControllerProxy() {} + + // keyboard::KeyboardControllerProxy: + virtual ui::InputMethod* GetInputMethod() OVERRIDE { + ui::InputMethod* input_method = + root_window_->GetProperty(aura::client::kRootWindowInputMethodKey); + return input_method; + } + + virtual void RequestAudioInput( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) OVERRIDE {} + + virtual content::BrowserContext* GetBrowserContext() OVERRIDE { + return browser_context_; + } + + private: + content::BrowserContext* browser_context_; + aura::Window* root_window_; + + DISALLOW_COPY_AND_ASSIGN(BasicKeyboardControllerProxy); +}; + +class VirtualKeyboardManagerImpl : public VirtualKeyboardManager { + public: + explicit VirtualKeyboardManagerImpl(content::BrowserContext* browser_context) + : browser_context_(browser_context), + container_(NULL) { + CHECK(!instance); + instance = this; + Init(); + } + + virtual ~VirtualKeyboardManagerImpl() { + CHECK_EQ(this, instance); + instance = NULL; + + keyboard::KeyboardController::ResetInstance(NULL); + } + + private: + void Init() { + container_ = athena::ScreenManager::Get()->CreateContainer( + "VirtualKeyboardContainer"); + container_->SetLayoutManager(new FillLayoutManager(container_)); + keyboard::SetOverrideContentUrl(GURL(keyboard::kKeyboardURL)); + + keyboard_controller_.reset(new keyboard::KeyboardController( + new BasicKeyboardControllerProxy(browser_context_, + container_->GetRootWindow()))); + keyboard::KeyboardController::ResetInstance(keyboard_controller_.get()); + aura::Window* kb_container = keyboard_controller_->GetContainerWindow(); + container_->AddChild(kb_container); + kb_container->Show(); + + content::WebUIControllerFactory::RegisterFactory( + VKWebUIControllerFactory::GetInstance()); + } + + content::BrowserContext* browser_context_; + aura::Window* container_; + scoped_ptr<keyboard::KeyboardController> keyboard_controller_; + + DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardManagerImpl); +}; + +} // namespace + +// static +VirtualKeyboardManager* VirtualKeyboardManager::Create( + content::BrowserContext* browser_context) { + CHECK(!instance); + keyboard::InitializeKeyboard(); + new VirtualKeyboardManagerImpl(browser_context); + CHECK(instance); + return instance; +} + +VirtualKeyboardManager* VirtualKeyboardManager::Get() { + return instance; +} + +void VirtualKeyboardManager::Shutdown() { + CHECK(instance); + delete instance; + CHECK(!instance); +} + +} // namespace athena diff --git a/athena/virtual_keyboard/vk_message_handler.cc b/athena/virtual_keyboard/vk_message_handler.cc new file mode 100644 index 0000000..fbd1e79 --- /dev/null +++ b/athena/virtual_keyboard/vk_message_handler.cc @@ -0,0 +1,57 @@ +// 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/vk_message_handler.h" + +#include "athena/screen/public/screen_manager.h" +#include "base/bind.h" +#include "base/values.h" +#include "content/public/browser/web_ui.h" +#include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_util.h" + +namespace athena { + +VKMessageHandler::VKMessageHandler() { +} +VKMessageHandler::~VKMessageHandler() { +} + +void VKMessageHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "sendKeyEvent", + base::Bind(&VKMessageHandler::SendKeyEvent, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "hideKeyboard", + base::Bind(&VKMessageHandler::HideKeyboard, base::Unretained(this))); +} + +void VKMessageHandler::SendKeyEvent(const base::ListValue* params) { + std::string type; + int char_value; + int key_code; + std::string key_name; + int modifiers; + if (!params->GetString(0, &type)) + return; + if (!params->GetInteger(1, &char_value)) + return; + if (!params->GetInteger(2, &key_code)) + return; + if (!params->GetString(3, &key_name)) + return; + if (!params->GetInteger(4, &modifiers)) + return; + + aura::Window* window = ScreenManager::Get()->GetContext(); + keyboard::SendKeyEvent( + type, char_value, key_code, key_name, modifiers, window->GetHost()); +} + +void VKMessageHandler::HideKeyboard(const base::ListValue* params) { + keyboard::KeyboardController::GetInstance()->HideKeyboard( + keyboard::KeyboardController::HIDE_REASON_MANUAL); +} + +} // namespace athena diff --git a/athena/virtual_keyboard/vk_message_handler.h b/athena/virtual_keyboard/vk_message_handler.h new file mode 100644 index 0000000..1fc6c7f3 --- /dev/null +++ b/athena/virtual_keyboard/vk_message_handler.h @@ -0,0 +1,36 @@ +// 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. + +#ifndef ATHENA_VIRTUAL_KEYBOARD_VK_MESSAGE_HANDLER_H_ +#define ATHENA_VIRTUAL_KEYBOARD_VK_MESSAGE_HANDLER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace base { +class ListValue; +} + +namespace athena { + +// Processes WebUI messages for chrome://keyboard. +class VKMessageHandler : public content::WebUIMessageHandler { + public: + VKMessageHandler(); + virtual ~VKMessageHandler(); + + private: + // WebUI message callbacks. + void SendKeyEvent(const base::ListValue* params); + void HideKeyboard(const base::ListValue* params); + + // content::WebUIMessageHandler: + virtual void RegisterMessages() OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(VKMessageHandler); +}; + +} // namespace athena + +#endif // ATHENA_VIRTUAL_KEYBOARD_VK_MESSAGE_HANDLER_H_ diff --git a/athena/virtual_keyboard/vk_webui_controller.cc b/athena/virtual_keyboard/vk_webui_controller.cc new file mode 100644 index 0000000..d26b2c9 --- /dev/null +++ b/athena/virtual_keyboard/vk_webui_controller.cc @@ -0,0 +1,101 @@ +// 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/vk_webui_controller.h" + +#include "athena/virtual_keyboard/vk_message_handler.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui_data_source.h" +#include "grit/keyboard_resources.h" +#include "grit/keyboard_resources_map.h" +#include "ui/keyboard/keyboard_constants.h" +#include "ui/keyboard/keyboard_util.h" + +namespace athena { + +namespace { + +content::WebUIDataSource* CreateKeyboardUIDataSource() { + content::WebUIDataSource* source = + content::WebUIDataSource::Create(keyboard::kKeyboardHost); + + size_t count = 0; + const GritResourceMap* resources = + keyboard::GetKeyboardExtensionResources(&count); + source->SetDefaultResource(IDR_KEYBOARD_INDEX); + + const std::string keyboard_host = + base::StringPrintf("%s/", keyboard::kKeyboardHost); + for (size_t i = 0; i < count; ++i) { + size_t offset = 0; + if (StartsWithASCII(std::string(resources[i].name), keyboard_host, false)) + offset = keyboard_host.length(); + source->AddResourcePath(resources[i].name + offset, resources[i].value); + } + return source; +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// VKWebUIController: + +VKWebUIController::VKWebUIController(content::WebUI* web_ui) + : WebUIController(web_ui) { + content::BrowserContext* browser_context = + web_ui->GetWebContents()->GetBrowserContext(); + web_ui->AddMessageHandler(new VKMessageHandler()); + content::WebUIDataSource::Add(browser_context, CreateKeyboardUIDataSource()); +} + +VKWebUIController::~VKWebUIController() { +} + +//////////////////////////////////////////////////////////////////////////////// +// VKWebUIControllerFactory: + +content::WebUI::TypeID VKWebUIControllerFactory::GetWebUIType( + content::BrowserContext* browser_context, + const GURL& url) const { + if (url == GURL(keyboard::kKeyboardURL)) + return const_cast<VKWebUIControllerFactory*>(this); + + return content::WebUI::kNoWebUI; +} + +bool VKWebUIControllerFactory::UseWebUIForURL( + content::BrowserContext* browser_context, + const GURL& url) const { + return GetWebUIType(browser_context, url) != content::WebUI::kNoWebUI; +} + +bool VKWebUIControllerFactory::UseWebUIBindingsForURL( + content::BrowserContext* browser_context, + const GURL& url) const { + return UseWebUIForURL(browser_context, url); +} + +content::WebUIController* VKWebUIControllerFactory::CreateWebUIControllerForURL( + content::WebUI* web_ui, + const GURL& url) const { + if (url == GURL(keyboard::kKeyboardURL)) + return new VKWebUIController(web_ui); + return NULL; +} + +// static +VKWebUIControllerFactory* VKWebUIControllerFactory::GetInstance() { + return Singleton<VKWebUIControllerFactory>::get(); +} + +// protected +VKWebUIControllerFactory::VKWebUIControllerFactory() { +} + +VKWebUIControllerFactory::~VKWebUIControllerFactory() { +} + +} // namespace athena diff --git a/athena/virtual_keyboard/vk_webui_controller.h b/athena/virtual_keyboard/vk_webui_controller.h new file mode 100644 index 0000000..c2c6ecc --- /dev/null +++ b/athena/virtual_keyboard/vk_webui_controller.h @@ -0,0 +1,52 @@ +// 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. + +#ifndef ATHENA_VIRTUAL_KEYBOARD_VK_WEBUI_CONTROLLER_H_ +#define ATHENA_VIRTUAL_KEYBOARD_VK_WEBUI_CONTROLLER_H_ + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "content/public/browser/web_ui_controller.h" +#include "content/public/browser/web_ui_controller_factory.h" + +namespace athena { + +class VKWebUIController : public content::WebUIController { + public: + explicit VKWebUIController(content::WebUI* web_ui); + virtual ~VKWebUIController(); + + private: + DISALLOW_COPY_AND_ASSIGN(VKWebUIController); +}; + +class VKWebUIControllerFactory : public content::WebUIControllerFactory { + public: + // WebUIControllerFactory: + virtual content::WebUI::TypeID GetWebUIType( + content::BrowserContext* browser_context, + const GURL& url) const OVERRIDE; + virtual bool UseWebUIForURL(content::BrowserContext* browser_context, + const GURL& url) const OVERRIDE; + virtual bool UseWebUIBindingsForURL(content::BrowserContext* browser_context, + const GURL& url) const OVERRIDE; + virtual content::WebUIController* CreateWebUIControllerForURL( + content::WebUI* web_ui, + const GURL& url) const OVERRIDE; + + static VKWebUIControllerFactory* GetInstance(); + + protected: + VKWebUIControllerFactory(); + virtual ~VKWebUIControllerFactory(); + + private: + friend struct DefaultSingletonTraits<VKWebUIControllerFactory>; + + DISALLOW_COPY_AND_ASSIGN(VKWebUIControllerFactory); +}; + +} // namespace athena + +#endif // ATHENA_VIRTUAL_KEYBOARD_VK_WEBUI_CONTROLLER_H_ |