diff options
Diffstat (limited to 'ui')
21 files changed, 872 insertions, 729 deletions
diff --git a/ui/keyboard/BUILD.gn b/ui/keyboard/BUILD.gn index a62fc8b..4600fbc 100644 --- a/ui/keyboard/BUILD.gn +++ b/ui/keyboard/BUILD.gn @@ -9,20 +9,16 @@ import("//tools/grit/grit_rule.gni") component("keyboard") { sources = [ - "keyboard.cc", - "keyboard.h", - "keyboard_constants.cc", - "keyboard_constants.h", "keyboard_controller.cc", "keyboard_controller.h", "keyboard_controller_observer.h", - "keyboard_controller_proxy.cc", - "keyboard_controller_proxy.h", "keyboard_export.h", "keyboard_layout_manager.cc", "keyboard_layout_manager.h", "keyboard_switches.cc", "keyboard_switches.h", + "keyboard_ui.cc", + "keyboard_ui.h", "keyboard_util.cc", "keyboard_util.h", ] @@ -30,13 +26,48 @@ component("keyboard") { defines = [ "KEYBOARD_IMPLEMENTATION" ] deps = [ + "//base", + "//base/third_party/dynamic_annotations", + "//media", + "//skia", + "//ui/aura", + "//ui/base", + "//ui/base/ime", + "//ui/compositor", + "//ui/events", + "//ui/events:dom_keycode_converter", + "//ui/events:events_base", + "//ui/gfx", + "//ui/gfx/geometry", + ] + + if (use_ozone) { + deps += [ "//ui/ozone" ] + } +} + +component("keyboard_with_content") { + sources = [ + "content/keyboard.cc", + "content/keyboard.h", + "content/keyboard_constants.cc", + "content/keyboard_constants.h", + "content/keyboard_content_util.cc", + "content/keyboard_content_util.h", + "content/keyboard_ui_content.cc", + "content/keyboard_ui_content.h", + ] + + defines = [ "KEYBOARD_IMPLEMENTATION" ] + + deps = [ + ":keyboard", ":resources", "//base", "//base/third_party/dynamic_annotations", "//content/public/browser", "//content/public/common", "//ipc", - "//media", "//skia", "//ui/aura", "//ui/base", @@ -50,10 +81,6 @@ component("keyboard") { "//ui/wm", "//url", ] - - if (use_ozone) { - deps += [ "//ui/ozone" ] - } } grit("resources_grit") { @@ -111,8 +138,6 @@ test("keyboard_unittests") { "//base", "//base/allocator", "//base/test:test_support", - "//content", - "//media", "//skia", "//testing/gtest", "//ui/aura:test_support", @@ -124,8 +149,6 @@ test("keyboard_unittests") { "//ui/gfx", "//ui/gfx/geometry", "//ui/gl", - "//ui/resources:ui_test_pak", "//ui/wm", - "//url", ] } diff --git a/ui/keyboard/content/DEPS b/ui/keyboard/content/DEPS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ui/keyboard/content/DEPS diff --git a/ui/keyboard/keyboard.cc b/ui/keyboard/content/keyboard.cc index 4e26637..4f7da4d 100644 --- a/ui/keyboard/keyboard.cc +++ b/ui/keyboard/content/keyboard.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2015 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 "ui/keyboard/keyboard.h" +#include "ui/keyboard/content/keyboard.h" #include "base/files/file_path.h" #include "base/path_service.h" diff --git a/ui/keyboard/keyboard.h b/ui/keyboard/content/keyboard.h index 0878b7b..0878b7b 100644 --- a/ui/keyboard/keyboard.h +++ b/ui/keyboard/content/keyboard.h diff --git a/ui/keyboard/keyboard_constants.cc b/ui/keyboard/content/keyboard_constants.cc index b13a604..449f96f 100644 --- a/ui/keyboard/keyboard_constants.cc +++ b/ui/keyboard/content/keyboard_constants.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2015 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 "ui/keyboard/keyboard_constants.h" +#include "ui/keyboard/content/keyboard_constants.h" namespace keyboard { diff --git a/ui/keyboard/keyboard_constants.h b/ui/keyboard/content/keyboard_constants.h index 75607c1..6c4e661 100644 --- a/ui/keyboard/keyboard_constants.h +++ b/ui/keyboard/content/keyboard_constants.h @@ -1,9 +1,9 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2015 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 UI_KEYBOARD_KEYBOARD_CONSTANTS_H_ -#define UI_KEYBOARD_KEYBOARD_CONSTANTS_H_ +#ifndef UI_KEYBOARD_CONTENT_KEYBOARD_CONSTANTS_H_ +#define UI_KEYBOARD_CONTENT_KEYBOARD_CONSTANTS_H_ #include "ui/keyboard/keyboard_export.h" @@ -17,4 +17,4 @@ KEYBOARD_EXPORT extern const char kKeyboardHost[]; } // namespace keyboard -#endif // UI_KEYBOARD_KEYBOARD_CONSTANTS_H_ +#endif // UI_KEYBOARD_CONTENT_KEYBOARD_CONSTANTS_H_ diff --git a/ui/keyboard/content/keyboard_content_util.cc b/ui/keyboard/content/keyboard_content_util.cc new file mode 100644 index 0000000..48bb08a --- /dev/null +++ b/ui/keyboard/content/keyboard_content_util.cc @@ -0,0 +1,108 @@ +// Copyright 2015 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 "ui/keyboard/content/keyboard_content_util.h" + +#include "base/lazy_instance.h" +#include "grit/keyboard_resources.h" +#include "grit/keyboard_resources_map.h" +#include "url/gurl.h" + +namespace keyboard { +namespace { + +base::LazyInstance<GURL> g_override_content_url = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +void SetOverrideContentUrl(const GURL& url) { + g_override_content_url.Get() = url; +} + +const GURL& GetOverrideContentUrl() { + return g_override_content_url.Get(); +} + +const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { + // This looks a lot like the contents of a resource map; however it is + // necessary to have a custom path for the extension path, so the resource + // map cannot be used directly. + static const GritResourceMap kKeyboardResources[] = { + {"keyboard/locales/en.js", IDR_KEYBOARD_LOCALES_EN}, + {"keyboard/config/emoji.js", IDR_KEYBOARD_CONFIG_EMOJI}, + {"keyboard/config/hwt.js", IDR_KEYBOARD_CONFIG_HWT}, + {"keyboard/config/us.js", IDR_KEYBOARD_CONFIG_US}, + {"keyboard/emoji.css", IDR_KEYBOARD_CSS_EMOJI}, + {"keyboard/images/3dots.png", IDR_KEYBOARD_IMAGES_3_DOTS}, + {"keyboard/images/back_to_keyboard.png", + IDR_KEYBOARD_IMAGES_BACK_TO_KEYBOARD}, + {"keyboard/images/backspace.png", IDR_KEYBOARD_IMAGES_BACKSPACE}, + {"keyboard/images/car.png", IDR_KEYBOARD_IMAGES_CAR}, + {"keyboard/images/check.png", IDR_KEYBOARD_IMAGES_CHECK}, + {"keyboard/images/check_in_menu.png", IDR_KEYBOARD_IMAGES_CHECK_IN_MENU}, + {"keyboard/images/compact.png", IDR_KEYBOARD_IMAGES_COMPACT}, + {"keyboard/images/down.png", IDR_KEYBOARD_IMAGES_DOWN}, + {"keyboard/images/emoji.png", IDR_KEYBOARD_IMAGES_EMOJI}, + {"keyboard/images/emoji_car.png", IDR_KEYBOARD_IMAGES_EMOJI_CAR}, + {"keyboard/images/emoji_crown.png", IDR_KEYBOARD_IMAGES_EMOJI_CROWN}, + {"keyboard/images/emoji_emoticon.png", + IDR_KEYBOARD_IMAGES_EMOJI_EMOTICON}, + {"keyboard/images/emoji_flower.png", IDR_KEYBOARD_IMAGES_EMOJI_FLOWER}, + {"keyboard/images/emoji_hot.png", IDR_KEYBOARD_IMAGES_EMOJI_HOT}, + {"keyboard/images/emoji_recent.png", IDR_KEYBOARD_IMAGES_EMOJI_RECENT}, + {"keyboard/images/emoji_shape.png", IDR_KEYBOARD_IMAGES_EMOJI_SHAPE}, + {"keyboard/images/emoji_cat_items.png", IDR_KEYBOARD_IMAGES_CAT}, + {"keyboard/images/emoticon.png", IDR_KEYBOARD_IMAGES_EMOTICON}, + {"keyboard/images/enter.png", IDR_KEYBOARD_IMAGES_RETURN}, + {"keyboard/images/error.png", IDR_KEYBOARD_IMAGES_ERROR}, + {"keyboard/images/favorit.png", IDR_KEYBOARD_IMAGES_FAVORITE}, + {"keyboard/images/flower.png", IDR_KEYBOARD_IMAGES_FLOWER}, + {"keyboard/images/globe.png", IDR_KEYBOARD_IMAGES_GLOBE}, + {"keyboard/images/hide.png", IDR_KEYBOARD_IMAGES_HIDE}, + {"keyboard/images/hidekeyboard.png", IDR_KEYBOARD_IMAGES_HIDE_KEYBOARD}, + {"keyboard/images/keyboard.svg", IDR_KEYBOARD_IMAGES_KEYBOARD}, + {"keyboard/images/left.png", IDR_KEYBOARD_IMAGES_LEFT}, + {"keyboard/images/penci.png", IDR_KEYBOARD_IMAGES_PENCIL}, + {"keyboard/images/recent.png", IDR_KEYBOARD_IMAGES_RECENT}, + {"keyboard/images/regular_size.png", IDR_KEYBOARD_IMAGES_FULLSIZE}, + {"keyboard/images/menu.png", IDR_KEYBOARD_IMAGES_MENU}, + {"keyboard/images/pencil.png", IDR_KEYBOARD_IMAGES_PENCIL}, + {"keyboard/images/right.png", IDR_KEYBOARD_IMAGES_RIGHT}, + {"keyboard/images/search.png", IDR_KEYBOARD_IMAGES_SEARCH}, + {"keyboard/images/select_right.png", IDR_KEYBOARD_IMAGES_SELECT_RIGHT}, + {"keyboard/images/select_left.png", IDR_KEYBOARD_IMAGES_SELECT_LEFT}, + {"keyboard/images/setting.png", IDR_KEYBOARD_IMAGES_SETTINGS}, + {"keyboard/images/shift.png", IDR_KEYBOARD_IMAGES_SHIFT}, + {"keyboard/images/space.png", IDR_KEYBOARD_IMAGES_SPACE}, + {"keyboard/images/tab.png", IDR_KEYBOARD_IMAGES_TAB}, + {"keyboard/images/tab_in_fullsize.png", + IDR_KEYBOARD_IMAGES_TAB_IN_FULLSIZE}, + {"keyboard/images/triangle.png", IDR_KEYBOARD_IMAGES_TRIANGLE}, + {"keyboard/images/up.png", IDR_KEYBOARD_IMAGES_UP}, + {"keyboard/index.html", IDR_KEYBOARD_INDEX}, + {"keyboard/inputview_adapter.js", IDR_KEYBOARD_INPUTVIEW_ADAPTER}, + {"keyboard/inputview.css", IDR_KEYBOARD_INPUTVIEW_CSS}, + {"keyboard/inputview.js", IDR_KEYBOARD_INPUTVIEW_JS}, + {"keyboard/inputview_layouts/101kbd.js", IDR_KEYBOARD_LAYOUTS_101}, + {"keyboard/inputview_layouts/compactkbd-qwerty.js", + IDR_KEYBOARD_LAYOUTS_COMPACT_QWERTY}, + {"keyboard/inputview_layouts/compactkbd-numberpad.js", + IDR_KEYBOARD_LAYOUTS_COMPACT_NUMBERPAD}, + {"keyboard/inputview_layouts/emoji.js", IDR_KEYBOARD_LAYOUTS_EMOJI}, + {"keyboard/inputview_layouts/handwriting.js", IDR_KEYBOARD_LAYOUTS_HWT}, + {"keyboard/manifest.json", IDR_KEYBOARD_MANIFEST}, + {"keyboard/sounds/keypress-delete.wav", + IDR_KEYBOARD_SOUNDS_KEYPRESS_DELETE}, + {"keyboard/sounds/keypress-return.wav", + IDR_KEYBOARD_SOUNDS_KEYPRESS_RETURN}, + {"keyboard/sounds/keypress-spacebar.wav", + IDR_KEYBOARD_SOUNDS_KEYPRESS_SPACEBAR}, + {"keyboard/sounds/keypress-standard.wav", + IDR_KEYBOARD_SOUNDS_KEYPRESS_STANDARD}, + }; + *size = arraysize(kKeyboardResources); + return kKeyboardResources; +} + +} // namespace keyboard
\ No newline at end of file diff --git a/ui/keyboard/content/keyboard_content_util.h b/ui/keyboard/content/keyboard_content_util.h new file mode 100644 index 0000000..65314be --- /dev/null +++ b/ui/keyboard/content/keyboard_content_util.h @@ -0,0 +1,31 @@ +// Copyright 2015 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 UI_KEYBOARD_CONTENT_KEYBOARD_COTNENT_UTIL_H_ +#define UI_KEYBOARD_CONTENT_KEYBOARD_COTNENT_UTIL_H_ + +#include "base/strings/string16.h" +#include "ui/keyboard/keyboard_export.h" + +class GURL; + +struct GritResourceMap; + +namespace keyboard { + +// Sets the override content url. +// This is used by for input view for extension IMEs. +KEYBOARD_EXPORT void SetOverrideContentUrl(const GURL& url); + +// Gets the override content url. +KEYBOARD_EXPORT const GURL& GetOverrideContentUrl(); + +// Get the list of keyboard resources. |size| is populated with the number of +// resources in the returned array. +KEYBOARD_EXPORT const GritResourceMap* GetKeyboardExtensionResources( + size_t* size); + +} // namespace keyboard + +#endif // UI_KEYBOARD_CONTENT_KEYBOARD_COTNENT_UTIL_H_ diff --git a/ui/keyboard/content/keyboard_ui_content.cc b/ui/keyboard/content/keyboard_ui_content.cc new file mode 100644 index 0000000..010abde --- /dev/null +++ b/ui/keyboard/content/keyboard_ui_content.cc @@ -0,0 +1,321 @@ +// Copyright (c) 2013 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 "ui/keyboard/content/keyboard_ui_content.h" + +#include "base/command_line.h" +#include "base/values.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_widget_host_iterator.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_ui.h" +#include "content/public/common/bindings_policy.h" +#include "ui/aura/layout_manager.h" +#include "ui/aura/window.h" +#include "ui/base/ime/input_method.h" +#include "ui/base/ime/text_input_client.h" +#include "ui/keyboard/content/keyboard_constants.h" +#include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_switches.h" +#include "ui/keyboard/keyboard_util.h" +#include "ui/wm/core/shadow.h" + +namespace { + +// The WebContentsDelegate for the keyboard. +// The delegate deletes itself when the keyboard is destroyed. +class KeyboardContentsDelegate : public content::WebContentsDelegate, + public content::WebContentsObserver { + public: + explicit KeyboardContentsDelegate(keyboard::KeyboardUIContent* ui) + : ui_(ui) {} + ~KeyboardContentsDelegate() override {} + + private: + // Overridden from content::WebContentsDelegate: + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override { + source->GetController().LoadURL( + params.url, params.referrer, params.transition, params.extra_headers); + Observe(source); + return source; + } + + bool CanDragEnter(content::WebContents* source, + const content::DropData& data, + blink::WebDragOperationsMask operations_allowed) override { + return false; + } + + bool ShouldCreateWebContents( + content::WebContents* web_contents, + int route_id, + int main_frame_route_id, + WindowContainerType window_container_type, + const std::string& frame_name, + const GURL& target_url, + const std::string& partition_id, + content::SessionStorageNamespace* session_storage_namespace) override { + return false; + } + + bool IsPopupOrPanel(const content::WebContents* source) const override { + return true; + } + + void MoveContents(content::WebContents* source, + const gfx::Rect& pos) override { + aura::Window* keyboard = ui_->GetKeyboardWindow(); + // keyboard window must have been added to keyboard container window at this + // point. Otherwise, wrong keyboard bounds is used and may cause problem as + // described in crbug.com/367788. + DCHECK(keyboard->parent()); + // keyboard window bounds may not set to |pos| after this call. If keyboard + // is in FULL_WIDTH mode, only the height of keyboard window will be + // changed. + keyboard->SetBounds(pos); + } + + // Overridden from content::WebContentsDelegate: + void RequestMediaAccessPermission( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) override { + ui_->RequestAudioInput(web_contents, request, callback); + } + + // Overridden from content::WebContentsObserver: + void WebContentsDestroyed() override { delete this; } + + keyboard::KeyboardUIContent* ui_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardContentsDelegate); +}; + +} // namespace + +namespace keyboard { + +class WindowBoundsChangeObserver : public aura::WindowObserver { + public: + explicit WindowBoundsChangeObserver(KeyboardUIContent* ui) : ui_(ui) {} + ~WindowBoundsChangeObserver() override {} + + void AddObservedWindow(aura::Window* window) { + if (!window->HasObserver(this)) { + window->AddObserver(this); + observed_windows_.insert(window); + } + } + void RemoveAllObservedWindows() { + for (std::set<aura::Window*>::iterator it = observed_windows_.begin(); + it != observed_windows_.end(); ++it) + (*it)->RemoveObserver(this); + observed_windows_.clear(); + } + + private: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) override { + ui_->UpdateInsetsForWindow(window); + } + void OnWindowDestroyed(aura::Window* window) override { + if (window->HasObserver(this)) + window->RemoveObserver(this); + observed_windows_.erase(window); + } + + KeyboardUIContent* ui_; + std::set<aura::Window*> observed_windows_; + + DISALLOW_COPY_AND_ASSIGN(WindowBoundsChangeObserver); +}; + +KeyboardUIContent::KeyboardUIContent(content::BrowserContext* context) + : browser_context_(context), + default_url_(kKeyboardURL), + window_bounds_observer_(new WindowBoundsChangeObserver(this)) { +} + +KeyboardUIContent::~KeyboardUIContent() { + ResetInsets(); +} + +void KeyboardUIContent::LoadSystemKeyboard() { + DCHECK(keyboard_contents_); + if (keyboard_contents_->GetURL() != default_url_) { + // TODO(bshe): The height of system virtual keyboard and IME virtual + // keyboard may different. The height needs to be restored too. + LoadContents(default_url_); + } +} + +void KeyboardUIContent::UpdateInsetsForWindow(aura::Window* window) { + aura::Window* keyboard_window = GetKeyboardWindow(); + scoped_ptr<content::RenderWidgetHostIterator> widgets( + content::RenderWidgetHost::GetRenderWidgetHosts()); + while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { + content::RenderWidgetHostView* view = widget->GetView(); + if (view && window->Contains(view->GetNativeView())) { + gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); + gfx::Rect intersect = + gfx::IntersectRects(window_bounds, keyboard_window->bounds()); + int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; + if (overlap > 0 && overlap < window_bounds.height()) + view->SetInsets(gfx::Insets(0, 0, overlap, 0)); + else + view->SetInsets(gfx::Insets()); + return; + } + } +} + +aura::Window* KeyboardUIContent::GetKeyboardWindow() { + if (!keyboard_contents_) { + content::BrowserContext* context = browser_context(); + keyboard_contents_.reset(content::WebContents::Create( + content::WebContents::CreateParams(context, + content::SiteInstance::CreateForURL(context, + GetVirtualKeyboardUrl())))); + keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this)); + SetupWebContents(keyboard_contents_.get()); + LoadContents(GetVirtualKeyboardUrl()); + keyboard_contents_->GetNativeView()->AddObserver(this); + } + + return keyboard_contents_->GetNativeView(); +} + +bool KeyboardUIContent::HasKeyboardWindow() const { + return keyboard_contents_; +} + +void KeyboardUIContent::ReloadKeyboardIfNeeded() { + DCHECK(keyboard_contents_); + if (keyboard_contents_->GetURL() != GetVirtualKeyboardUrl()) { + if (keyboard_contents_->GetURL().GetOrigin() != + GetVirtualKeyboardUrl().GetOrigin()) { + // Sets keyboard window rectangle to 0 and close current page before + // navigate to a keyboard in a different extension. This keeps the UX the + // same as Android. Note we need to explicitly close current page as it + // might try to resize keyboard window in javascript on a resize event. + GetKeyboardWindow()->SetBounds(gfx::Rect()); + keyboard_contents_->ClosePage(); + keyboard_controller()->SetKeyboardMode(FULL_WIDTH); + } + LoadContents(GetVirtualKeyboardUrl()); + } +} + +void KeyboardUIContent::InitInsets(const gfx::Rect& new_bounds) { + // Adjust the height of the viewport for visible windows on the primary + // display. + // TODO(kevers): Add EnvObserver to properly initialize insets if a + // window is created while the keyboard is visible. + scoped_ptr<content::RenderWidgetHostIterator> widgets( + content::RenderWidgetHost::GetRenderWidgetHosts()); + aura::Window* keyboard_window = GetKeyboardWindow(); + aura::Window* root_window = keyboard_window->GetRootWindow(); + while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { + content::RenderWidgetHostView* view = widget->GetView(); + // Can be NULL, e.g. if the RenderWidget is being destroyed or + // the render process crashed. + if (view) { + aura::Window* window = view->GetNativeView(); + // If virtual keyboard failed to load, a widget that displays error + // message will be created and adds as a child of the virtual keyboard + // window. We want to avoid add BoundsChangedObserver to that window. + if (!keyboard_window->Contains(window) && + window->GetRootWindow() == root_window) { + gfx::Rect window_bounds = window->GetBoundsInScreen(); + gfx::Rect intersect = gfx::IntersectRects(window_bounds, + new_bounds); + int overlap = intersect.height(); + if (overlap > 0 && overlap < window_bounds.height()) + view->SetInsets(gfx::Insets(0, 0, overlap, 0)); + else + view->SetInsets(gfx::Insets()); + AddBoundsChangedObserver(window); + } + } + } +} + +void KeyboardUIContent::ResetInsets() { + const gfx::Insets insets; + scoped_ptr<content::RenderWidgetHostIterator> widgets( + content::RenderWidgetHost::GetRenderWidgetHosts()); + while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { + content::RenderWidgetHostView* view = widget->GetView(); + if (view) + view->SetInsets(insets); + } + window_bounds_observer_->RemoveAllObservedWindows(); +} + +void KeyboardUIContent::SetupWebContents(content::WebContents* contents) { +} + +void KeyboardUIContent::OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { + if (!shadow_) { + shadow_.reset(new wm::Shadow()); + shadow_->Init(wm::Shadow::STYLE_ACTIVE); + shadow_->layer()->SetVisible(true); + DCHECK(keyboard_contents_->GetNativeView()->parent()); + keyboard_contents_->GetNativeView()->parent()->layer()->Add( + shadow_->layer()); + } + + shadow_->SetContentBounds(new_bounds); +} + +void KeyboardUIContent::OnWindowDestroyed(aura::Window* window) { + window->RemoveObserver(this); +} + +void KeyboardUIContent::LoadContents(const GURL& url) { + if (keyboard_contents_) { + content::OpenURLParams params( + url, + content::Referrer(), + SINGLETON_TAB, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, + false); + keyboard_contents_->OpenURL(params); + } +} + +const GURL& KeyboardUIContent::GetVirtualKeyboardUrl() { + if (keyboard::IsInputViewEnabled()) { + const GURL& override_url = GetOverrideContentUrl(); + return override_url.is_valid() ? override_url : default_url_; + } else { + return default_url_; + } +} + +bool KeyboardUIContent::ShouldEnableInsets(aura::Window* window) { + aura::Window* keyboard_window = GetKeyboardWindow(); + return (keyboard_window->GetRootWindow() == window->GetRootWindow() && + keyboard::IsKeyboardOverscrollEnabled() && + keyboard_window->IsVisible() && + keyboard_controller()->keyboard_visible()); +} + +void KeyboardUIContent::AddBoundsChangedObserver(aura::Window* window) { + aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; + if (target_window) + window_bounds_observer_->AddObservedWindow(target_window); +} + +} // namespace keyboard diff --git a/ui/keyboard/content/keyboard_ui_content.h b/ui/keyboard/content/keyboard_ui_content.h new file mode 100644 index 0000000..1c6fc25 --- /dev/null +++ b/ui/keyboard/content/keyboard_ui_content.h @@ -0,0 +1,127 @@ +// Copyright 2015 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 UI_KEYBOARD_CONTENT_KEYBOARD_UI_CONTENT_H_ +#define UI_KEYBOARD_CONTENT_KEYBOARD_UI_CONTENT_H_ + +#include "base/memory/scoped_ptr.h" +#include "content/public/common/media_stream_request.h" +#include "ui/aura/window_observer.h" +#include "ui/base/ime/text_input_type.h" +#include "ui/keyboard/keyboard_export.h" +#include "ui/keyboard/keyboard_ui.h" + +namespace aura { +class Window; +} +namespace content { +class BrowserContext; +class SiteInstance; +class WebContents; +} +namespace gfx { +class Rect; +} +namespace ui { +class InputMethod; +} +namespace wm { +class Shadow; +} + +namespace keyboard { + +class KeyboardController; +class WindowBoundsChangeObserver; + +// An implementation of KeyboardUI that uses a content::WebContents to implement +//the keyboard. +class KEYBOARD_EXPORT KeyboardUIContent : public KeyboardUI, + public aura::WindowObserver { + public: + class TestApi { + public: + explicit TestApi(KeyboardUIContent* ui) : ui_(ui) {} + + const content::WebContents* keyboard_contents() { + return ui_->keyboard_contents_.get(); + } + + private: + KeyboardUIContent* ui_; + + DISALLOW_COPY_AND_ASSIGN(TestApi); + }; + + explicit KeyboardUIContent(content::BrowserContext* context); + ~KeyboardUIContent() override; + + // Requests the audio input from microphone for speech input. + virtual void RequestAudioInput(content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) = 0; + + // Loads system virtual keyboard. Noop if the current virtual keyboard is + // system virtual keyboard. + virtual void LoadSystemKeyboard(); + + // Called when a window being observed changes bounds, to update its insets. + void UpdateInsetsForWindow(aura::Window* window); + + // Overridden from KeyboardUI: + aura::Window* GetKeyboardWindow() override; + bool HasKeyboardWindow() const override; + void ReloadKeyboardIfNeeded() override; + void InitInsets(const gfx::Rect& new_bounds) override; + void ResetInsets() override; + + protected: + // The implementation can choose to setup the WebContents before the virtual + // keyboard page is loaded (e.g. install a WebContentsObserver). + // SetupWebContents() is called right after creating the WebContents, before + // loading the keyboard page. + virtual void SetupWebContents(content::WebContents* contents); + + // aura::WindowObserver overrides: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) override; + void OnWindowDestroyed(aura::Window* window) override; + + content::BrowserContext* browser_context() { return browser_context_; } + + private: + friend class TestApi; + + // Loads the web contents for the given |url|. + void LoadContents(const GURL& url); + + // Gets the virtual keyboard URL (either the default URL or IME override URL). + const GURL& GetVirtualKeyboardUrl(); + + // Determines whether a particular window should have insets for overscroll. + bool ShouldEnableInsets(aura::Window* window); + + // Adds an observer for tracking changes to a window size or + // position while the keyboard is displayed. Any window repositioning + // invalidates insets for overscrolling. + void AddBoundsChangedObserver(aura::Window* window); + + // The BrowserContext to use for creating the WebContents hosting the + // keyboard. + content::BrowserContext* browser_context_; + + const GURL default_url_; + + scoped_ptr<content::WebContents> keyboard_contents_; + scoped_ptr<wm::Shadow> shadow_; + + scoped_ptr<WindowBoundsChangeObserver> window_bounds_observer_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardUIContent); +}; + +} // namespace keyboard + +#endif // UI_KEYBOARD_CONTENT_KEYBOARD_UI_CONTENT_H_
\ No newline at end of file diff --git a/ui/keyboard/keyboard.gyp b/ui/keyboard/keyboard.gyp index 2f4fcdd..96fc1fd 100644 --- a/ui/keyboard/keyboard.gyp +++ b/ui/keyboard/keyboard.gyp @@ -49,11 +49,8 @@ 'dependencies': [ '../../base/base.gyp:base', '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '../../content/content.gyp:content_browser', - '../../ipc/ipc.gyp:ipc', '../../media/media.gyp:media', '../../skia/skia.gyp:skia', - '../../url/url.gyp:url_lib', '../aura/aura.gyp:aura', '../base/ime/ui_base_ime.gyp:ui_base_ime', '../base/ui_base.gyp:ui_base', @@ -63,27 +60,22 @@ '../events/events.gyp:events_base', '../gfx/gfx.gyp:gfx', '../gfx/gfx.gyp:gfx_geometry', - '../wm/wm.gyp:wm', 'keyboard_resources', ], 'defines': [ 'KEYBOARD_IMPLEMENTATION', ], 'sources': [ - 'keyboard.cc', - 'keyboard.h', - 'keyboard_constants.cc', - 'keyboard_constants.h', 'keyboard_controller.cc', 'keyboard_controller.h', 'keyboard_controller_observer.h', - 'keyboard_controller_proxy.cc', - 'keyboard_controller_proxy.h', 'keyboard_export.h', 'keyboard_layout_manager.cc', 'keyboard_layout_manager.h', 'keyboard_switches.cc', 'keyboard_switches.h', + 'keyboard_ui.cc', + 'keyboard_ui.h', 'keyboard_util.cc', 'keyboard_util.h', ], @@ -96,15 +88,51 @@ ], }, { + # GN version: //ui/keyboard:keyboard_with_content + 'target_name': 'keyboard_with_content', + 'type': '<(component)', + 'dependencies': [ + 'keyboard', + '../../base/base.gyp:base', + '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../../content/content.gyp:content_browser', + '../../ipc/ipc.gyp:ipc', + '../../skia/skia.gyp:skia', + '../../url/url.gyp:url_lib', + '../aura/aura.gyp:aura', + '../base/ime/ui_base_ime.gyp:ui_base_ime', + '../base/ui_base.gyp:ui_base', + '../compositor/compositor.gyp:compositor', + '../events/events.gyp:dom_keycode_converter', + '../events/events.gyp:events', + '../events/events.gyp:events_base', + '../gfx/gfx.gyp:gfx', + '../gfx/gfx.gyp:gfx_geometry', + '../wm/wm.gyp:wm', + 'keyboard_resources', + ], + 'defines': [ + 'KEYBOARD_IMPLEMENTATION', + ], + 'sources': [ + 'content/keyboard.cc', + 'content/keyboard.h', + 'content/keyboard_constants.cc', + 'content/keyboard_constants.h', + 'content/keyboard_content_util.cc', + 'content/keyboard_content_util.h', + 'content/keyboard_ui_content.cc', + 'content/keyboard_ui_content.h', + ], + }, + { 'target_name': 'keyboard_unittests', 'type': '<(gtest_target_type)', 'dependencies': [ '../../base/base.gyp:base', '../../base/base.gyp:test_support_base', - '../../content/content.gyp:content', '../../skia/skia.gyp:skia', '../../testing/gtest.gyp:gtest', - '../../url/url.gyp:url_lib', '../aura/aura.gyp:aura', '../aura/aura.gyp:aura_test_support', '../base/ime/ui_base_ime.gyp:ui_base_ime', @@ -113,7 +141,6 @@ '../compositor/compositor.gyp:compositor_test_support', '../gfx/gfx.gyp:gfx', '../gfx/gfx.gyp:gfx_geometry', - '../resources/ui_resources.gyp:ui_test_pak', '../wm/wm.gyp:wm', 'keyboard', ], diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index 1be0200..a50f7c7 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc @@ -8,9 +8,6 @@ #include "base/bind.h" #include "base/command_line.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_iterator.h" -#include "content/public/browser/render_widget_host_view.h" #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_observer.h" @@ -24,10 +21,9 @@ #include "ui/gfx/path.h" #include "ui/gfx/skia_util.h" #include "ui/keyboard/keyboard_controller_observer.h" -#include "ui/keyboard/keyboard_controller_proxy.h" #include "ui/keyboard/keyboard_layout_manager.h" +#include "ui/keyboard/keyboard_ui.h" #include "ui/keyboard/keyboard_util.h" -#include "ui/wm/core/masked_window_targeter.h" #if defined(OS_CHROMEOS) #include "base/process/launch.h" @@ -161,52 +157,11 @@ void CallbackAnimationObserver::OnLayerAnimationAborted( animator_->RemoveObserver(this); } -class WindowBoundsChangeObserver : public aura::WindowObserver { - public: - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override; - void OnWindowDestroyed(aura::Window* window) override; - - void AddObservedWindow(aura::Window* window); - void RemoveAllObservedWindows(); - - private: - std::set<aura::Window*> observed_windows_; -}; - -void WindowBoundsChangeObserver::OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) { - KeyboardController* controller = KeyboardController::GetInstance(); - if (controller) - controller->UpdateWindowInsets(window); -} - -void WindowBoundsChangeObserver::OnWindowDestroyed(aura::Window* window) { - if (window->HasObserver(this)) - window->RemoveObserver(this); - observed_windows_.erase(window); -} - -void WindowBoundsChangeObserver::AddObservedWindow(aura::Window* window) { - if (!window->HasObserver(this)) { - window->AddObserver(this); - observed_windows_.insert(window); - } -} - -void WindowBoundsChangeObserver::RemoveAllObservedWindows() { - for (std::set<aura::Window*>::iterator it = observed_windows_.begin(); - it != observed_windows_.end(); ++it) - (*it)->RemoveObserver(this); - observed_windows_.clear(); -} - // static KeyboardController* KeyboardController::instance_ = NULL; -KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) - : proxy_(proxy), +KeyboardController::KeyboardController(KeyboardUI* ui) + : ui_(ui), input_method_(NULL), keyboard_visible_(false), show_on_resize_(false), @@ -214,11 +169,10 @@ KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) keyboard_mode_(FULL_WIDTH), type_(ui::TEXT_INPUT_TYPE_NONE), weak_factory_(this) { - CHECK(proxy); - input_method_ = proxy_->GetInputMethod(); + CHECK(ui); + input_method_ = ui_->GetInputMethod(); input_method_->AddObserver(this); - window_bounds_observer_.reset(new WindowBoundsChangeObserver()); - proxy_->SetController(this); + ui_->SetController(this); } KeyboardController::~KeyboardController() { @@ -229,8 +183,7 @@ KeyboardController::~KeyboardController() { } if (input_method_) input_method_->RemoveObserver(this); - ResetWindowInsets(); - proxy_->SetController(nullptr); + ui_->SetController(nullptr); } // static @@ -260,45 +213,14 @@ aura::Window* KeyboardController::GetContainerWindow() { void KeyboardController::NotifyKeyboardBoundsChanging( const gfx::Rect& new_bounds) { current_keyboard_bounds_ = new_bounds; - if (proxy_->HasKeyboardWindow() && proxy_->GetKeyboardWindow()->IsVisible()) { + if (ui_->HasKeyboardWindow() && ui_->GetKeyboardWindow()->IsVisible()) { FOR_EACH_OBSERVER(KeyboardControllerObserver, observer_list_, OnKeyboardBoundsChanging(new_bounds)); - if (keyboard::IsKeyboardOverscrollEnabled()) { - // Adjust the height of the viewport for visible windows on the primary - // display. - // TODO(kevers): Add EnvObserver to properly initialize insets if a - // window is created while the keyboard is visible. - scoped_ptr<content::RenderWidgetHostIterator> widgets( - content::RenderWidgetHost::GetRenderWidgetHosts()); - aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); - aura::Window* root_window = keyboard_window->GetRootWindow(); - while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { - content::RenderWidgetHostView* view = widget->GetView(); - // Can be NULL, e.g. if the RenderWidget is being destroyed or - // the render process crashed. - if (view) { - aura::Window* window = view->GetNativeView(); - // If virtual keyboard failed to load, a widget that displays error - // message will be created and adds as a child of the virtual keyboard - // window. We want to avoid add BoundsChangedObserver to that window. - if (!keyboard_window->Contains(window) && - window->GetRootWindow() == root_window) { - gfx::Rect window_bounds = window->GetBoundsInScreen(); - gfx::Rect intersect = gfx::IntersectRects(window_bounds, - new_bounds); - int overlap = intersect.height(); - if (overlap > 0 && overlap < window_bounds.height()) - view->SetInsets(gfx::Insets(0, 0, overlap, 0)); - else - view->SetInsets(gfx::Insets()); - AddBoundsChangedObserver(window); - } - } - } - } else { - ResetWindowInsets(); - } + if (keyboard::IsKeyboardOverscrollEnabled()) + ui_->InitInsets(new_bounds); + else + ui_->ResetInsets(); } else { current_keyboard_bounds_ = gfx::Rect(); } @@ -373,7 +295,7 @@ void KeyboardController::ShowKeyboard(bool lock) { void KeyboardController::OnWindowHierarchyChanged( const HierarchyChangeParams& params) { if (params.new_parent && params.target == container_.get()) - OnTextInputStateChanged(proxy_->GetInputMethod()->GetTextInputClient()); + OnTextInputStateChanged(ui_->GetInputMethod()->GetTextInputClient()); } void KeyboardController::OnWindowAddedToRootWindow(aura::Window* window) { @@ -394,7 +316,7 @@ void KeyboardController::OnWindowBoundsChanged(aura::Window* window, return; // Keep the same height when window resize. It gets called when screen // rotate. - if (!keyboard_container_initialized() || !proxy_->HasKeyboardWindow()) + if (!keyboard_container_initialized() || !ui_->HasKeyboardWindow()) return; int container_height = container_->bounds().height(); @@ -416,11 +338,11 @@ void KeyboardController::OnWindowBoundsChanged(aura::Window* window, } void KeyboardController::Reload() { - if (proxy_->HasKeyboardWindow()) { + if (ui_->HasKeyboardWindow()) { // A reload should never try to show virtual keyboard. If keyboard is not // visible before reload, it should keep invisible after reload. show_on_resize_ = false; - proxy_->ReloadKeyboardIfNeeded(); + ui_->ReloadKeyboardIfNeeded(); } } @@ -448,7 +370,7 @@ void KeyboardController::OnTextInputStateChanged( weak_factory_.InvalidateWeakPtrs(); keyboard_visible_ = true; } - proxy_->SetUpdateInputType(type_); + ui_->SetUpdateInputType(type_); // Do not explicitly show the Virtual keyboard unless it is in the process // of hiding. Instead, the virtual keyboard is shown in response to a user // gesture (mouse or touch) that is received while an element has input @@ -467,53 +389,23 @@ void KeyboardController::OnShowImeIfNeeded() { ShowKeyboardInternal(); } -bool KeyboardController::ShouldEnableInsets(aura::Window* window) { - aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); - return (keyboard_window->GetRootWindow() == window->GetRootWindow() && - keyboard::IsKeyboardOverscrollEnabled() && - keyboard_window->IsVisible() && keyboard_visible_); -} - -void KeyboardController::UpdateWindowInsets(aura::Window* window) { - aura::Window* keyboard_window = proxy_->GetKeyboardWindow(); - if (window == keyboard_window) - return; - - scoped_ptr<content::RenderWidgetHostIterator> widgets( - content::RenderWidgetHost::GetRenderWidgetHosts()); - while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { - content::RenderWidgetHostView* view = widget->GetView(); - if (view && window->Contains(view->GetNativeView())) { - gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); - gfx::Rect intersect = - gfx::IntersectRects(window_bounds, keyboard_window->bounds()); - int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; - if (overlap > 0 && overlap < window_bounds.height()) - view->SetInsets(gfx::Insets(0, 0, overlap, 0)); - else - view->SetInsets(gfx::Insets()); - return; - } - } -} - void KeyboardController::ShowKeyboardInternal() { if (!container_.get()) return; if (container_->children().empty()) { keyboard::MarkKeyboardLoadStarted(); - aura::Window* keyboard = proxy_->GetKeyboardWindow(); + aura::Window* keyboard = ui_->GetKeyboardWindow(); keyboard->Show(); container_->AddChild(keyboard); keyboard->set_owned_by_parent(false); } - proxy_->ReloadKeyboardIfNeeded(); + ui_->ReloadKeyboardIfNeeded(); if (keyboard_visible_) { return; - } else if (proxy_->GetKeyboardWindow()->bounds().height() == 0) { + } else if (ui_->GetKeyboardWindow()->bounds().height() == 0) { show_on_resize_ = true; return; } @@ -559,7 +451,7 @@ void KeyboardController::ShowKeyboardInternal() { container_animator->AddObserver(animation_observer_.get()); } - proxy_->ShowKeyboardContainer(container_.get()); + ui_->ShowKeyboardContainer(container_.get()); { // Scope the following animation settings as we don't want to animate @@ -575,18 +467,6 @@ void KeyboardController::ShowKeyboardInternal() { } } -void KeyboardController::ResetWindowInsets() { - const gfx::Insets insets; - scoped_ptr<content::RenderWidgetHostIterator> widgets( - content::RenderWidgetHost::GetRenderWidgetHosts()); - while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { - content::RenderWidgetHostView* view = widget->GetView(); - if (view) - view->SetInsets(insets); - } - window_bounds_observer_->RemoveAllObservedWindows(); -} - bool KeyboardController::WillHideKeyboard() const { return weak_factory_.HasWeakPtrs(); } @@ -595,17 +475,11 @@ void KeyboardController::ShowAnimationFinished() { // Notify observers after animation finished to prevent reveal desktop // background during animation. NotifyKeyboardBoundsChanging(container_->bounds()); - proxy_->EnsureCaretInWorkArea(); + ui_->EnsureCaretInWorkArea(); } void KeyboardController::HideAnimationFinished() { - proxy_->HideKeyboardContainer(container_.get()); -} - -void KeyboardController::AddBoundsChangedObserver(aura::Window* window) { - aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr; - if (target_window) - window_bounds_observer_->AddObservedWindow(target_window); + ui_->HideKeyboardContainer(container_.get()); } } // namespace keyboard diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h index a5156bb..5211d0d 100644 --- a/ui/keyboard/keyboard_controller.h +++ b/ui/keyboard/keyboard_controller.h @@ -14,7 +14,6 @@ #include "ui/base/ime/text_input_type.h" #include "ui/gfx/geometry/rect.h" #include "ui/keyboard/keyboard_export.h" -#include "url/gurl.h" namespace aura { class Window; @@ -27,9 +26,8 @@ class TextInputClient; namespace keyboard { class CallbackAnimationObserver; -class WindowBoundsChangeObserver; class KeyboardControllerObserver; -class KeyboardControllerProxy; +class KeyboardUI; // Animation distance. const int kAnimationDistance = 30; @@ -58,8 +56,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, HIDE_REASON_MANUAL, }; - // Takes ownership of |proxy|. - explicit KeyboardController(KeyboardControllerProxy* proxy); + // Takes ownership of |ui|. + explicit KeyboardController(KeyboardUI* ui); ~KeyboardController() override; // Returns the container for the keyboard, which is owned by @@ -88,7 +86,7 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, virtual void AddObserver(KeyboardControllerObserver* observer); virtual void RemoveObserver(KeyboardControllerObserver* observer); - KeyboardControllerProxy* proxy() { return proxy_.get(); } + KeyboardUI* ui() { return ui_.get(); } void set_lock_keyboard(bool lock) { lock_keyboard_ = lock; } @@ -119,12 +117,6 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, return current_keyboard_bounds_; } - // Determines whether a particular window should have insets for overscroll. - bool ShouldEnableInsets(aura::Window* window); - - // Updates insets on web content window - void UpdateWindowInsets(aura::Window* window); - private: // For access to Observer methods for simulation. friend class KeyboardControllerTest; @@ -150,9 +142,6 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, // Show virtual keyboard immediately with animation. void ShowKeyboardInternal(); - // Clears any insets on web content windows. - void ResetWindowInsets(); - // Returns true if keyboard is scheduled to hide. bool WillHideKeyboard() const; @@ -161,19 +150,12 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, void ShowAnimationFinished(); void HideAnimationFinished(); - // Adds an observer for tracking changes to a window size or - // position while the keyboard is displayed. Any window repositioning - // invalidates insets for overscrolling. - void AddBoundsChangedObserver(aura::Window* window); - - scoped_ptr<KeyboardControllerProxy> proxy_; + scoped_ptr<KeyboardUI> ui_; scoped_ptr<aura::Window> container_; // CallbackAnimationObserver should destructed before container_ because it // uses container_'s animator. scoped_ptr<CallbackAnimationObserver> animation_observer_; - scoped_ptr<WindowBoundsChangeObserver> window_bounds_observer_; - ui::InputMethod* input_method_; bool keyboard_visible_; bool show_on_resize_; diff --git a/ui/keyboard/keyboard_controller_proxy.cc b/ui/keyboard/keyboard_controller_proxy.cc deleted file mode 100644 index 3671b02..0000000 --- a/ui/keyboard/keyboard_controller_proxy.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2013 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 "ui/keyboard/keyboard_controller_proxy.h" - -#include "base/command_line.h" -#include "base/values.h" -#include "content/public/browser/site_instance.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_ui.h" -#include "content/public/common/bindings_policy.h" -#include "ui/aura/layout_manager.h" -#include "ui/aura/window.h" -#include "ui/base/ime/input_method.h" -#include "ui/base/ime/text_input_client.h" -#include "ui/keyboard/keyboard_constants.h" -#include "ui/keyboard/keyboard_controller.h" -#include "ui/keyboard/keyboard_switches.h" -#include "ui/keyboard/keyboard_util.h" -#include "ui/wm/core/shadow.h" - -namespace { - -// The WebContentsDelegate for the keyboard. -// The delegate deletes itself when the keyboard is destroyed. -class KeyboardContentsDelegate : public content::WebContentsDelegate, - public content::WebContentsObserver { - public: - KeyboardContentsDelegate(keyboard::KeyboardControllerProxy* proxy) - : proxy_(proxy) {} - ~KeyboardContentsDelegate() override {} - - private: - // Overridden from content::WebContentsDelegate: - content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) override { - source->GetController().LoadURL( - params.url, params.referrer, params.transition, params.extra_headers); - Observe(source); - return source; - } - - bool CanDragEnter(content::WebContents* source, - const content::DropData& data, - blink::WebDragOperationsMask operations_allowed) override { - return false; - } - - bool ShouldCreateWebContents( - content::WebContents* web_contents, - int route_id, - int main_frame_route_id, - WindowContainerType window_container_type, - const std::string& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) override { - return false; - } - - bool IsPopupOrPanel(const content::WebContents* source) const override { - return true; - } - - void MoveContents(content::WebContents* source, - const gfx::Rect& pos) override { - aura::Window* keyboard = proxy_->GetKeyboardWindow(); - // keyboard window must have been added to keyboard container window at this - // point. Otherwise, wrong keyboard bounds is used and may cause problem as - // described in crbug.com/367788. - DCHECK(keyboard->parent()); - // keyboard window bounds may not set to |pos| after this call. If keyboard - // is in FULL_WIDTH mode, only the height of keyboard window will be - // changed. - keyboard->SetBounds(pos); - } - - // Overridden from content::WebContentsDelegate: - void RequestMediaAccessPermission( - content::WebContents* web_contents, - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) override { - proxy_->RequestAudioInput(web_contents, request, callback); - } - - // Overridden from content::WebContentsObserver: - void WebContentsDestroyed() override { delete this; } - - keyboard::KeyboardControllerProxy* proxy_; - - DISALLOW_COPY_AND_ASSIGN(KeyboardContentsDelegate); -}; - -} // namespace - -namespace keyboard { - -KeyboardControllerProxy::KeyboardControllerProxy( - content::BrowserContext* context) - : browser_context_(context), - default_url_(kKeyboardURL), - keyboard_controller_(nullptr) { -} - -KeyboardControllerProxy::~KeyboardControllerProxy() { -} - -const GURL& KeyboardControllerProxy::GetVirtualKeyboardUrl() { - if (keyboard::IsInputViewEnabled()) { - const GURL& override_url = GetOverrideContentUrl(); - return override_url.is_valid() ? override_url : default_url_; - } else { - return default_url_; - } -} - -void KeyboardControllerProxy::LoadContents(const GURL& url) { - if (keyboard_contents_) { - content::OpenURLParams params( - url, - content::Referrer(), - SINGLETON_TAB, - ui::PAGE_TRANSITION_AUTO_TOPLEVEL, - false); - keyboard_contents_->OpenURL(params); - } -} - -aura::Window* KeyboardControllerProxy::GetKeyboardWindow() { - if (!keyboard_contents_) { - content::BrowserContext* context = browser_context(); - keyboard_contents_.reset(content::WebContents::Create( - content::WebContents::CreateParams(context, - content::SiteInstance::CreateForURL(context, - GetVirtualKeyboardUrl())))); - keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this)); - SetupWebContents(keyboard_contents_.get()); - LoadContents(GetVirtualKeyboardUrl()); - keyboard_contents_->GetNativeView()->AddObserver(this); - } - - return keyboard_contents_->GetNativeView(); -} - -bool KeyboardControllerProxy::HasKeyboardWindow() const { - return keyboard_contents_; -} - -void KeyboardControllerProxy::ShowKeyboardContainer(aura::Window* container) { - GetKeyboardWindow()->Show(); - container->Show(); -} - -void KeyboardControllerProxy::HideKeyboardContainer(aura::Window* container) { - container->Hide(); - GetKeyboardWindow()->Hide(); -} - -void KeyboardControllerProxy::SetUpdateInputType(ui::TextInputType type) { -} - -void KeyboardControllerProxy::EnsureCaretInWorkArea() { - if (GetInputMethod()->GetTextInputClient()) { - aura::Window* keyboard_window = GetKeyboardWindow(); - aura::Window* root_window = keyboard_window->GetRootWindow(); - gfx::Rect available_bounds = root_window->bounds(); - gfx::Rect keyboard_bounds = keyboard_window->bounds(); - available_bounds.set_height(available_bounds.height() - - keyboard_bounds.height()); - GetInputMethod()->GetTextInputClient()->EnsureCaretInRect(available_bounds); - } -} - -void KeyboardControllerProxy::LoadSystemKeyboard() { - DCHECK(keyboard_contents_); - if (keyboard_contents_->GetURL() != default_url_) { - // TODO(bshe): The height of system virtual keyboard and IME virtual - // keyboard may different. The height needs to be restored too. - LoadContents(default_url_); - } -} - -void KeyboardControllerProxy::ReloadKeyboardIfNeeded() { - DCHECK(keyboard_contents_); - if (keyboard_contents_->GetURL() != GetVirtualKeyboardUrl()) { - if (keyboard_contents_->GetURL().GetOrigin() != - GetVirtualKeyboardUrl().GetOrigin()) { - // Sets keyboard window rectangle to 0 and close current page before - // navigate to a keyboard in a different extension. This keeps the UX the - // same as Android. Note we need to explicitly close current page as it - // might try to resize keyboard window in javascript on a resize event. - GetKeyboardWindow()->SetBounds(gfx::Rect()); - keyboard_contents_->ClosePage(); - keyboard_controller()->SetKeyboardMode(FULL_WIDTH); - } - LoadContents(GetVirtualKeyboardUrl()); - } -} - -void KeyboardControllerProxy::SetController(KeyboardController* controller) { - keyboard_controller_ = controller; -} - -void KeyboardControllerProxy::SetupWebContents(content::WebContents* contents) { -} - -void KeyboardControllerProxy::OnWindowBoundsChanged( - aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) { - if (!shadow_) { - shadow_.reset(new wm::Shadow()); - shadow_->Init(wm::Shadow::STYLE_ACTIVE); - shadow_->layer()->SetVisible(true); - DCHECK(keyboard_contents_->GetNativeView()->parent()); - keyboard_contents_->GetNativeView()->parent()->layer()->Add( - shadow_->layer()); - } - - shadow_->SetContentBounds(new_bounds); -} - -void KeyboardControllerProxy::OnWindowDestroyed(aura::Window* window) { - window->RemoveObserver(this); -} - -} // namespace keyboard diff --git a/ui/keyboard/keyboard_controller_proxy.h b/ui/keyboard/keyboard_controller_proxy.h deleted file mode 100644 index 98051fa..0000000 --- a/ui/keyboard/keyboard_controller_proxy.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2013 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 UI_KEYBOARD_KEYBOARD_CONTROLLER_PROXY_H_ -#define UI_KEYBOARD_KEYBOARD_CONTROLLER_PROXY_H_ - -#include "base/memory/scoped_ptr.h" -#include "content/public/common/media_stream_request.h" -#include "ui/aura/window_observer.h" -#include "ui/base/ime/text_input_type.h" -#include "ui/keyboard/keyboard_export.h" - -namespace aura { -class Window; -} -namespace content { -class BrowserContext; -class SiteInstance; -class WebContents; -} -namespace gfx { -class Rect; -} -namespace ui { -class InputMethod; -} -namespace wm { -class Shadow; -} - -namespace keyboard { - -class KeyboardController; - -// A proxy used by the KeyboardController to get access to the virtual -// keyboard window. -class KEYBOARD_EXPORT KeyboardControllerProxy : public aura::WindowObserver { - public: - class TestApi { - public: - explicit TestApi(KeyboardControllerProxy* proxy) : proxy_(proxy) {} - - const content::WebContents* keyboard_contents() { - return proxy_->keyboard_contents_.get(); - } - - private: - KeyboardControllerProxy* proxy_; - - DISALLOW_COPY_AND_ASSIGN(TestApi); - }; - - explicit KeyboardControllerProxy(content::BrowserContext* context); - ~KeyboardControllerProxy() override; - - // Gets the virtual keyboard window. Ownership of the returned Window remains - // with the proxy. - virtual aura::Window* GetKeyboardWindow(); - - // Whether the keyboard window is created. The keyboard window is tied to a - // WebContent so we can just check if the WebContent is created or not. - virtual bool HasKeyboardWindow() const; - - // Gets the InputMethod that will provide notifications about changes in the - // text input context. - virtual ui::InputMethod* GetInputMethod() = 0; - - // Requests the audio input from microphone for speech input. - virtual void RequestAudioInput(content::WebContents* web_contents, - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) = 0; - - // Shows the container window of the keyboard. The default implementation - // simply shows the container. An overridden implementation can set up - // necessary animation, or delay the visibility change as it desires. - virtual void ShowKeyboardContainer(aura::Window* container); - - // Hides the container window of the keyboard. The default implementation - // simply hides the container. An overridden implementation can set up - // necesasry animation, or delay the visibility change as it desires. - virtual void HideKeyboardContainer(aura::Window* container); - - // Updates the type of the focused text input box. - virtual void SetUpdateInputType(ui::TextInputType type); - - // Ensures caret in current work area (not occluded by virtual keyboard - // window). - virtual void EnsureCaretInWorkArea(); - - // Loads system virtual keyboard. Noop if the current virtual keyboard is - // system virtual keyboard. - virtual void LoadSystemKeyboard(); - - // Reloads virtual keyboard URL if the current keyboard's web content URL is - // different. The URL can be different if user switch from password field to - // any other type input field. - // At password field, the system virtual keyboard is forced to load even if - // the current IME provides a customized virtual keyboard. This is needed to - // prevent IME virtual keyboard logging user's password. Once user switch to - // other input fields, the virtual keyboard should switch back to the IME - // provided keyboard, or keep using the system virtual keyboard if IME doesn't - // provide one. - virtual void ReloadKeyboardIfNeeded(); - - // KeyboardController owns KeyboardControllerProxy so KeyboardControllerProxy - // or its subclasses should not take ownership of the |controller|. - // |controller| can be null when KeyboardController is destroying. - virtual void SetController(KeyboardController* controller); - - protected: - // The implementation can choose to setup the WebContents before the virtual - // keyboard page is loaded (e.g. install a WebContentsObserver). - // SetupWebContents() is called right after creating the WebContents, before - // loading the keyboard page. - virtual void SetupWebContents(content::WebContents* contents); - - // aura::WindowObserver overrides: - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override; - void OnWindowDestroyed(aura::Window* window) override; - - content::BrowserContext* browser_context() { return browser_context_; } - KeyboardController* keyboard_controller() { return keyboard_controller_; } - - private: - friend class TestApi; - - // Loads the web contents for the given |url|. - void LoadContents(const GURL& url); - - // Gets the virtual keyboard URL (either the default URL or IME override URL). - const GURL& GetVirtualKeyboardUrl(); - - // The BrowserContext to use for creating the WebContents hosting the - // keyboard. - content::BrowserContext* browser_context_; - - const GURL default_url_; - keyboard::KeyboardController* keyboard_controller_; - - scoped_ptr<content::WebContents> keyboard_contents_; - scoped_ptr<wm::Shadow> shadow_; - - DISALLOW_COPY_AND_ASSIGN(KeyboardControllerProxy); -}; - -} // namespace keyboard - -#endif // UI_KEYBOARD_KEYBOARD_CONTROLLER_PROXY_H_ diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc index b30f7a5..5c5cf1c 100644 --- a/ui/keyboard/keyboard_controller_unittest.cc +++ b/ui/keyboard/keyboard_controller_unittest.cc @@ -28,7 +28,7 @@ #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/rect.h" #include "ui/keyboard/keyboard_controller_observer.h" -#include "ui/keyboard/keyboard_controller_proxy.h" +#include "ui/keyboard/keyboard_ui.h" #include "ui/keyboard/keyboard_util.h" #include "ui/wm/core/default_activation_client.h" @@ -86,18 +86,15 @@ class TestFocusController : public ui::EventHandler { DISALLOW_COPY_AND_ASSIGN(TestFocusController); }; -class TestKeyboardControllerProxy : public KeyboardControllerProxy { +class TestKeyboardUI : public KeyboardUI { public: - TestKeyboardControllerProxy(ui::InputMethod* input_method) - : KeyboardControllerProxy(nullptr), - input_method_(input_method) {} - - ~TestKeyboardControllerProxy() override { + TestKeyboardUI(ui::InputMethod* input_method) : input_method_(input_method) {} + ~TestKeyboardUI() override { // Destroy the window before the delegate. window_.reset(); } - // Overridden from KeyboardControllerProxy: + // Overridden from KeyboardUI: bool HasKeyboardWindow() const override { return window_; } aura::Window* GetKeyboardWindow() override { if (!window_) { @@ -108,21 +105,17 @@ class TestKeyboardControllerProxy : public KeyboardControllerProxy { return window_.get(); } ui::InputMethod* GetInputMethod() override { return input_method_; } - void RequestAudioInput( - content::WebContents* web_contents, - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) override { - return; - } - void LoadSystemKeyboard() override{}; - void ReloadKeyboardIfNeeded() override{}; + void SetUpdateInputType(ui::TextInputType type) override {} + void ReloadKeyboardIfNeeded() override {}; + void InitInsets(const gfx::Rect& keyboard_bounds) override {} + void ResetInsets() override {} private: scoped_ptr<aura::Window> window_; aura::test::TestWindowDelegate delegate_; ui::InputMethod* input_method_; - DISALLOW_COPY_AND_ASSIGN(TestKeyboardControllerProxy); + DISALLOW_COPY_AND_ASSIGN(TestKeyboardUI); }; // Keeps a count of all the events a window receives. @@ -169,7 +162,7 @@ class KeyboardContainerObserver : public aura::WindowObserver { class KeyboardControllerTest : public testing::Test, public KeyboardControllerObserver { public: - KeyboardControllerTest() : number_of_calls_(0), proxy_(nullptr) {} + KeyboardControllerTest() : number_of_calls_(0), ui_(nullptr) {} ~KeyboardControllerTest() override {} void SetUp() override { @@ -183,9 +176,8 @@ class KeyboardControllerTest : public testing::Test, aura_test_helper_->SetUp(context_factory); new wm::DefaultActivationClient(aura_test_helper_->root_window()); focus_controller_.reset(new TestFocusController(root_window())); - proxy_ = new TestKeyboardControllerProxy( - aura_test_helper_->host()->GetInputMethod()); - controller_.reset(new KeyboardController(proxy_)); + ui_ = new TestKeyboardUI(aura_test_helper_->host()->GetInputMethod()); + controller_.reset(new KeyboardController(ui_)); controller()->AddObserver(this); } @@ -198,7 +190,7 @@ class KeyboardControllerTest : public testing::Test, } aura::Window* root_window() { return aura_test_helper_->root_window(); } - KeyboardControllerProxy* proxy() { return proxy_; } + KeyboardUI* ui() { return ui_; } KeyboardController* controller() { return controller_.get(); } void ShowKeyboard() { @@ -228,13 +220,13 @@ class KeyboardControllerTest : public testing::Test, const gfx::Rect& notified_bounds() { return notified_bounds_; } void SetFocus(ui::TextInputClient* client) { - ui::InputMethod* input_method = proxy()->GetInputMethod(); + ui::InputMethod* input_method = ui()->GetInputMethod(); input_method->SetFocusedTextInputClient(client); if (client && client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) { input_method->ShowImeIfNeeded(); - if (proxy_->GetKeyboardWindow()->bounds().height() == 0) { + if (ui_->GetKeyboardWindow()->bounds().height() == 0) { // Set initial bounds for test keyboard window. - proxy_->GetKeyboardWindow()->SetBounds( + ui_->GetKeyboardWindow()->SetBounds( FullWidthKeyboardBoundsFromRootBounds( root_window()->bounds(), kDefaultVirtualKeyboardHeight)); } @@ -246,7 +238,11 @@ class KeyboardControllerTest : public testing::Test, } bool ShouldEnableInsets(aura::Window* window) { - return controller_->ShouldEnableInsets(window); + aura::Window* keyboard_window = ui_->GetKeyboardWindow(); + return (keyboard_window->GetRootWindow() == window->GetRootWindow() && + keyboard::IsKeyboardOverscrollEnabled() && + keyboard_window->IsVisible() && + controller_->keyboard_visible()); } base::MessageLoopForUI message_loop_; @@ -256,7 +252,7 @@ class KeyboardControllerTest : public testing::Test, private: int number_of_calls_; gfx::Rect notified_bounds_; - KeyboardControllerProxy* proxy_; + KeyboardUI* ui_; scoped_ptr<KeyboardController> controller_; scoped_ptr<ui::TextInputClient> test_text_input_client_; DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); @@ -264,7 +260,7 @@ class KeyboardControllerTest : public testing::Test, TEST_F(KeyboardControllerTest, KeyboardSize) { aura::Window* container(controller()->GetContainerWindow()); - aura::Window* keyboard(proxy()->GetKeyboardWindow()); + aura::Window* keyboard(ui()->GetKeyboardWindow()); gfx::Rect screen_bounds = root_window()->bounds(); root_window()->AddChild(container); container->AddChild(keyboard); @@ -303,7 +299,7 @@ TEST_F(KeyboardControllerTest, KeyboardSize) { TEST_F(KeyboardControllerTest, FloatingKeyboardSize) { aura::Window* container(controller()->GetContainerWindow()); - aura::Window* keyboard(proxy()->GetKeyboardWindow()); + aura::Window* keyboard(ui()->GetKeyboardWindow()); gfx::Rect screen_bounds = root_window()->bounds(); root_window()->AddChild(container); controller()->SetKeyboardMode(FLOATING); @@ -413,11 +409,11 @@ TEST_F(KeyboardControllerTest, CheckOverscrollInsetDuringVisibilityChange) { SetFocus(&no_input_client); // Insets should not be enabled for new windows while keyboard is in the // process of hiding when overscroll is enabled. - EXPECT_FALSE(ShouldEnableInsets(proxy()->GetKeyboardWindow())); + EXPECT_FALSE(ShouldEnableInsets(ui()->GetKeyboardWindow())); // Cancel keyboard hide. SetFocus(&input_client); // Insets should be enabled for new windows as hide was cancelled. - EXPECT_TRUE(ShouldEnableInsets(proxy()->GetKeyboardWindow())); + EXPECT_TRUE(ShouldEnableInsets(ui()->GetKeyboardWindow())); } // Verify switch to FLOATING mode will reset the overscroll or resize and when @@ -543,7 +539,7 @@ class KeyboardControllerAnimationTest : public KeyboardControllerTest { } aura::Window* keyboard_window() { - return proxy()->GetKeyboardWindow(); + return ui()->GetKeyboardWindow(); } private: diff --git a/ui/keyboard/keyboard_layout_manager.cc b/ui/keyboard/keyboard_layout_manager.cc index 60c7303..2af8777 100644 --- a/ui/keyboard/keyboard_layout_manager.cc +++ b/ui/keyboard/keyboard_layout_manager.cc @@ -6,7 +6,6 @@ #include "ui/compositor/layer_animator.h" #include "ui/keyboard/keyboard_controller.h" -#include "ui/keyboard/keyboard_controller_proxy.h" #include "ui/keyboard/keyboard_util.h" namespace keyboard { diff --git a/ui/keyboard/keyboard_ui.cc b/ui/keyboard/keyboard_ui.cc new file mode 100644 index 0000000..816933b --- /dev/null +++ b/ui/keyboard/keyboard_ui.cc @@ -0,0 +1,47 @@ +// Copyright 2015 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 "ui/keyboard/keyboard_ui.h" + +#include "ui/aura/window.h" +#include "ui/base/ime/input_method.h" +#include "ui/base/ime/text_input_client.h" +#include "ui/keyboard/keyboard_controller.h" + +namespace keyboard { + +KeyboardUI::KeyboardUI() : keyboard_controller_(nullptr) {} +KeyboardUI::~KeyboardUI() {} + +void KeyboardUI::ShowKeyboardContainer(aura::Window* container) { + if (HasKeyboardWindow()) { + GetKeyboardWindow()->Show(); + container->Show(); + } +} + +void KeyboardUI::HideKeyboardContainer(aura::Window* container) { + if (HasKeyboardWindow()) { + container->Hide(); + GetKeyboardWindow()->Hide(); + } +} + +void KeyboardUI::EnsureCaretInWorkArea() { + if (GetInputMethod()->GetTextInputClient()) { + aura::Window* keyboard_window = GetKeyboardWindow(); + aura::Window* root_window = keyboard_window->GetRootWindow(); + gfx::Rect available_bounds = root_window->bounds(); + gfx::Rect keyboard_bounds = keyboard_window->bounds(); + available_bounds.set_height(available_bounds.height() - + keyboard_bounds.height()); + GetInputMethod()->GetTextInputClient()->EnsureCaretInRect(available_bounds); + } +} + +void KeyboardUI::SetController(KeyboardController* controller) { + keyboard_controller_ = controller; +} + +} // namespace keyboard diff --git a/ui/keyboard/keyboard_ui.h b/ui/keyboard/keyboard_ui.h new file mode 100644 index 0000000..895617ff --- /dev/null +++ b/ui/keyboard/keyboard_ui.h @@ -0,0 +1,94 @@ +// Copyright 2015 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 UI_KEYBOARD_KEYBOARD_UI_H_ +#define UI_KEYBOARD_KEYBOARD_UI_H_ + +#include "base/macros.h" +#include "ui/base/ime/text_input_type.h" +#include "ui/keyboard/keyboard_export.h" + +namespace aura { +class Window; +} +namespace gfx { +class Rect; +} +namespace ui { +class InputMethod; +} + +namespace keyboard { + +class KeyboardController; + +// An interface implemented by an object that implements a keyboard UI. +class KEYBOARD_EXPORT KeyboardUI { + public: + KeyboardUI(); + virtual ~KeyboardUI(); + + // Gets the virtual keyboard window. May return null if the window has not yet + // been created. + virtual aura::Window* GetKeyboardWindow() = 0; + + // Whether the keyboard window has been created. + virtual bool HasKeyboardWindow() const = 0; + + // Gets the InputMethod that will provide notifications about changes in the + // text input context. + virtual ui::InputMethod* GetInputMethod() = 0; + + // Shows the container window of the keyboard. The default implementation + // simply shows the container. An overridden implementation can set up + // necessary animation, or delay the visibility change as it desires. + virtual void ShowKeyboardContainer(aura::Window* container); + + // Hides the container window of the keyboard. The default implementation + // simply hides the container. An overridden implementation can set up + // necesasry animation, or delay the visibility change as it desires. + virtual void HideKeyboardContainer(aura::Window* container); + + // Updates the type of the focused text input box. + virtual void SetUpdateInputType(ui::TextInputType type) = 0; + + // Ensures caret in current work area (not occluded by virtual keyboard + // window). + virtual void EnsureCaretInWorkArea(); + + // KeyboardController owns the KeyboardUI instance so KeyboardUI subclasses + // should not take ownership of the |controller|. |controller| can be null + // when KeyboardController is destroying. + virtual void SetController(KeyboardController* controller); + + // Reloads virtual keyboard URL if the current keyboard's web content URL is + // different. The URL can be different if user switch from password field to + // any other type input field. + // At password field, the system virtual keyboard is forced to load even if + // the current IME provides a customized virtual keyboard. This is needed to + // prevent IME virtual keyboard logging user's password. Once user switch to + // other input fields, the virtual keyboard should switch back to the IME + // provided keyboard, or keep using the system virtual keyboard if IME doesn't + // provide one. + virtual void ReloadKeyboardIfNeeded() = 0; + + // When the embedder changes the keyboard bounds, asks the keyboard to adjust + // insets for windows affected by this. + virtual void InitInsets(const gfx::Rect& keyboard_bounds) = 0; + + // Resets insets for affected windows. + virtual void ResetInsets() = 0; + + protected: + KeyboardController* keyboard_controller() { return keyboard_controller_; } + + private: + keyboard::KeyboardController* keyboard_controller_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardUI); +}; + +} // namespace keyboard + +#endif // UI_KEYBOARD_KEYBOARD_UI_H_ diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc index ecc8e29..2a5ae6a 100644 --- a/ui/keyboard/keyboard_util.cc +++ b/ui/keyboard/keyboard_util.cc @@ -12,8 +12,6 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/strings/string16.h" -#include "grit/keyboard_resources.h" -#include "grit/keyboard_resources_map.h" #include "media/audio/audio_manager.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_tree_host.h" @@ -26,9 +24,8 @@ #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion.h" #include "ui/keyboard/keyboard_controller.h" -#include "ui/keyboard/keyboard_controller_proxy.h" #include "ui/keyboard/keyboard_switches.h" -#include "url/gurl.h" +#include "ui/keyboard/keyboard_ui.h" namespace { @@ -52,8 +49,6 @@ bool g_accessibility_keyboard_enabled = false; bool g_hotrod_keyboard_enabled = false; -base::LazyInstance<GURL> g_override_content_url = LAZY_INSTANCE_INITIALIZER; - bool g_touch_keyboard_enabled = false; keyboard::KeyboardState g_requested_keyboard_state = @@ -223,7 +218,7 @@ bool InsertText(const base::string16& text) { if (!controller) return false; - ui::InputMethod* input_method = controller->proxy()->GetInputMethod(); + ui::InputMethod* input_method = controller->ui()->GetInputMethod(); if (!input_method) return false; @@ -390,96 +385,6 @@ void MarkKeyboardLoadFinished() { } } -const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { - // This looks a lot like the contents of a resource map; however it is - // necessary to have a custom path for the extension path, so the resource - // map cannot be used directly. - static const GritResourceMap kKeyboardResources[] = { - {"keyboard/locales/en.js", IDR_KEYBOARD_LOCALES_EN}, - {"keyboard/config/emoji.js", IDR_KEYBOARD_CONFIG_EMOJI}, - {"keyboard/config/hwt.js", IDR_KEYBOARD_CONFIG_HWT}, - {"keyboard/config/us.js", IDR_KEYBOARD_CONFIG_US}, - {"keyboard/emoji.css", IDR_KEYBOARD_CSS_EMOJI}, - {"keyboard/images/3dots.png", IDR_KEYBOARD_IMAGES_3_DOTS}, - {"keyboard/images/back_to_keyboard.png", - IDR_KEYBOARD_IMAGES_BACK_TO_KEYBOARD}, - {"keyboard/images/backspace.png", IDR_KEYBOARD_IMAGES_BACKSPACE}, - {"keyboard/images/car.png", IDR_KEYBOARD_IMAGES_CAR}, - {"keyboard/images/check.png", IDR_KEYBOARD_IMAGES_CHECK}, - {"keyboard/images/check_in_menu.png", IDR_KEYBOARD_IMAGES_CHECK_IN_MENU}, - {"keyboard/images/compact.png", IDR_KEYBOARD_IMAGES_COMPACT}, - {"keyboard/images/down.png", IDR_KEYBOARD_IMAGES_DOWN}, - {"keyboard/images/emoji.png", IDR_KEYBOARD_IMAGES_EMOJI}, - {"keyboard/images/emoji_car.png", IDR_KEYBOARD_IMAGES_EMOJI_CAR}, - {"keyboard/images/emoji_crown.png", IDR_KEYBOARD_IMAGES_EMOJI_CROWN}, - {"keyboard/images/emoji_emoticon.png", - IDR_KEYBOARD_IMAGES_EMOJI_EMOTICON}, - {"keyboard/images/emoji_flower.png", IDR_KEYBOARD_IMAGES_EMOJI_FLOWER}, - {"keyboard/images/emoji_hot.png", IDR_KEYBOARD_IMAGES_EMOJI_HOT}, - {"keyboard/images/emoji_recent.png", IDR_KEYBOARD_IMAGES_EMOJI_RECENT}, - {"keyboard/images/emoji_shape.png", IDR_KEYBOARD_IMAGES_EMOJI_SHAPE}, - {"keyboard/images/emoji_cat_items.png", IDR_KEYBOARD_IMAGES_CAT}, - {"keyboard/images/emoticon.png", IDR_KEYBOARD_IMAGES_EMOTICON}, - {"keyboard/images/enter.png", IDR_KEYBOARD_IMAGES_RETURN}, - {"keyboard/images/error.png", IDR_KEYBOARD_IMAGES_ERROR}, - {"keyboard/images/favorit.png", IDR_KEYBOARD_IMAGES_FAVORITE}, - {"keyboard/images/flower.png", IDR_KEYBOARD_IMAGES_FLOWER}, - {"keyboard/images/globe.png", IDR_KEYBOARD_IMAGES_GLOBE}, - {"keyboard/images/hide.png", IDR_KEYBOARD_IMAGES_HIDE}, - {"keyboard/images/hidekeyboard.png", IDR_KEYBOARD_IMAGES_HIDE_KEYBOARD}, - {"keyboard/images/keyboard.svg", IDR_KEYBOARD_IMAGES_KEYBOARD}, - {"keyboard/images/left.png", IDR_KEYBOARD_IMAGES_LEFT}, - {"keyboard/images/penci.png", IDR_KEYBOARD_IMAGES_PENCIL}, - {"keyboard/images/recent.png", IDR_KEYBOARD_IMAGES_RECENT}, - {"keyboard/images/regular_size.png", IDR_KEYBOARD_IMAGES_FULLSIZE}, - {"keyboard/images/menu.png", IDR_KEYBOARD_IMAGES_MENU}, - {"keyboard/images/pencil.png", IDR_KEYBOARD_IMAGES_PENCIL}, - {"keyboard/images/right.png", IDR_KEYBOARD_IMAGES_RIGHT}, - {"keyboard/images/search.png", IDR_KEYBOARD_IMAGES_SEARCH}, - {"keyboard/images/select_right.png", IDR_KEYBOARD_IMAGES_SELECT_RIGHT}, - {"keyboard/images/select_left.png", IDR_KEYBOARD_IMAGES_SELECT_LEFT}, - {"keyboard/images/setting.png", IDR_KEYBOARD_IMAGES_SETTINGS}, - {"keyboard/images/shift.png", IDR_KEYBOARD_IMAGES_SHIFT}, - {"keyboard/images/space.png", IDR_KEYBOARD_IMAGES_SPACE}, - {"keyboard/images/tab.png", IDR_KEYBOARD_IMAGES_TAB}, - {"keyboard/images/tab_in_fullsize.png", - IDR_KEYBOARD_IMAGES_TAB_IN_FULLSIZE}, - {"keyboard/images/triangle.png", IDR_KEYBOARD_IMAGES_TRIANGLE}, - {"keyboard/images/up.png", IDR_KEYBOARD_IMAGES_UP}, - {"keyboard/index.html", IDR_KEYBOARD_INDEX}, - {"keyboard/inputview_adapter.js", IDR_KEYBOARD_INPUTVIEW_ADAPTER}, - {"keyboard/inputview.css", IDR_KEYBOARD_INPUTVIEW_CSS}, - {"keyboard/inputview.js", IDR_KEYBOARD_INPUTVIEW_JS}, - {"keyboard/inputview_layouts/101kbd.js", IDR_KEYBOARD_LAYOUTS_101}, - {"keyboard/inputview_layouts/compactkbd-qwerty.js", - IDR_KEYBOARD_LAYOUTS_COMPACT_QWERTY}, - {"keyboard/inputview_layouts/compactkbd-numberpad.js", - IDR_KEYBOARD_LAYOUTS_COMPACT_NUMBERPAD}, - {"keyboard/inputview_layouts/emoji.js", IDR_KEYBOARD_LAYOUTS_EMOJI}, - {"keyboard/inputview_layouts/handwriting.js", IDR_KEYBOARD_LAYOUTS_HWT}, - {"keyboard/manifest.json", IDR_KEYBOARD_MANIFEST}, - {"keyboard/sounds/keypress-delete.wav", - IDR_KEYBOARD_SOUNDS_KEYPRESS_DELETE}, - {"keyboard/sounds/keypress-return.wav", - IDR_KEYBOARD_SOUNDS_KEYPRESS_RETURN}, - {"keyboard/sounds/keypress-spacebar.wav", - IDR_KEYBOARD_SOUNDS_KEYPRESS_SPACEBAR}, - {"keyboard/sounds/keypress-standard.wav", - IDR_KEYBOARD_SOUNDS_KEYPRESS_STANDARD}, - }; - static const size_t kKeyboardResourcesSize = arraysize(kKeyboardResources); - *size = kKeyboardResourcesSize; - return kKeyboardResources; -} - -void SetOverrideContentUrl(const GURL& url) { - g_override_content_url.Get() = url; -} - -const GURL& GetOverrideContentUrl() { - return g_override_content_url.Get(); -} - void LogKeyboardControlEvent(KeyboardControlEvent event) { UMA_HISTOGRAM_ENUMERATION( "VirtualKeyboard.KeyboardControlEvent", diff --git a/ui/keyboard/keyboard_util.h b/ui/keyboard/keyboard_util.h index 55621b5..2eefc9b 100644 --- a/ui/keyboard/keyboard_util.h +++ b/ui/keyboard/keyboard_util.h @@ -7,13 +7,10 @@ #include <string> -#include "base/strings/string16.h" // TODO(beng): replace with forward decl once RootWindow is renamed. #include "ui/aura/window.h" #include "ui/keyboard/keyboard_export.h" -struct GritResourceMap; - namespace aura { class WindowTreeHost; } @@ -162,11 +159,6 @@ KEYBOARD_EXPORT void MarkKeyboardLoadStarted(); // keyboard is loaded. KEYBOARD_EXPORT void MarkKeyboardLoadFinished(); -// Get the list of keyboard resources. |size| is populated with the number of -// resources in the returned array. -KEYBOARD_EXPORT const GritResourceMap* GetKeyboardExtensionResources( - size_t* size); - // Sets the override content url. // This is used by for input view for extension IMEs. KEYBOARD_EXPORT void SetOverrideContentUrl(const GURL& url); |