Chromium Code Reviews| 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..18eea8bc60fda9ea00862b87a3115395d9d8c89d |
| --- /dev/null |
| +++ b/content/public/test/text_input_test_utils.cc |
| @@ -0,0 +1,301 @@ |
| +// 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/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 { |
| + |
| +namespace { |
| + |
| +// The implementation of the TestTextInputManagerObserver which is observing the |
| +// content::TextInputManager for the given WebContentsImpl. |
| +class TextInputManagerObserver : public TestTextInputManagerObserver, |
| + public TextInputManager::Observer { |
| + public: |
| + // TestTextInputManagerObserver implementations. |
| + TextInputManagerObserver(WebContents* web_contents) |
| + : updated_view_(nullptr), changed_(false) { |
| + text_input_manager_ = |
| + static_cast<WebContentsImpl*>(web_contents)->GetTextInputManager(); |
| + DCHECK(!!text_input_manager_); |
| + text_input_manager_->AddObserver(this); |
| + } |
| + |
| + ~TextInputManagerObserver() override { |
| + text_input_manager_->RemoveObserver(this); |
| + } |
| + |
| + void SetUpdateCallback(const content::TestTextInputManagerObserver::Callback& |
| + callback) override { |
| + update_callback_.reset( |
| + new content::TestTextInputManagerObserver::Callback(callback)); |
| + } |
| + |
| + bool GetTextInputValue(std::string& value) const override { |
| + const content::TextInputState* state = |
| + text_input_manager_->GetTextInputState(); |
| + if (!state) |
| + return false; |
| + value = state->value; |
| + return true; |
| + } |
| + |
| + ui::TextInputType GetTextInputType() const override { |
| + const content::TextInputState* state = |
| + text_input_manager_->GetTextInputState(); |
| + return !!state ? state->type : ui::TEXT_INPUT_TYPE_NONE; |
| + } |
| + |
| + const RenderWidgetHostView* GetActiveView() const override { |
| + return text_input_manager_->GetActiveView(); |
| + } |
| + |
| + const RenderWidgetHostView* GetUpdatedView() const override { |
| + return updated_view_; |
| + } |
| + |
| + bool IsTextInputStateChanged() const override { return changed_; } |
| + |
| + private: |
| + // TextInputManager::Observer implementations. |
| + void OnTextInputStateUpdated(TextInputManager* text_input_manager, |
| + RenderWidgetHostViewBase* updated_view, |
| + bool changed) override { |
| + if (text_input_manager_ != text_input_manager) |
| + return; |
| + changed_ = changed; |
| + updated_view_ = updated_view; |
| + if (update_callback_) |
| + update_callback_->Run(this); |
| + } |
| + |
| + content::TextInputManager* text_input_manager_; |
| + content::RenderWidgetHostViewBase* updated_view_; |
| + bool changed_; |
| + std::unique_ptr<content::TestTextInputManagerObserver::Callback> |
| + update_callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TextInputManagerObserver); |
| +}; |
| + |
| +class RenderWidgetHostViewBaseObserverImpl |
| + : public RenderWidgetHostViewBaseObserver, |
| + public RenderWidgetHostViewDestructionObserver { |
| + public: |
| + RenderWidgetHostViewBaseObserverImpl(RenderWidgetHostViewBase* view) |
| + : view_(view), destroyed_(false) { |
| + view->AddObserver(this); |
| + } |
| + |
| + void Wait() override { |
| + if (destroyed_) |
| + return; |
| + message_loop_runner_ = new content::MessageLoopRunner(); |
| + message_loop_runner_->Run(); |
| + } |
| + |
| + private: |
| + void OnRenderWidgetHostViewBaseDestroyed( |
| + RenderWidgetHostViewBase* view) override { |
| + DCHECK(view_ == view); |
| + destroyed_ = true; |
| + view->RemoveObserver(this); |
| + if (message_loop_runner_ && message_loop_runner_->loop_running()) |
| + message_loop_runner_->Quit(); |
| + } |
| + |
| + RenderWidgetHostView* view_; |
| + bool destroyed_; |
| + scoped_refptr<MessageLoopRunner> message_loop_runner_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewBaseObserverImpl); |
| +}; |
| + |
| +#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() const 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_.reset(new base::Closure(callback)); |
| + } |
| + |
| + void SetOnShowImeIfNeededCallback(const base::Closure& callback) override { |
| + on_show_ime_if_needed_callback_.reset(new base::Closure(callback)); |
| + } |
| + |
| + private: |
| + // ui::InputMethodObserver implementations. |
| + void OnTextInputTypeChanged(const ui::TextInputClient* client) override { |
| + text_input_client_ = client; |
| + if (on_text_input_type_changed_callback_) |
| + 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 { |
| + if (on_show_ime_if_needed_callback_) |
| + on_show_ime_if_needed_callback_->Run(); |
| + } |
| + |
| + ui::InputMethod* input_method_; |
| + const ui::TextInputClient* text_input_client_; |
| + std::unique_ptr<base::Closure> on_text_input_type_changed_callback_; |
| + std::unique_ptr<base::Closure> on_show_ime_if_needed_callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(InputMethodObserverAura); |
| +}; |
| +#endif |
| + |
| +} // namespace |
| + |
| +// TestTextInputManagerObserver Implementations. |
| +TestTextInputManagerObserver::~TestTextInputManagerObserver() {} |
| + |
| +// static |
| +std::unique_ptr<TestTextInputManagerObserver> |
| +TestTextInputManagerObserver::Create(WebContents* web_contents) { |
| + return std::unique_ptr<TestTextInputManagerObserver>( |
| + static_cast<TestTextInputManagerObserver*>( |
|
dcheng
2016/05/10 20:33:41
return base::WrapUnique(new TextInputManagerObserv
EhsanK
2016/05/11 01:54:03
Thanks! This is great!
|
| + new TextInputManagerObserver(web_contents))); |
| +} |
| + |
| +// static |
| +std::unordered_map<const RenderWidgetHostView*, ui::TextInputType> |
| +TestTextInputManagerObserver::GetTextInputTypeMap(WebContents* web_contents) { |
| + TextInputManager* manager = |
| + static_cast<WebContentsImpl*>(web_contents)->GetTextInputManager(); |
| + std::unordered_map<const RenderWidgetHostView*, ui::TextInputType> result; |
| + for (const auto& pair : manager->text_input_state_map_) |
| + result[pair.first] = pair.second.type; |
| + return result; |
| +} |
| + |
| +// RenderWidgetHostViewDestructionObserver implementations. |
| +RenderWidgetHostViewDestructionObserver:: |
| + ~RenderWidgetHostViewDestructionObserver() {} |
| + |
| +// static |
| +std::unique_ptr<RenderWidgetHostViewDestructionObserver> |
| +RenderWidgetHostViewDestructionObserver::Create(RenderWidgetHostView* view) { |
| + return std::unique_ptr<RenderWidgetHostViewDestructionObserver>( |
| + static_cast<RenderWidgetHostViewDestructionObserver*>( |
|
dcheng
2016/05/10 20:33:41
return base::WrapUnique(new RenderWidgetHostViewBa
EhsanK
2016/05/11 01:54:03
Done.
|
| + new RenderWidgetHostViewBaseObserverImpl( |
| + static_cast<RenderWidgetHostViewBase*>(view)))); |
| +} |
| + |
| +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; |
| +} |
| + |
| +RenderWidgetHostView* GetActiveViewFromWebContents(WebContents* web_contents) { |
| + return static_cast<WebContentsImpl*>(web_contents) |
| + ->GetTextInputManager() |
| + ->GetActiveView(); |
| +} |
| + |
| +// TextInputStateSender implementations. |
| +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 implementations. |
| +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(static_cast<TestInputMethodObserver*>( |
| + new InputMethodObserverAura(view->GetInputMethod()))); |
|
dcheng
2016/05/10 20:33:41
This static cast should be unnecessary. IF it is r
EhsanK
2016/05/11 01:54:03
I think I was getting some compile error no a bot.
|
| +#endif |
| + return observer; |
| +} |
| + |
| +} // namespace content |