| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/ash/ash_keyboard_controller_proxy.h" | |
| 6 | |
| 7 #include "ash/shell.h" | |
| 8 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" | |
| 9 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | |
| 10 #include "content/public/browser/host_zoom_map.h" | |
| 11 #include "content/public/browser/render_process_host.h" | |
| 12 #include "content/public/browser/render_view_host.h" | |
| 13 #include "content/public/browser/site_instance.h" | |
| 14 #include "content/public/browser/web_contents.h" | |
| 15 #include "extensions/browser/event_router.h" | |
| 16 #include "extensions/browser/extension_registry.h" | |
| 17 #include "extensions/browser/view_type_utils.h" | |
| 18 #include "extensions/common/api/virtual_keyboard_private.h" | |
| 19 #include "extensions/common/constants.h" | |
| 20 #include "extensions/common/extension_messages.h" | |
| 21 #include "ipc/ipc_message_macros.h" | |
| 22 #include "ui/aura/window.h" | |
| 23 #include "ui/aura/window_event_dispatcher.h" | |
| 24 #include "ui/aura/window_tree_host.h" | |
| 25 #include "ui/compositor/scoped_layer_animation_settings.h" | |
| 26 #include "ui/keyboard/keyboard_controller.h" | |
| 27 #include "ui/keyboard/keyboard_controller_observer.h" | |
| 28 | |
| 29 namespace virtual_keyboard_private = extensions::api::virtual_keyboard_private; | |
| 30 | |
| 31 typedef virtual_keyboard_private::OnTextInputBoxFocused::Context Context; | |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 const char* kVirtualKeyboardExtensionID = "mppnpdlheglhdfmldimlhpnegondlapf"; | |
| 36 | |
| 37 virtual_keyboard_private::OnTextInputBoxFocusedType | |
| 38 TextInputTypeToGeneratedInputTypeEnum(ui::TextInputType type) { | |
| 39 switch (type) { | |
| 40 case ui::TEXT_INPUT_TYPE_NONE: | |
| 41 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_NONE; | |
| 42 case ui::TEXT_INPUT_TYPE_PASSWORD: | |
| 43 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_PASSWORD; | |
| 44 case ui::TEXT_INPUT_TYPE_EMAIL: | |
| 45 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_EMAIL; | |
| 46 case ui::TEXT_INPUT_TYPE_NUMBER: | |
| 47 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_NUMBER; | |
| 48 case ui::TEXT_INPUT_TYPE_TELEPHONE: | |
| 49 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_TEL; | |
| 50 case ui::TEXT_INPUT_TYPE_URL: | |
| 51 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_URL; | |
| 52 case ui::TEXT_INPUT_TYPE_DATE: | |
| 53 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_DATE; | |
| 54 case ui::TEXT_INPUT_TYPE_TEXT: | |
| 55 case ui::TEXT_INPUT_TYPE_SEARCH: | |
| 56 case ui::TEXT_INPUT_TYPE_DATE_TIME: | |
| 57 case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL: | |
| 58 case ui::TEXT_INPUT_TYPE_MONTH: | |
| 59 case ui::TEXT_INPUT_TYPE_TIME: | |
| 60 case ui::TEXT_INPUT_TYPE_WEEK: | |
| 61 case ui::TEXT_INPUT_TYPE_TEXT_AREA: | |
| 62 case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE: | |
| 63 case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD: | |
| 64 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_TEXT; | |
| 65 } | |
| 66 NOTREACHED(); | |
| 67 return virtual_keyboard_private::ON_TEXT_INPUT_BOX_FOCUSED_TYPE_NONE; | |
| 68 } | |
| 69 | |
| 70 class AshKeyboardControllerObserver | |
| 71 : public keyboard::KeyboardControllerObserver { | |
| 72 public: | |
| 73 explicit AshKeyboardControllerObserver(content::BrowserContext* context) | |
| 74 : context_(context) {} | |
| 75 ~AshKeyboardControllerObserver() override {} | |
| 76 | |
| 77 // KeyboardControllerObserver overrides: | |
| 78 void OnKeyboardBoundsChanging(const gfx::Rect& bounds) override { | |
| 79 extensions::EventRouter* router = extensions::EventRouter::Get(context_); | |
| 80 | |
| 81 if (!router->HasEventListener( | |
| 82 virtual_keyboard_private::OnBoundsChanged::kEventName)) { | |
| 83 return; | |
| 84 } | |
| 85 | |
| 86 scoped_ptr<base::ListValue> event_args(new base::ListValue()); | |
| 87 scoped_ptr<base::DictionaryValue> new_bounds(new base::DictionaryValue()); | |
| 88 new_bounds->SetInteger("left", bounds.x()); | |
| 89 new_bounds->SetInteger("top", bounds.y()); | |
| 90 new_bounds->SetInteger("width", bounds.width()); | |
| 91 new_bounds->SetInteger("height", bounds.height()); | |
| 92 event_args->Append(new_bounds.release()); | |
| 93 | |
| 94 scoped_ptr<extensions::Event> event(new extensions::Event( | |
| 95 extensions::events::VIRTUAL_KEYBOARD_PRIVATE_ON_BOUNDS_CHANGED, | |
| 96 virtual_keyboard_private::OnBoundsChanged::kEventName, | |
| 97 event_args.Pass())); | |
| 98 event->restrict_to_browser_context = context_; | |
| 99 router->BroadcastEvent(event.Pass()); | |
| 100 } | |
| 101 | |
| 102 private: | |
| 103 content::BrowserContext* context_; | |
| 104 | |
| 105 DISALLOW_COPY_AND_ASSIGN(AshKeyboardControllerObserver); | |
| 106 }; | |
| 107 | |
| 108 } // namespace | |
| 109 | |
| 110 AshKeyboardControllerProxy::AshKeyboardControllerProxy( | |
| 111 content::BrowserContext* context) | |
| 112 : keyboard::KeyboardControllerProxy(context) { | |
| 113 } | |
| 114 | |
| 115 AshKeyboardControllerProxy::~AshKeyboardControllerProxy() { | |
| 116 DCHECK(!keyboard_controller()); | |
| 117 } | |
| 118 | |
| 119 ui::InputMethod* AshKeyboardControllerProxy::GetInputMethod() { | |
| 120 aura::Window* root_window = ash::Shell::GetTargetRootWindow(); | |
| 121 DCHECK(root_window); | |
| 122 return root_window->GetHost()->GetInputMethod(); | |
| 123 } | |
| 124 | |
| 125 void AshKeyboardControllerProxy::RequestAudioInput( | |
| 126 content::WebContents* web_contents, | |
| 127 const content::MediaStreamRequest& request, | |
| 128 const content::MediaResponseCallback& callback) { | |
| 129 const extensions::Extension* extension = NULL; | |
| 130 GURL origin(request.security_origin); | |
| 131 if (origin.SchemeIs(extensions::kExtensionScheme)) { | |
| 132 const extensions::ExtensionRegistry* registry = | |
| 133 extensions::ExtensionRegistry::Get(browser_context()); | |
| 134 extension = registry->enabled_extensions().GetByID(origin.host()); | |
| 135 DCHECK(extension); | |
| 136 } | |
| 137 | |
| 138 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest( | |
| 139 web_contents, request, callback, extension); | |
| 140 } | |
| 141 | |
| 142 void AshKeyboardControllerProxy::SetupWebContents( | |
| 143 content::WebContents* contents) { | |
| 144 extensions::SetViewType(contents, extensions::VIEW_TYPE_VIRTUAL_KEYBOARD); | |
| 145 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( | |
| 146 contents); | |
| 147 Observe(contents); | |
| 148 } | |
| 149 | |
| 150 void AshKeyboardControllerProxy::SetController( | |
| 151 keyboard::KeyboardController* controller) { | |
| 152 // During KeyboardController destruction, controller can be set to null. | |
| 153 if (!controller) { | |
| 154 DCHECK(keyboard_controller()); | |
| 155 keyboard_controller()->RemoveObserver(observer_.get()); | |
| 156 KeyboardControllerProxy::SetController(nullptr); | |
| 157 return; | |
| 158 } | |
| 159 KeyboardControllerProxy::SetController(controller); | |
| 160 observer_.reset(new AshKeyboardControllerObserver(browser_context())); | |
| 161 keyboard_controller()->AddObserver(observer_.get()); | |
| 162 } | |
| 163 | |
| 164 void AshKeyboardControllerProxy::RenderViewCreated( | |
| 165 content::RenderViewHost* render_view_host) { | |
| 166 content::HostZoomMap* zoom_map = | |
| 167 content::HostZoomMap::GetDefaultForBrowserContext(browser_context()); | |
| 168 DCHECK(zoom_map); | |
| 169 int render_process_id = render_view_host->GetProcess()->GetID(); | |
| 170 int render_view_id = render_view_host->GetRoutingID(); | |
| 171 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, 0); | |
| 172 } | |
| 173 | |
| 174 void AshKeyboardControllerProxy::ShowKeyboardContainer( | |
| 175 aura::Window* container) { | |
| 176 // TODO(bshe): Implement logic to decide which root window should display | |
| 177 // virtual keyboard. http://crbug.com/303429 | |
| 178 if (container->GetRootWindow() != ash::Shell::GetPrimaryRootWindow()) | |
| 179 NOTIMPLEMENTED(); | |
| 180 | |
| 181 KeyboardControllerProxy::ShowKeyboardContainer(container); | |
| 182 } | |
| 183 | |
| 184 void AshKeyboardControllerProxy::SetUpdateInputType(ui::TextInputType type) { | |
| 185 // TODO(bshe): Need to check the affected window's profile once multi-profile | |
| 186 // is supported. | |
| 187 extensions::EventRouter* router = | |
| 188 extensions::EventRouter::Get(browser_context()); | |
| 189 | |
| 190 if (!router->HasEventListener( | |
| 191 virtual_keyboard_private::OnTextInputBoxFocused::kEventName)) { | |
| 192 return; | |
| 193 } | |
| 194 | |
| 195 scoped_ptr<base::ListValue> event_args(new base::ListValue()); | |
| 196 scoped_ptr<base::DictionaryValue> input_context(new base::DictionaryValue()); | |
| 197 input_context->SetString("type", | |
| 198 virtual_keyboard_private::ToString( | |
| 199 TextInputTypeToGeneratedInputTypeEnum(type))); | |
| 200 event_args->Append(input_context.release()); | |
| 201 | |
| 202 scoped_ptr<extensions::Event> event(new extensions::Event( | |
| 203 extensions::events::VIRTUAL_KEYBOARD_PRIVATE_ON_TEXT_INPUT_BOX_FOCUSED, | |
| 204 virtual_keyboard_private::OnTextInputBoxFocused::kEventName, | |
| 205 event_args.Pass())); | |
| 206 event->restrict_to_browser_context = browser_context(); | |
| 207 router->DispatchEventToExtension(kVirtualKeyboardExtensionID, event.Pass()); | |
| 208 } | |
| OLD | NEW |