1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/keyboard/keyboard_controller.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/bind.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/command_line.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/focus_client.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/layout_manager.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/test/aura_test_helper.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/window.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/base/ime/dummy_text_input_client.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/input_method.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/input_method_factory.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/text_input_client.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/ime/text_input_focus_manager.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/ui_base_switches_util.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/compositor/compositor.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/compositor/layer_type.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h"
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/test/context_factories_for_test.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/test/layer_animator_test_controller.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/gfx/geometry/rect.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/keyboard/keyboard_controller_observer.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/keyboard/keyboard_controller_proxy.h"
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/keyboard/keyboard_util.h"
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/wm/core/default_activation_client.h"
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace keyboard {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Steps a layer animation until it is completed. Animations must be enabled.
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RunAnimationForLayer(ui::Layer* layer) {
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Animations must be enabled for stepping to work.
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::LayerAnimatorTestController controller(layer->GetAnimator());
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Multiple steps are required to complete complex animations.
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(vollick): This should not be necessary. crbug.com/154017
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (controller.animator()->is_animating()) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    controller.StartThreadedAnimationsIfNeeded();
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TimeTicks step_time = controller.animator()->last_step_time();
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    controller.animator()->Step(step_time +
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                base::TimeDelta::FromMilliseconds(1000));
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// An event handler that focuses a window when it is clicked/touched on. This is
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// used to match the focus manger behaviour in ash and views.
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestFocusController : public ui::EventHandler {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit TestFocusController(aura::Window* root)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : root_(root) {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_->AddPreTargetHandler(this);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~TestFocusController() {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root_->RemovePreTargetHandler(this);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from ui::EventHandler:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura::Window* target = static_cast<aura::Window*>(event->target());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (event->type() == ui::ET_MOUSE_PRESSED ||
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        event->type() == ui::ET_TOUCH_PRESSED) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::client::GetFocusClient(target)->FocusWindow(target);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* root_;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestFocusController);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestKeyboardControllerProxy : public KeyboardControllerProxy {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestKeyboardControllerProxy()
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : input_method_(
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            ui::CreateInputMethod(NULL, gfx::kNullAcceleratedWidget)) {}
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~TestKeyboardControllerProxy() {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Destroy the window before the delegate.
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_.reset();
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from KeyboardControllerProxy:
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool HasKeyboardWindow() const OVERRIDE { return window_; }
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual aura::Window* GetKeyboardWindow() OVERRIDE {
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!window_) {
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      window_.reset(new aura::Window(&delegate_));
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      window_->set_owned_by_parent(false);
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return window_.get();
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual content::BrowserContext* GetBrowserContext() OVERRIDE { return NULL; }
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ui::InputMethod* GetInputMethod() OVERRIDE {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return input_method_.get();
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void RequestAudioInput(content::WebContents* web_contents,
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const content::MediaStreamRequest& request,
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const content::MediaResponseCallback& callback) OVERRIDE { return; }
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void LoadSystemKeyboard() OVERRIDE {};
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void ReloadKeyboardIfNeeded() OVERRIDE {};
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<aura::Window> window_;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::test::TestWindowDelegate delegate_;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ui::InputMethod> input_method_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestKeyboardControllerProxy);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Keeps a count of all the events a window receives.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class EventObserver : public ui::EventHandler {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventObserver() {}
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~EventObserver() {}
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return event_counts_[type];
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from ui::EventHandler:
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::EventHandler::OnEvent(event);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    event_counts_[event->type()]++;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::map<ui::EventType, int> event_counts_;
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventObserver);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class KeyboardContainerObserver : public aura::WindowObserver {
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  explicit KeyboardContainerObserver(aura::Window* window) : window_(window) {
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_->AddObserver(this);
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~KeyboardContainerObserver() {
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_->RemoveObserver(this);
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnWindowVisibilityChanged(aura::Window* window,
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         bool visible) OVERRIDE {
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!visible)
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::MessageLoop::current()->Quit();
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  aura::Window* window_;
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(KeyboardContainerObserver);
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class KeyboardControllerTest : public testing::Test {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  KeyboardControllerTest() {}
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~KeyboardControllerTest() {}
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The ContextFactory must exist before any Compositors are created.
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool enable_pixel_output = false;
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui::ContextFactory* context_factory =
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ui::InitializeContextFactoryForTests(enable_pixel_output);
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    aura_test_helper_->SetUp(context_factory);
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    new wm::DefaultActivationClient(aura_test_helper_->root_window());
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::SetUpInputMethodFactoryForTesting();
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (::switches::IsTextInputFocusManagerEnabled())
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL);
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    focus_controller_.reset(new TestFocusController(root_window()));
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    proxy_ = new TestKeyboardControllerProxy();
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    controller_.reset(new KeyboardController(proxy_));
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    controller_.reset();
190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    focus_controller_.reset();
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (::switches::IsTextInputFocusManagerEnabled())
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL);
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    aura_test_helper_->TearDown();
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::TerminateContextFactoryForTests();
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window() { return aura_test_helper_->root_window(); }
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  KeyboardControllerProxy* proxy() { return proxy_; }
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  KeyboardController* controller() { return controller_.get(); }
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ShowKeyboard() {
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    test_text_input_client_.reset(
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT));
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SetFocus(test_text_input_client_.get());
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetFocus(ui::TextInputClient* client) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::InputMethod* input_method = proxy()->GetInputMethod();
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (::switches::IsTextInputFocusManagerEnabled()) {
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(client);
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      input_method->OnTextInputTypeChanged(client);
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      input_method->SetFocusedTextInputClient(client);
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (client && client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) {
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      input_method->ShowImeIfNeeded();
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (proxy_->GetKeyboardWindow()->bounds().height() == 0) {
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        // Set initial bounds for test keyboard window.
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        proxy_->GetKeyboardWindow()->SetBounds(
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            KeyboardBoundsFromWindowBounds(
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                controller()->GetContainerWindow()->bounds(), 100));
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool WillHideKeyboard() {
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return controller_->WillHideKeyboard();
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool ShouldEnableInsets(aura::Window* window) {
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return controller_->ShouldEnableInsets(window);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<TestFocusController> focus_controller_;
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  KeyboardControllerProxy* proxy_;
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<KeyboardController> controller_;
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ui::TextInputClient> test_text_input_client_;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, KeyboardSize) {
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  aura::Window* container(controller()->GetContainerWindow());
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  aura::Window* keyboard(proxy()->GetKeyboardWindow());
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  container->SetBounds(gfx::Rect(0, 0, 200, 100));
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  container->AddChild(keyboard);
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const gfx::Rect& before_bounds = keyboard->bounds();
2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The initial keyboard should be positioned at the bottom of container and
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // has 0 height.
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(gfx::Rect(0, 100, 200, 0), before_bounds);
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect new_bounds(
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      before_bounds.x(), before_bounds.y() - 50,
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      before_bounds.width(), 50);
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  keyboard->SetBounds(new_bounds);
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(new_bounds, keyboard->bounds());
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Mock a screen rotation.
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  container->SetBounds(gfx::Rect(0, 0, 100, 200));
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The above call should resize keyboard to new width while keeping the old
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // height.
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(gfx::Rect(0, 150, 100, 50), keyboard->bounds());
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that tapping/clicking inside the keyboard does not give it focus.
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) {
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Rect& root_bounds = root_window()->bounds();
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::test::EventCountDelegate delegate;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<aura::Window> window(new aura::Window(&delegate));
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->SetBounds(root_bounds);
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_window()->AddChild(window.get());
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->Show();
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->Focus();
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  aura::Window* keyboard_container(controller()->GetContainerWindow());
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_container->SetBounds(root_bounds);
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  root_window()->AddChild(keyboard_container);
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_container->Show();
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ShowKeyboard();
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(window->IsVisible());
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(window->HasFocus());
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(keyboard_container->HasFocus());
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Click on the keyboard. Make sure the keyboard receives the event, but does
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // not get focus.
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventObserver observer;
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_container->AddPreTargetHandler(&observer);
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  generator.MoveMouseTo(proxy()->GetKeyboardWindow()->bounds().CenterPoint());
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  generator.ClickLeftButton();
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(window->HasFocus());
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(keyboard_container->HasFocus());
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset());
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED));
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED));
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Click outside of the keyboard. It should reach the window behind.
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  generator.MoveMouseTo(gfx::Point());
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  generator.ClickLeftButton();
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard_container->RemovePreTargetHandler(&observer);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(KeyboardControllerTest, EventHitTestingInContainer) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::Rect& root_bounds = root_window()->bounds();
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::test::EventCountDelegate delegate;
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> window(new aura::Window(&delegate));
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetBounds(root_bounds);
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_window()->AddChild(window.get());
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Show();
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Focus();
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* keyboard_container(controller()->GetContainerWindow());
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard_container->SetBounds(root_bounds);
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_window()->AddChild(keyboard_container);
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard_container->Show();
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShowKeyboard();
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(window->IsVisible());
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(window->HasFocus());
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(keyboard_container->HasFocus());
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure hit testing works correctly while the keyboard is visible.
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* keyboard_window = proxy()->GetKeyboardWindow();
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventTarget* root = root_window();
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventTargeter* targeter = root->GetEventTargeter();
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point location = keyboard_window->bounds().CenterPoint();
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent mouse1(ui::ET_MOUSE_MOVED, location, location, ui::EF_NONE,
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        ui::EF_NONE);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(keyboard_window, targeter->FindTargetForEvent(root, &mouse1));
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  location.set_y(keyboard_window->bounds().y() - 5);
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, location, location, ui::EF_NONE,
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        ui::EF_NONE);
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root, &mouse2));
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(KeyboardControllerTest, KeyboardWindowCreation) {
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const gfx::Rect& root_bounds = root_window()->bounds();
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  aura::test::EventCountDelegate delegate;
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<aura::Window> window(new aura::Window(&delegate));
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window->SetBounds(root_bounds);
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  root_window()->AddChild(window.get());
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window->Show();
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window->Focus();
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  aura::Window* keyboard_container(controller()->GetContainerWindow());
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  keyboard_container->SetBounds(root_bounds);
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  root_window()->AddChild(keyboard_container);
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  keyboard_container->Show();
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(proxy()->HasKeyboardWindow());
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventTarget* root = root_window();
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventTargeter* targeter = root->GetEventTargeter();
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Point location(root_window()->bounds().width() / 2,
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      root_window()->bounds().height() - 10);
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::MouseEvent mouse(
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ui::ET_MOUSE_MOVED, location, location, ui::EF_NONE, ui::EF_NONE);
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root, &mouse));
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(proxy()->HasKeyboardWindow());
380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(
382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      controller()->GetContainerWindow(),
383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      controller()->GetContainerWindow()->GetEventHandlerForPoint(location));
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(proxy()->HasKeyboardWindow());
385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) {
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Rect& root_bounds = root_window()->bounds();
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient input_client_1(ui::TEXT_INPUT_TYPE_TEXT);
392effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient input_client_2(ui::TEXT_INPUT_TYPE_TEXT);
393effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient no_input_client_0(ui::TEXT_INPUT_TYPE_NONE);
394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient no_input_client_1(ui::TEXT_INPUT_TYPE_NONE);
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  aura::Window* keyboard_container(controller()->GetContainerWindow());
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<KeyboardContainerObserver> keyboard_container_observer(
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new KeyboardContainerObserver(keyboard_container));
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_container->SetBounds(root_bounds);
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  root_window()->AddChild(keyboard_container);
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&input_client_0);
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&no_input_client_0);
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Keyboard should not immediately hide itself. It is delayed to avoid layout
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // flicker when the focus of input field quickly change.
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(WillHideKeyboard());
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Wait for hide keyboard to finish.
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessageLoop::current()->Run();
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(keyboard_container->IsVisible());
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&input_client_1);
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Schedule to hide keyboard.
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&no_input_client_1);
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(WillHideKeyboard());
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Cancel keyboard hide.
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&input_client_2);
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(WillHideKeyboard());
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test to prevent spurious overscroll boxes when changing tabs during keyboard
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// hide. Refer to crbug.com/401670 for more context.
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(KeyboardControllerTest, CheckOverscrollInsetDuringVisibilityChange) {
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const gfx::Rect& root_bounds = root_window()->bounds();
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE);
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  aura::Window* keyboard_container(controller()->GetContainerWindow());
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  keyboard_container->SetBounds(root_bounds);
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  root_window()->AddChild(keyboard_container);
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enable touch keyboard / overscroll mode to test insets.
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  keyboard::SetTouchKeyboardEnabled(true);
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(keyboard::IsKeyboardOverscrollEnabled());
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetFocus(&input_client);
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetFocus(&no_input_client);
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Insets should not be enabled for new windows while keyboard is in the
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // process of hiding when overscroll is enabled.
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(ShouldEnableInsets(proxy()->GetKeyboardWindow()));
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Cancel keyboard hide.
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetFocus(&input_client);
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Insets should be enabled for new windows as hide was cancelled.
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(ShouldEnableInsets(proxy()->GetKeyboardWindow()));
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(KeyboardControllerTest, AlwaysVisibleWhenLocked) {
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::Rect& root_bounds = root_window()->bounds();
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
458effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient input_client_1(ui::TEXT_INPUT_TYPE_TEXT);
460effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient no_input_client_0(ui::TEXT_INPUT_TYPE_NONE);
461effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ui::DummyTextInputClient no_input_client_1(ui::TEXT_INPUT_TYPE_NONE);
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* keyboard_container(controller()->GetContainerWindow());
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<KeyboardContainerObserver> keyboard_container_observer(
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new KeyboardContainerObserver(keyboard_container));
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  keyboard_container->SetBounds(root_bounds);
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_window()->AddChild(keyboard_container);
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&input_client_0);
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Lock keyboard.
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller()->set_lock_keyboard(true);
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&no_input_client_0);
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Keyboard should not try to hide itself as it is locked.
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
47958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(WillHideKeyboard());
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&input_client_1);
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(keyboard_container->IsVisible());
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Unlock keyboard.
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller()->set_lock_keyboard(false);
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Keyboard should hide when focus on no input client.
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocus(&no_input_client_1);
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(WillHideKeyboard());
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait for hide keyboard to finish.
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->Run();
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(keyboard_container->IsVisible());
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class KeyboardControllerAnimationTest : public KeyboardControllerTest,
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        public KeyboardControllerObserver {
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  KeyboardControllerAnimationTest() {}
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~KeyboardControllerAnimationTest() {}
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // We cannot short-circuit animations for this test.
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ui::ScopedAnimationDurationScaleMode test_duration_mode(
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    KeyboardControllerTest::SetUp();
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& root_bounds = root_window()->bounds();
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    keyboard_container()->SetBounds(root_bounds);
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_window()->AddChild(keyboard_container());
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    controller()->AddObserver(this);
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    controller()->RemoveObserver(this);
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    KeyboardControllerTest::TearDown();
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // KeyboardControllerObserver overrides
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) OVERRIDE {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    notified_bounds_ = new_bounds;
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::Rect& notified_bounds() { return notified_bounds_; }
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* keyboard_container() {
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return controller()->GetContainerWindow();
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* keyboard_window() {
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return proxy()->GetKeyboardWindow();
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect notified_bounds_;
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(KeyboardControllerAnimationTest);
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests virtual keyboard has correct show and hide animation.
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) {
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::Layer* layer = keyboard_container()->layer();
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShowKeyboard();
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Keyboard container and window should immediately become visible before
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // animation starts.
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container()->IsVisible());
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_window()->IsVisible());
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float show_start_opacity = layer->opacity();
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Transform transform;
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  transform.Translate(0, kAnimationDistance);
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(transform, layer->transform());
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(), notified_bounds());
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunAnimationForLayer(layer);
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container()->IsVisible());
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_window()->IsVisible());
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float show_end_opacity = layer->opacity();
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(show_start_opacity, show_end_opacity);
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(gfx::Transform(), layer->transform());
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // KeyboardController should notify the bounds of keyboard window to its
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // observers after show animation finished.
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(keyboard_window()->bounds(), notified_bounds());
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Directly hide keyboard without delay.
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller()->HideKeyboard(KeyboardController::HIDE_REASON_AUTOMATIC);
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container()->IsVisible());
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container()->layer()->visible());
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_window()->IsVisible());
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float hide_start_opacity = layer->opacity();
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // KeyboardController should notify the bounds of keyboard window to its
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // observers before hide animation starts.
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(), notified_bounds());
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunAnimationForLayer(layer);
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(keyboard_container()->IsVisible());
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(keyboard_container()->layer()->visible());
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(keyboard_window()->IsVisible());
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float hide_end_opacity = layer->opacity();
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(hide_start_opacity, hide_end_opacity);
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(transform, layer->transform());
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(), notified_bounds());
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Show keyboard during keyboard hide animation should abort the hide animation
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and the keyboard should animate in.
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test for crbug.com/333284.
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(KeyboardControllerAnimationTest, ContainerShowWhileHide) {
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::Layer* layer = keyboard_container()->layer();
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShowKeyboard();
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunAnimationForLayer(layer);
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller()->HideKeyboard(KeyboardController::HIDE_REASON_AUTOMATIC);
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Before hide animation finishes, show keyboard again.
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShowKeyboard();
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunAnimationForLayer(layer);
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_container()->IsVisible());
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(keyboard_window()->IsVisible());
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1.0, layer->opacity());
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(gfx::Transform(), layer->transform());
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace keyboard
606