1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/ash/ash_keyboard_controller_proxy.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ui/aura/test/test_window_delegate.h"
10 #include "ui/aura/window.h"
11 #include "ui/base/ime/input_method.h"
12 #include "ui/base/ime/input_method_factory.h"
13 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
14 #include "ui/compositor/test/layer_animator_test_controller.h"
15 #include "ui/keyboard/keyboard_controller.h"
19 // Steps a layer animation until it is completed. Animations must be enabled.
20 void RunAnimationForLayer(ui::Layer
* layer
) {
21 // Animations must be enabled for stepping to work.
22 ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
23 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION
);
25 ui::LayerAnimatorTestController
controller(layer
->GetAnimator());
26 gfx::AnimationContainerElement
* element
= layer
->GetAnimator();
27 // Multiple steps are required to complete complex animations.
28 // TODO(vollick): This should not be necessary. crbug.com/154017
29 while (controller
.animator()->is_animating()) {
30 controller
.StartThreadedAnimationsIfNeeded();
31 base::TimeTicks step_time
= controller
.animator()->last_step_time();
32 element
->Step(step_time
+ base::TimeDelta::FromMilliseconds(1000));
38 class TestAshKeyboardControllerProxy
: public AshKeyboardControllerProxy
{
40 TestAshKeyboardControllerProxy()
41 : window_(new aura::Window(&delegate_
)),
42 input_method_(ui::CreateInputMethod(NULL
,
43 gfx::kNullAcceleratedWidget
)) {
44 window_
->Init(aura::WINDOW_LAYER_NOT_DRAWN
);
45 window_
->set_owned_by_parent(false);
48 virtual ~TestAshKeyboardControllerProxy() {
52 // Overridden from AshKeyboardControllerProxy:
53 virtual aura::Window
* GetKeyboardWindow() OVERRIDE
{ return window_
.get(); }
54 virtual content::BrowserContext
* GetBrowserContext() OVERRIDE
{ return NULL
; }
55 virtual ui::InputMethod
* GetInputMethod() OVERRIDE
{
56 return input_method_
.get();
58 virtual void RequestAudioInput(content::WebContents
* web_contents
,
59 const content::MediaStreamRequest
& request
,
60 const content::MediaResponseCallback
& callback
) OVERRIDE
{}
63 scoped_ptr
<aura::Window
> window_
;
64 aura::test::TestWindowDelegate delegate_
;
65 scoped_ptr
<ui::InputMethod
> input_method_
;
67 DISALLOW_COPY_AND_ASSIGN(TestAshKeyboardControllerProxy
);
70 // TODO(bshe): Move this test back to unit test if
71 // ui::SetUpInputMethodFactoryForTesting() is safe to be called in unit test.
72 class AshKeyboardControllerProxyTest
: public ash::test::AshTestBase
{
74 AshKeyboardControllerProxyTest() {}
76 virtual ~AshKeyboardControllerProxyTest() {}
79 virtual void SetUp() OVERRIDE
;
80 virtual void TearDown() OVERRIDE
;
82 TestAshKeyboardControllerProxy
* proxy() { return proxy_
; }
83 keyboard::KeyboardController
* controller() { return controller_
.get(); }
86 void ShowKeyboard(aura::Window
* container
);
87 void HideKeyboard(aura::Window
* container
);
89 TestAshKeyboardControllerProxy
* proxy_
;
90 scoped_ptr
<keyboard::KeyboardController
> controller_
;
93 DISALLOW_COPY_AND_ASSIGN(AshKeyboardControllerProxyTest
);
96 void AshKeyboardControllerProxyTest::SetUp() {
97 ui::SetUpInputMethodFactoryForTesting();
99 proxy_
= new TestAshKeyboardControllerProxy();
100 controller_
.reset(new keyboard::KeyboardController(proxy_
));
102 aura::Window
* keyboard_container(controller_
->GetContainerWindow());
103 keyboard_container
->SetBounds(ash::Shell::GetPrimaryRootWindow()->bounds());
104 ash::Shell::GetPrimaryRootWindow()->AddChild(keyboard_container
);
105 keyboard_container
->AddChild(proxy_
->GetKeyboardWindow());
106 ASSERT_NE(proxy_
->GetKeyboardWindow()->bounds().height(), 0);
109 void AshKeyboardControllerProxyTest::TearDown() {
110 AshTestBase::TearDown();
113 void AshKeyboardControllerProxyTest::ShowKeyboard(aura::Window
* container
) {
114 proxy_
->ShowKeyboardContainer(container
);
117 void AshKeyboardControllerProxyTest::HideKeyboard(aura::Window
* container
) {
118 proxy_
->HideKeyboardContainer(container
);
121 TEST_F(AshKeyboardControllerProxyTest
, VirtualKeyboardContainerAnimation
) {
122 // We cannot short-circuit animations for this test.
123 ui::ScopedAnimationDurationScaleMode
normal_duration_mode(
124 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION
);
126 aura::Window
* keyboard_container(controller()->GetContainerWindow());
127 ui::Layer
* layer
= keyboard_container
->layer();
129 EXPECT_FALSE(keyboard_container
->IsVisible());
130 ShowKeyboard(keyboard_container
);
132 // Keyboard container and window should immediately become visible before
134 EXPECT_TRUE(keyboard_container
->IsVisible());
135 EXPECT_TRUE(proxy()->GetKeyboardWindow()->IsVisible());
136 float show_start_opacity
= layer
->opacity();
137 gfx::Transform transform
;
138 transform
.Translate(0, proxy()->GetKeyboardWindow()->bounds().height());
139 EXPECT_EQ(transform
, layer
->transform());
141 RunAnimationForLayer(layer
);
142 EXPECT_TRUE(keyboard_container
->IsVisible());
143 EXPECT_TRUE(proxy()->GetKeyboardWindow()->IsVisible());
144 float show_end_opacity
= layer
->opacity();
145 EXPECT_LT(show_start_opacity
, show_end_opacity
);
146 EXPECT_EQ(gfx::Transform(), layer
->transform());
148 HideKeyboard(keyboard_container
);
149 EXPECT_TRUE(keyboard_container
->IsVisible());
150 EXPECT_TRUE(keyboard_container
->layer()->visible());
151 EXPECT_TRUE(proxy()->GetKeyboardWindow()->IsVisible());
152 float hide_start_opacity
= layer
->opacity();
154 RunAnimationForLayer(layer
);
155 EXPECT_FALSE(keyboard_container
->IsVisible());
156 EXPECT_FALSE(keyboard_container
->layer()->visible());
157 EXPECT_FALSE(proxy()->GetKeyboardWindow()->IsVisible());
158 float hide_end_opacity
= layer
->opacity();
159 EXPECT_GT(hide_start_opacity
, hide_end_opacity
);
160 EXPECT_EQ(transform
, layer
->transform());
163 // Test for crbug.com/333284.
164 TEST_F(AshKeyboardControllerProxyTest
, VirtualKeyboardContainerShowWhileHide
) {
165 // We cannot short-circuit animations for this test.
166 ui::ScopedAnimationDurationScaleMode
normal_duration_mode(
167 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION
);
169 aura::Window
* keyboard_container(controller()->GetContainerWindow());
170 ui::Layer
* layer
= keyboard_container
->layer();
172 EXPECT_FALSE(keyboard_container
->IsVisible());
173 ShowKeyboard(keyboard_container
);
174 RunAnimationForLayer(layer
);
176 HideKeyboard(keyboard_container
);
177 // Before hide animation finishes, show keyboard again.
178 ShowKeyboard(keyboard_container
);
180 RunAnimationForLayer(layer
);
181 EXPECT_TRUE(keyboard_container
->IsVisible());
182 EXPECT_TRUE(proxy()->GetKeyboardWindow()->IsVisible());
183 EXPECT_EQ(1.0, layer
->opacity());
184 EXPECT_EQ(gfx::Transform(), layer
->transform());