| Index: content/public/test/text_input_test_utils.cc
|
| diff --git a/content/public/test/text_input_test_utils.cc b/content/public/test/text_input_test_utils.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..895f7b743d0bee0f76c7df4b0aa4641cdf921927
|
| --- /dev/null
|
| +++ b/content/public/test/text_input_test_utils.cc
|
| @@ -0,0 +1,325 @@
|
| +// Copyright 2016 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 "content/public/test/text_input_test_utils.h"
|
| +
|
| +#include "content/browser/renderer_host/render_widget_host_view_aura.h"
|
| +#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
| +#include "content/browser/renderer_host/render_widget_host_view_base_observer.h"
|
| +#include "content/browser/renderer_host/text_input_manager.h"
|
| +#include "content/browser/web_contents/web_contents_impl.h"
|
| +#include "content/common/text_input_state.h"
|
| +#include "content/public/browser/render_widget_host_view.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/browser/web_contents_observer.h"
|
| +#include "content/public/test/test_utils.h"
|
| +#include "ui/base/ime/input_method.h"
|
| +#include "ui/base/ime/input_method_observer.h"
|
| +
|
| +namespace ui {
|
| +class TextInputClient;
|
| +}
|
| +
|
| +namespace content {
|
| +
|
| +// This class is an observer of TextInputManager associated with the provided
|
| +// WebContents. An instance of this class is used in TextInputManagerTester to
|
| +// expose the required API for testing outside of content/.
|
| +class TextInputManagerTester::InternalObserver
|
| + : public TextInputManager::Observer,
|
| + public WebContentsObserver {
|
| + public:
|
| + InternalObserver(WebContents* web_contents, TextInputManagerTester* tester)
|
| + : WebContentsObserver(web_contents),
|
| + tester_(tester),
|
| + updated_view_(nullptr),
|
| + text_input_state_changed_(false) {
|
| + text_input_manager_ =
|
| + static_cast<WebContentsImpl*>(web_contents)->GetTextInputManager();
|
| + DCHECK(!!text_input_manager_);
|
| + text_input_manager_->AddObserver(this);
|
| + }
|
| +
|
| + ~InternalObserver() override {
|
| + if (text_input_manager_)
|
| + text_input_manager_->RemoveObserver(this);
|
| + }
|
| +
|
| + void set_update_text_input_state_called_callback(
|
| + const TextInputManagerTester::Callback& callback) {
|
| + update_text_input_state_callback_ = callback;
|
| + }
|
| +
|
| + const RenderWidgetHostView* GetUpdatedView() const { return updated_view_; }
|
| +
|
| + bool text_input_state_changed() const { return text_input_state_changed_; }
|
| +
|
| + TextInputManager* text_input_manager() const { return text_input_manager_; }
|
| +
|
| + // TextInputManager::Observer implementations.
|
| + void OnUpdateTextInputStateCalled(TextInputManager* text_input_manager,
|
| + RenderWidgetHostViewBase* updated_view,
|
| + bool did_change_state) override {
|
| + if (text_input_manager_ != text_input_manager)
|
| + return;
|
| + text_input_state_changed_ = did_change_state;
|
| + updated_view_ = updated_view;
|
| + update_text_input_state_callback_.Run(tester_);
|
| + }
|
| +
|
| + // WebContentsObserver implementation.
|
| + void WebContentsDestroyed() override { text_input_manager_ = nullptr; }
|
| +
|
| + private:
|
| + TextInputManagerTester* tester_;
|
| + TextInputManager* text_input_manager_;
|
| + RenderWidgetHostViewBase* updated_view_;
|
| + bool text_input_state_changed_;
|
| + TextInputManagerTester::Callback update_text_input_state_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(InternalObserver);
|
| +};
|
| +
|
| +// This class observes the lifetime of a RenderWidgetHostView. An instance of
|
| +// this class is used in TestRenderWidgetHostViewDestructionObserver to expose
|
| +// the required observer API for testing outside of content/.
|
| +class TestRenderWidgetHostViewDestructionObserver::InternalObserver
|
| + : public RenderWidgetHostViewBaseObserver {
|
| + public:
|
| + InternalObserver(RenderWidgetHostViewBase* view)
|
| + : view_(view), destroyed_(false) {
|
| + view->AddObserver(this);
|
| + }
|
| +
|
| + ~InternalObserver() override {
|
| + if (view_)
|
| + view_->RemoveObserver(this);
|
| + }
|
| +
|
| + void Wait() {
|
| + if (destroyed_)
|
| + return;
|
| + message_loop_runner_ = new content::MessageLoopRunner();
|
| + message_loop_runner_->Run();
|
| + }
|
| +
|
| + private:
|
| + void OnRenderWidgetHostViewBaseDestroyed(
|
| + RenderWidgetHostViewBase* view) override {
|
| + DCHECK_EQ(view_, view);
|
| + destroyed_ = true;
|
| + view->RemoveObserver(this);
|
| + view_ = nullptr;
|
| + if (message_loop_runner_)
|
| + message_loop_runner_->Quit();
|
| + }
|
| +
|
| + RenderWidgetHostViewBase* view_;
|
| + bool destroyed_;
|
| + scoped_refptr<MessageLoopRunner> message_loop_runner_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(InternalObserver);
|
| +};
|
| +
|
| +#ifdef USE_AURA
|
| +class InputMethodObserverAura : public TestInputMethodObserver,
|
| + public ui::InputMethodObserver {
|
| + public:
|
| + explicit InputMethodObserverAura(ui::InputMethod* input_method)
|
| + : input_method_(input_method), text_input_client_(nullptr) {
|
| + input_method_->AddObserver(this);
|
| + }
|
| +
|
| + ~InputMethodObserverAura() override {
|
| + if (input_method_)
|
| + input_method_->RemoveObserver(this);
|
| + }
|
| +
|
| + // TestInputMethodObserver implementations.
|
| + ui::TextInputType GetTextInputTypeFromClient() override {
|
| + if (text_input_client_)
|
| + return text_input_client_->GetTextInputType();
|
| +
|
| + return ui::TEXT_INPUT_TYPE_NONE;
|
| + }
|
| +
|
| + void SetOnTextInputTypeChangedCallback(
|
| + const base::Closure& callback) override {
|
| + on_text_input_type_changed_callback_ = callback;
|
| + }
|
| +
|
| + void SetOnShowImeIfNeededCallback(const base::Closure& callback) override {
|
| + on_show_ime_if_needed_callback_ = callback;
|
| + }
|
| +
|
| + private:
|
| + // ui::InputMethodObserver implementations.
|
| + void OnTextInputTypeChanged(const ui::TextInputClient* client) override {
|
| + text_input_client_ = client;
|
| + on_text_input_type_changed_callback_.Run();
|
| + }
|
| +
|
| + void OnFocus() override {}
|
| + void OnBlur() override {}
|
| + void OnCaretBoundsChanged(const ui::TextInputClient* client) override {}
|
| + void OnTextInputStateChanged(const ui::TextInputClient* client) override {}
|
| + void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {}
|
| +
|
| + void OnShowImeIfNeeded() override { on_show_ime_if_needed_callback_.Run(); }
|
| +
|
| + ui::InputMethod* input_method_;
|
| + const ui::TextInputClient* text_input_client_;
|
| + base::Closure on_text_input_type_changed_callback_;
|
| + base::Closure on_show_ime_if_needed_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(InputMethodObserverAura);
|
| +};
|
| +#endif
|
| +
|
| +ui::TextInputType GetTextInputTypeFromWebContents(WebContents* web_contents) {
|
| + const TextInputState* state = static_cast<WebContentsImpl*>(web_contents)
|
| + ->GetTextInputManager()
|
| + ->GetTextInputState();
|
| + return !!state ? state->type : ui::TEXT_INPUT_TYPE_NONE;
|
| +}
|
| +
|
| +bool GetTextInputTypeForView(WebContents* web_contents,
|
| + RenderWidgetHostView* view,
|
| + ui::TextInputType* type) {
|
| + TextInputManager* manager =
|
| + static_cast<WebContentsImpl*>(web_contents)->GetTextInputManager();
|
| +
|
| + RenderWidgetHostViewBase* view_base =
|
| + static_cast<RenderWidgetHostViewBase*>(view);
|
| + if (!manager || !manager->IsRegistered(view_base))
|
| + return false;
|
| +
|
| + *type = manager->text_input_state_map_[view_base].type;
|
| + return true;
|
| +}
|
| +
|
| +RenderWidgetHostView* GetActiveViewFromWebContents(WebContents* web_contents) {
|
| + return static_cast<WebContentsImpl*>(web_contents)
|
| + ->GetTextInputManager()
|
| + ->GetActiveView();
|
| +}
|
| +
|
| +TextInputManagerTester::TextInputManagerTester(WebContents* web_contents)
|
| + : observer_(new InternalObserver(web_contents, this)) {}
|
| +
|
| +TextInputManagerTester::~TextInputManagerTester() {}
|
| +
|
| +void TextInputManagerTester::SetUpdateTextInputStateCalledCallback(
|
| + const Callback& callback) {
|
| + observer_->set_update_text_input_state_called_callback(callback);
|
| +}
|
| +
|
| +bool TextInputManagerTester::GetTextInputType(ui::TextInputType* type) {
|
| + DCHECK(observer_->text_input_manager());
|
| + const TextInputState* state =
|
| + observer_->text_input_manager()->GetTextInputState();
|
| + if (!state)
|
| + return false;
|
| + *type = state->type;
|
| + return true;
|
| +}
|
| +
|
| +bool TextInputManagerTester::GetTextInputValue(std::string* value) {
|
| + DCHECK(observer_->text_input_manager());
|
| + const TextInputState* state =
|
| + observer_->text_input_manager()->GetTextInputState();
|
| + if (!state)
|
| + return false;
|
| + *value = state->value;
|
| + return true;
|
| +}
|
| +
|
| +const RenderWidgetHostView* TextInputManagerTester::GetActiveView() {
|
| + DCHECK(observer_->text_input_manager());
|
| + return observer_->text_input_manager()->GetActiveView();
|
| +}
|
| +
|
| +const RenderWidgetHostView* TextInputManagerTester::GetUpdatedView() {
|
| + return observer_->GetUpdatedView();
|
| +}
|
| +
|
| +bool TextInputManagerTester::IsTextInputStateChanged() {
|
| + return observer_->text_input_state_changed();
|
| +}
|
| +
|
| +TestRenderWidgetHostViewDestructionObserver::
|
| + TestRenderWidgetHostViewDestructionObserver(RenderWidgetHostView* view)
|
| + : observer_(
|
| + new InternalObserver(static_cast<RenderWidgetHostViewBase*>(view))) {}
|
| +
|
| +TestRenderWidgetHostViewDestructionObserver::
|
| + ~TestRenderWidgetHostViewDestructionObserver() {}
|
| +
|
| +void TestRenderWidgetHostViewDestructionObserver::Wait() {
|
| + observer_->Wait();
|
| +}
|
| +
|
| +TextInputStateSender::TextInputStateSender(RenderWidgetHostView* view)
|
| + : text_input_state_(new TextInputState()),
|
| + view_(static_cast<RenderWidgetHostViewBase*>(view)) {}
|
| +
|
| +TextInputStateSender::~TextInputStateSender() {}
|
| +
|
| +void TextInputStateSender::Send() {
|
| + if (view_)
|
| + view_->TextInputStateChanged(*text_input_state_);
|
| +}
|
| +
|
| +void TextInputStateSender::SetFromCurrentState() {
|
| + if (view_) {
|
| + *text_input_state_ =
|
| + *RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())
|
| + ->delegate()
|
| + ->GetTextInputManager()
|
| + ->GetTextInputState();
|
| + }
|
| +}
|
| +
|
| +void TextInputStateSender::SetType(ui::TextInputType type) {
|
| + text_input_state_->type = type;
|
| +}
|
| +
|
| +void TextInputStateSender::SetMode(ui::TextInputMode mode) {
|
| + text_input_state_->mode = mode;
|
| +}
|
| +
|
| +void TextInputStateSender::SetFlags(int flags) {
|
| + text_input_state_->flags = flags;
|
| +}
|
| +
|
| +void TextInputStateSender::SetCanComposeInline(bool can_compose_inline) {
|
| + text_input_state_->can_compose_inline = can_compose_inline;
|
| +}
|
| +
|
| +void TextInputStateSender::SetShowImeIfNeeded(bool show_ime_if_needed) {
|
| + text_input_state_->show_ime_if_needed = show_ime_if_needed;
|
| +}
|
| +
|
| +void TextInputStateSender::SetIsNonImeChange(bool is_non_ime_change) {
|
| + text_input_state_->is_non_ime_change = is_non_ime_change;
|
| +}
|
| +
|
| +TestInputMethodObserver::TestInputMethodObserver() {}
|
| +
|
| +TestInputMethodObserver::~TestInputMethodObserver() {}
|
| +
|
| +// static
|
| +std::unique_ptr<TestInputMethodObserver> TestInputMethodObserver::Create(
|
| + WebContents* web_contents) {
|
| + std::unique_ptr<TestInputMethodObserver> observer;
|
| +
|
| +#ifdef USE_AURA
|
| + RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
|
| + web_contents->GetRenderWidgetHostView());
|
| + observer.reset(new InputMethodObserverAura(view->GetInputMethod()));
|
| +#endif
|
| + return observer;
|
| +}
|
| +
|
| +} // namespace content
|
|
|