Commit b03ffb6b authored by Darren Shen's avatar Darren Shen Committed by Commit Bot

[VK] Clarify KeyboardUI interface.

Currently, KeyboardUI has a weird interface where |GetKeyboardWindow|
will start loading the keyboard web page if it is called the first time.
So this resulted in a lot of places where we were calling
GetKeyboardWindow and didn't know whether it would cause a load or not.

We change the KeyboardUI interface a bit to explicitly state when we
are creating / loading a keyboard window, vs just getting an already
loaded one.

This removes ChromeKeyboardUIWebContent's dependency on
KeyboardController as well.

We tried to keep the same behaviour for existing KeyboardUI subclasses.

Bug: 845780
Change-Id: I3178c81c382f2c3cd8217eda5a0c9b9d489df5be
Reviewed-on: https://chromium-review.googlesource.com/c/1264336
Commit-Queue: Darren Shen <shend@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599772}
parent ef99d0ab
...@@ -14,17 +14,20 @@ ...@@ -14,17 +14,20 @@
namespace ash { namespace ash {
TestKeyboardUI::TestKeyboardUI() = default; TestKeyboardUI::TestKeyboardUI() = default;
TestKeyboardUI::~TestKeyboardUI() = default; TestKeyboardUI::~TestKeyboardUI() = default;
bool TestKeyboardUI::HasKeyboardWindow() const { aura::Window* TestKeyboardUI::LoadKeyboardWindow(LoadCallback callback) {
return !!keyboard_window_; DCHECK(!keyboard_window_);
keyboard_window_ = window_factory::NewWindow(&delegate_);
keyboard_window_->Init(ui::LAYER_NOT_DRAWN);
// TODO(https://crbug.com/849995): Call |callback| instead of having tests
// call |NotifyKeyboardWindowLoaded|.
return keyboard_window_.get();
} }
aura::Window* TestKeyboardUI::GetKeyboardWindow() { aura::Window* TestKeyboardUI::GetKeyboardWindow() const {
if (!keyboard_window_) {
keyboard_window_ = window_factory::NewWindow(&delegate_);
keyboard_window_->Init(ui::LAYER_NOT_DRAWN);
}
return keyboard_window_.get(); return keyboard_window_.get();
} }
......
...@@ -23,8 +23,9 @@ class TestKeyboardUI : public keyboard::KeyboardUI { ...@@ -23,8 +23,9 @@ class TestKeyboardUI : public keyboard::KeyboardUI {
TestKeyboardUI(); TestKeyboardUI();
~TestKeyboardUI() override; ~TestKeyboardUI() override;
bool HasKeyboardWindow() const override; // Overridden from KeyboardUI:
aura::Window* GetKeyboardWindow() override; aura::Window* LoadKeyboardWindow(LoadCallback callback) override;
aura::Window* GetKeyboardWindow() const override;
private: private:
// Overridden from keyboard::KeyboardUI: // Overridden from keyboard::KeyboardUI:
......
...@@ -107,7 +107,7 @@ ChromeKeyboardUI::~ChromeKeyboardUI() { ...@@ -107,7 +107,7 @@ ChromeKeyboardUI::~ChromeKeyboardUI() {
} }
void ChromeKeyboardUI::UpdateInsetsForWindow(aura::Window* window) { void ChromeKeyboardUI::UpdateInsetsForWindow(aura::Window* window) {
if (!HasKeyboardWindow() || !ShouldWindowOverscroll(window)) if (!GetKeyboardWindow() || !ShouldWindowOverscroll(window))
return; return;
std::unique_ptr<content::RenderWidgetHostIterator> widgets( std::unique_ptr<content::RenderWidgetHostIterator> widgets(
...@@ -127,13 +127,12 @@ void ChromeKeyboardUI::UpdateInsetsForWindow(aura::Window* window) { ...@@ -127,13 +127,12 @@ void ChromeKeyboardUI::UpdateInsetsForWindow(aura::Window* window) {
} }
} }
aura::Window* ChromeKeyboardUI::GetKeyboardWindow() { aura::Window* ChromeKeyboardUI::LoadKeyboardWindow(LoadCallback callback) {
if (keyboard_contents_) DCHECK(!keyboard_contents_);
return keyboard_contents_->web_contents()->GetNativeView();
GURL keyboard_url = GetVirtualKeyboardUrl(); GURL keyboard_url = GetVirtualKeyboardUrl();
keyboard_contents_ = std::make_unique<ChromeKeyboardWebContents>( keyboard_contents_ = std::make_unique<ChromeKeyboardWebContents>(
browser_context_, keyboard_url); browser_context_, keyboard_url, std::move(callback));
aura::Window* keyboard_window = aura::Window* keyboard_window =
keyboard_contents_->web_contents()->GetNativeView(); keyboard_contents_->web_contents()->GetNativeView();
...@@ -166,8 +165,10 @@ aura::Window* ChromeKeyboardUI::GetKeyboardWindow() { ...@@ -166,8 +165,10 @@ aura::Window* ChromeKeyboardUI::GetKeyboardWindow() {
return keyboard_window; return keyboard_window;
} }
bool ChromeKeyboardUI::HasKeyboardWindow() const { aura::Window* ChromeKeyboardUI::GetKeyboardWindow() const {
return !!keyboard_contents_; return keyboard_contents_
? keyboard_contents_->web_contents()->GetNativeView()
: nullptr;
} }
ui::InputMethod* ChromeKeyboardUI::GetInputMethod() { ui::InputMethod* ChromeKeyboardUI::GetInputMethod() {
...@@ -286,10 +287,10 @@ bool ChromeKeyboardUI::ShouldWindowOverscroll(aura::Window* window) { ...@@ -286,10 +287,10 @@ bool ChromeKeyboardUI::ShouldWindowOverscroll(aura::Window* window) {
if (!root_window) if (!root_window)
return true; return true;
if (!HasKeyboardWindow()) aura::Window* keyboard_window = GetKeyboardWindow();
if (!keyboard_window)
return false; return false;
aura::Window* keyboard_window = GetKeyboardWindow();
if (root_window != keyboard_window->GetRootWindow()) if (root_window != keyboard_window->GetRootWindow())
return false; return false;
...@@ -310,8 +311,9 @@ void ChromeKeyboardUI::AddBoundsChangedObserver(aura::Window* window) { ...@@ -310,8 +311,9 @@ void ChromeKeyboardUI::AddBoundsChangedObserver(aura::Window* window) {
} }
void ChromeKeyboardUI::SetShadowAroundKeyboard() { void ChromeKeyboardUI::SetShadowAroundKeyboard() {
DCHECK(HasKeyboardWindow());
aura::Window* contents_window = GetKeyboardWindow(); aura::Window* contents_window = GetKeyboardWindow();
DCHECK(contents_window);
if (!shadow_) { if (!shadow_) {
shadow_ = std::make_unique<ui::Shadow>(); shadow_ = std::make_unique<ui::Shadow>();
shadow_->Init(kShadowElevationVirtualKeyboard); shadow_->Init(kShadowElevationVirtualKeyboard);
......
...@@ -52,8 +52,8 @@ class ChromeKeyboardUI : public keyboard::KeyboardUI, ...@@ -52,8 +52,8 @@ class ChromeKeyboardUI : public keyboard::KeyboardUI,
void UpdateInsetsForWindow(aura::Window* window); void UpdateInsetsForWindow(aura::Window* window);
// Overridden from KeyboardUI: // Overridden from KeyboardUI:
aura::Window* GetKeyboardWindow() override; aura::Window* LoadKeyboardWindow(LoadCallback callback) override;
bool HasKeyboardWindow() const override; aura::Window* GetKeyboardWindow() const override;
ui::InputMethod* GetInputMethod() override; ui::InputMethod* GetInputMethod() override;
void ReloadKeyboardIfNeeded() override; void ReloadKeyboardIfNeeded() override;
void InitInsets(const gfx::Rect& new_bounds) override; void InitInsets(const gfx::Rect& new_bounds) override;
......
...@@ -37,8 +37,9 @@ class ChromeKeyboardUITest : public ChromeRenderViewHostTestHarness { ...@@ -37,8 +37,9 @@ class ChromeKeyboardUITest : public ChromeRenderViewHostTestHarness {
} // namespace } // namespace
// Ensure ChromeKeyboardContentsDelegate is successfully constructed and has // Ensure ChromeKeyboardContentsDelegate is successfully constructed and has
// a valid aura::Window when GetKeyboardWindow() is called. // a valid aura::Window after calling LoadKeyboardWindow().
TEST_F(ChromeKeyboardUITest, ChromeKeyboardContentsDelegate) { TEST_F(ChromeKeyboardUITest, ChromeKeyboardContentsDelegate) {
aura::Window* window = chrome_keyboard_ui_->GetKeyboardWindow(); aura::Window* window =
ASSERT_TRUE(window); chrome_keyboard_ui_->LoadKeyboardWindow(base::DoNothing());
EXPECT_TRUE(window);
} }
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
#include "third_party/blink/public/platform/web_gesture_event.h" #include "third_party/blink/public/platform/web_gesture_event.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_features.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_resource_util.h"
namespace { namespace {
...@@ -124,7 +122,9 @@ class ChromeKeyboardContentsDelegate : public content::WebContentsDelegate, ...@@ -124,7 +122,9 @@ class ChromeKeyboardContentsDelegate : public content::WebContentsDelegate,
ChromeKeyboardWebContents::ChromeKeyboardWebContents( ChromeKeyboardWebContents::ChromeKeyboardWebContents(
content::BrowserContext* context, content::BrowserContext* context,
const GURL& url) { const GURL& url,
LoadCallback callback)
: callback_(std::move(callback)) {
DCHECK(context); DCHECK(context);
content::WebContents::CreateParams web_contents_params( content::WebContents::CreateParams web_contents_params(
context, content::SiteInstance::CreateForURL(context, url)); context, content::SiteInstance::CreateForURL(context, url));
...@@ -171,9 +171,7 @@ void ChromeKeyboardWebContents::RenderViewCreated( ...@@ -171,9 +171,7 @@ void ChromeKeyboardWebContents::RenderViewCreated(
void ChromeKeyboardWebContents::DidFinishLoad( void ChromeKeyboardWebContents::DidFinishLoad(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const GURL& validated_url) { const GURL& validated_url) {
// TODO(mash): Support virtual keyboard. https://crbug.com/843332. std::move(callback_).Run();
if (!features::IsMultiProcessMash())
keyboard::KeyboardController::Get()->NotifyKeyboardWindowLoaded();
} }
void ChromeKeyboardWebContents::LoadContents(const GURL& url) { void ChromeKeyboardWebContents::LoadContents(const GURL& url) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
...@@ -20,11 +21,15 @@ class WebContents; ...@@ -20,11 +21,15 @@ class WebContents;
// contents, manages the content::HostZoomMap, and informs the virtual // contents, manages the content::HostZoomMap, and informs the virtual
// keyboard controller when the contents have loaded. It also provides a // keyboard controller when the contents have loaded. It also provides a
// WebContentsDelegate implementation. // WebContentsDelegate implementation.
// TODO(mash): Remove keyboard::KeyboardController dependency to support
// multi process mash.
class ChromeKeyboardWebContents : public content::WebContentsObserver { class ChromeKeyboardWebContents : public content::WebContentsObserver {
public: public:
ChromeKeyboardWebContents(content::BrowserContext* context, const GURL& url); using LoadCallback = base::OnceCallback<void()>;
// Immediately starts loading |url| in a WebContents. |callback| is called
// when the WebContents finishes loading.
ChromeKeyboardWebContents(content::BrowserContext* context,
const GURL& url,
LoadCallback callback);
~ChromeKeyboardWebContents() override; ~ChromeKeyboardWebContents() override;
// Updates the keyboard URL if |url| does not match the existing url. // Updates the keyboard URL if |url| does not match the existing url.
...@@ -45,6 +50,7 @@ class ChromeKeyboardWebContents : public content::WebContentsObserver { ...@@ -45,6 +50,7 @@ class ChromeKeyboardWebContents : public content::WebContentsObserver {
void LoadContents(const GURL& url); void LoadContents(const GURL& url);
std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<content::WebContents> web_contents_;
LoadCallback callback_;
DISALLOW_COPY_AND_ASSIGN(ChromeKeyboardWebContents); DISALLOW_COPY_AND_ASSIGN(ChromeKeyboardWebContents);
}; };
......
...@@ -27,9 +27,10 @@ class ChromeKeyboardWebContentsTest : public ChromeRenderViewHostTestHarness { ...@@ -27,9 +27,10 @@ class ChromeKeyboardWebContentsTest : public ChromeRenderViewHostTestHarness {
ChromeRenderViewHostTestHarness::TearDown(); ChromeRenderViewHostTestHarness::TearDown();
} }
void CreateWebContents(const GURL& url) { void CreateWebContents(const GURL& url,
chrome_keyboard_web_contents_ = ChromeKeyboardWebContents::LoadCallback callback) {
std::make_unique<ChromeKeyboardWebContents>(profile(), url); chrome_keyboard_web_contents_ = std::make_unique<ChromeKeyboardWebContents>(
profile(), url, std::move(callback));
} }
protected: protected:
...@@ -61,7 +62,7 @@ class TestDelegate : public content::WebContentsDelegate { ...@@ -61,7 +62,7 @@ class TestDelegate : public content::WebContentsDelegate {
// Calling SetKeyboardUrl with a different URL should open the new page. // Calling SetKeyboardUrl with a different URL should open the new page.
TEST_F(ChromeKeyboardWebContentsTest, SetKeyboardUrl) { TEST_F(ChromeKeyboardWebContentsTest, SetKeyboardUrl) {
CreateWebContents(GURL("http://foo.com")); CreateWebContents(GURL("http://foo.com"), base::DoNothing());
ASSERT_TRUE(chrome_keyboard_web_contents_->web_contents()); ASSERT_TRUE(chrome_keyboard_web_contents_->web_contents());
// Override the delegate to test that OpenURLFromTab gets called. // Override the delegate to test that OpenURLFromTab gets called.
......
...@@ -283,7 +283,7 @@ void KeyboardController::DeactivateKeyboard() { ...@@ -283,7 +283,7 @@ void KeyboardController::DeactivateKeyboard() {
} }
aura::Window* KeyboardController::GetKeyboardWindow() const { aura::Window* KeyboardController::GetKeyboardWindow() const {
return ui_ && ui_->HasKeyboardWindow() ? ui_->GetKeyboardWindow() : nullptr; return ui_ ? ui_->GetKeyboardWindow() : nullptr;
} }
aura::Window* KeyboardController::GetRootWindow() { aura::Window* KeyboardController::GetRootWindow() {
...@@ -710,10 +710,13 @@ void KeyboardController::PopulateKeyboardContent( ...@@ -710,10 +710,13 @@ void KeyboardController::PopulateKeyboardContent(
if (parent_container_->children().empty()) { if (parent_container_->children().empty()) {
DCHECK_EQ(state_, KeyboardControllerState::INITIAL); DCHECK_EQ(state_, KeyboardControllerState::INITIAL);
// TODO(https://crbug.com/845780): This call will create and load the // For now, using Unretained is safe here because the |ui_| is owned by
// virtual keyboard window. Redesign the KeyboardUI interface so that // |this| and the callback does not outlive |ui_|.
// loading is explicit. // TODO(https://crbug.com/845780): Use a weak ptr here in case this
aura::Window* keyboard_window = ui_->GetKeyboardWindow(); // assumption changes.
aura::Window* keyboard_window = ui_->LoadKeyboardWindow(
base::BindOnce(&KeyboardController::NotifyKeyboardWindowLoaded,
base::Unretained(this)));
keyboard_window->AddPreTargetHandler(&event_filter_); keyboard_window->AddPreTargetHandler(&event_filter_);
keyboard_window->AddObserver(this); keyboard_window->AddObserver(this);
parent_container_->AddChild(keyboard_window); parent_container_->AddChild(keyboard_window);
......
...@@ -18,15 +18,17 @@ KeyboardUI::KeyboardUI() = default; ...@@ -18,15 +18,17 @@ KeyboardUI::KeyboardUI() = default;
KeyboardUI::~KeyboardUI() = default; KeyboardUI::~KeyboardUI() = default;
void KeyboardUI::ShowKeyboardWindow() { void KeyboardUI::ShowKeyboardWindow() {
if (HasKeyboardWindow()) { aura::Window* window = GetKeyboardWindow();
if (window) {
TRACE_EVENT0("vk", "ShowKeyboardWindow"); TRACE_EVENT0("vk", "ShowKeyboardWindow");
GetKeyboardWindow()->Show(); window->Show();
} }
} }
void KeyboardUI::HideKeyboardWindow() { void KeyboardUI::HideKeyboardWindow() {
if (HasKeyboardWindow()) aura::Window* window = GetKeyboardWindow();
GetKeyboardWindow()->Hide(); if (window)
window->Hide();
} }
void KeyboardUI::SetController(KeyboardController* controller) { void KeyboardUI::SetController(KeyboardController* controller) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef UI_KEYBOARD_KEYBOARD_UI_H_ #ifndef UI_KEYBOARD_KEYBOARD_UI_H_
#define UI_KEYBOARD_KEYBOARD_UI_H_ #define UI_KEYBOARD_KEYBOARD_UI_H_
#include "base/callback_forward.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/base/ime/text_input_type.h" #include "ui/base/ime/text_input_type.h"
#include "ui/keyboard/keyboard_export.h" #include "ui/keyboard/keyboard_export.h"
...@@ -26,17 +27,21 @@ class KeyboardController; ...@@ -26,17 +27,21 @@ class KeyboardController;
// Interface representing a window containing virtual keyboard UI. // Interface representing a window containing virtual keyboard UI.
class KEYBOARD_EXPORT KeyboardUI { class KEYBOARD_EXPORT KeyboardUI {
public: public:
using LoadCallback = base::OnceCallback<void()>;
KeyboardUI(); KeyboardUI();
virtual ~KeyboardUI(); virtual ~KeyboardUI();
// Gets the virtual keyboard window i.e. the WebContents window where // Begin loading the virtual keyboard window asynchronously.
// keyboard extensions are loaded. May return null if the window has not yet // Returns a window immediately, but the UI within the window is not
// been created. // guaranteed to be fully loaded until |callback| is called.
// This class owns the window. // This function can only be called once.
virtual aura::Window* GetKeyboardWindow() = 0; virtual aura::Window* LoadKeyboardWindow(LoadCallback callback) = 0;
// Whether the keyboard window has been created. // Gets the virtual keyboard window i.e. the WebContents window where
virtual bool HasKeyboardWindow() const = 0; // keyboard extensions are loaded. Returns null if the window has not started
// loading.
virtual aura::Window* GetKeyboardWindow() const = 0;
// Gets the InputMethod that will provide notifications about changes in the // Gets the InputMethod that will provide notifications about changes in the
// text input context. // text input context.
......
...@@ -124,21 +124,23 @@ TestKeyboardUI::~TestKeyboardUI() { ...@@ -124,21 +124,23 @@ TestKeyboardUI::~TestKeyboardUI() {
window_.reset(); window_.reset();
} }
aura::Window* TestKeyboardUI::GetKeyboardWindow() { aura::Window* TestKeyboardUI::LoadKeyboardWindow(LoadCallback callback) {
if (!window_) { DCHECK(!window_);
window_.reset(new aura::Window(&delegate_)); window_ = std::make_unique<aura::Window>(&delegate_);
window_->Init(ui::LAYER_NOT_DRAWN); window_->Init(ui::LAYER_NOT_DRAWN);
window_->set_owned_by_parent(false); window_->set_owned_by_parent(false);
}
// TODO(https://crbug.com/849995): Call |callback| instead of having tests
// call |NotifyKeyboardWindowLoaded|.
return window_.get(); return window_.get();
} }
ui::InputMethod* TestKeyboardUI::GetInputMethod() { aura::Window* TestKeyboardUI::GetKeyboardWindow() const {
return input_method_; return window_.get();
} }
bool TestKeyboardUI::HasKeyboardWindow() const { ui::InputMethod* TestKeyboardUI::GetInputMethod() {
return !!window_; return input_method_;
} }
} // namespace keyboard } // namespace keyboard
...@@ -43,8 +43,8 @@ class TestKeyboardUI : public KeyboardUI { ...@@ -43,8 +43,8 @@ class TestKeyboardUI : public KeyboardUI {
~TestKeyboardUI() override; ~TestKeyboardUI() override;
// Overridden from KeyboardUI: // Overridden from KeyboardUI:
bool HasKeyboardWindow() const override; aura::Window* LoadKeyboardWindow(LoadCallback callback) override;
aura::Window* GetKeyboardWindow() override; aura::Window* GetKeyboardWindow() const override;
ui::InputMethod* GetInputMethod() override; ui::InputMethod* GetInputMethod() override;
void ReloadKeyboardIfNeeded() override {} void ReloadKeyboardIfNeeded() override {}
void InitInsets(const gfx::Rect& keyboard_bounds) override {} void InitInsets(const gfx::Rect& keyboard_bounds) override {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment