Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / keyboard / keyboard_controller_unittest.cc
index 98e0895..af3b8d3 100644 (file)
 #include "ui/base/ime/input_method_factory.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/compositor/layer_type.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/compositor/test/layer_animator_test_controller.h"
 #include "ui/gfx/rect.h"
 #include "ui/keyboard/keyboard_controller.h"
+#include "ui/keyboard/keyboard_controller_observer.h"
 #include "ui/keyboard/keyboard_controller_proxy.h"
 #include "ui/keyboard/keyboard_switches.h"
 
 namespace keyboard {
 namespace {
 
+// Steps a layer animation until it is completed. Animations must be enabled.
+void RunAnimationForLayer(ui::Layer* layer) {
+  // Animations must be enabled for stepping to work.
+  ASSERT_NE(ui::ScopedAnimationDurationScaleMode::duration_scale_mode(),
+            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
+
+  ui::LayerAnimatorTestController controller(layer->GetAnimator());
+  gfx::AnimationContainerElement* element = layer->GetAnimator();
+  // Multiple steps are required to complete complex animations.
+  // TODO(vollick): This should not be necessary. crbug.com/154017
+  while (controller.animator()->is_animating()) {
+    controller.StartThreadedAnimationsIfNeeded();
+    base::TimeTicks step_time = controller.animator()->last_step_time();
+    element->Step(step_time + base::TimeDelta::FromMilliseconds(1000));
+  }
+}
+
 // An event handler that focuses a window when it is clicked/touched on. This is
 // used to match the focus manger behaviour in ash and views.
 class TestFocusController : public ui::EventHandler {
@@ -69,6 +89,7 @@ class TestKeyboardControllerProxy : public KeyboardControllerProxy {
   }
 
   // Overridden from KeyboardControllerProxy:
+  virtual bool HasKeyboardWindow() const OVERRIDE { return true; }
   virtual aura::Window* GetKeyboardWindow() OVERRIDE { return window_.get(); }
   virtual content::BrowserContext* GetBrowserContext() OVERRIDE { return NULL; }
   virtual ui::InputMethod* GetInputMethod() OVERRIDE {
@@ -453,6 +474,115 @@ TEST_F(KeyboardControllerTest, KeyboardResizingFromContents) {
   EXPECT_EQ(180, keyboard_window->bounds().height());
 }
 
+class KeyboardControllerAnimationTest : public KeyboardControllerTest,
+                                        public KeyboardControllerObserver {
+ public:
+  KeyboardControllerAnimationTest() {}
+  virtual ~KeyboardControllerAnimationTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    // We cannot short-circuit animations for this test.
+    ui::ScopedAnimationDurationScaleMode normal_duration_mode(
+        ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
+
+    KeyboardControllerTest::SetUp();
+
+    const gfx::Rect& root_bounds = root_window()->bounds();
+    keyboard_container()->SetBounds(root_bounds);
+    root_window()->AddChild(keyboard_container());
+    controller()->AddObserver(this);
+  }
+
+  virtual void TearDown() OVERRIDE {
+    controller()->RemoveObserver(this);
+    KeyboardControllerTest::TearDown();
+  }
+
+ protected:
+  // KeyboardControllerObserver overrides
+  virtual void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) OVERRIDE {
+    notified_bounds_ = new_bounds;
+  }
+
+  const gfx::Rect& notified_bounds() { return notified_bounds_; }
+
+  aura::Window* keyboard_container() {
+    return controller()->GetContainerWindow();
+  }
+
+  aura::Window* keyboard_window() {
+    return proxy()->GetKeyboardWindow();
+  }
+
+ private:
+  gfx::Rect notified_bounds_;
+
+  DISALLOW_COPY_AND_ASSIGN(KeyboardControllerAnimationTest);
+};
+
+// Tests virtual keyboard has correct show and hide animation.
+TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) {
+  ui::Layer* layer = keyboard_container()->layer();
+  ShowKeyboard();
+
+  // Keyboard container and window should immediately become visible before
+  // animation starts.
+  EXPECT_TRUE(keyboard_container()->IsVisible());
+  EXPECT_TRUE(keyboard_window()->IsVisible());
+  float show_start_opacity = layer->opacity();
+  gfx::Transform transform;
+  transform.Translate(0, keyboard_window()->bounds().height());
+  EXPECT_EQ(transform, layer->transform());
+  EXPECT_EQ(gfx::Rect(), notified_bounds());
+
+  RunAnimationForLayer(layer);
+  EXPECT_TRUE(keyboard_container()->IsVisible());
+  EXPECT_TRUE(keyboard_window()->IsVisible());
+  float show_end_opacity = layer->opacity();
+  EXPECT_LT(show_start_opacity, show_end_opacity);
+  EXPECT_EQ(gfx::Transform(), layer->transform());
+  // KeyboardController should notify the bounds of keyboard window to its
+  // observers after show animation finished.
+  EXPECT_EQ(keyboard_window()->bounds(), notified_bounds());
+
+  // Directly hide keyboard without delay.
+  controller()->HideKeyboard(KeyboardController::HIDE_REASON_AUTOMATIC);
+  EXPECT_TRUE(keyboard_container()->IsVisible());
+  EXPECT_TRUE(keyboard_container()->layer()->visible());
+  EXPECT_TRUE(keyboard_window()->IsVisible());
+  float hide_start_opacity = layer->opacity();
+  // KeyboardController should notify the bounds of keyboard window to its
+  // observers before hide animation starts.
+  EXPECT_EQ(gfx::Rect(), notified_bounds());
+
+  RunAnimationForLayer(layer);
+  EXPECT_FALSE(keyboard_container()->IsVisible());
+  EXPECT_FALSE(keyboard_container()->layer()->visible());
+  EXPECT_FALSE(keyboard_window()->IsVisible());
+  float hide_end_opacity = layer->opacity();
+  EXPECT_GT(hide_start_opacity, hide_end_opacity);
+  EXPECT_EQ(transform, layer->transform());
+  EXPECT_EQ(gfx::Rect(), notified_bounds());
+}
+
+// Show keyboard during keyboard hide animation should abort the hide animation
+// and the keyboard should animate in.
+// Test for crbug.com/333284.
+TEST_F(KeyboardControllerAnimationTest, ContainerShowWhileHide) {
+  ui::Layer* layer = keyboard_container()->layer();
+  ShowKeyboard();
+  RunAnimationForLayer(layer);
+
+  controller()->HideKeyboard(KeyboardController::HIDE_REASON_AUTOMATIC);
+  // Before hide animation finishes, show keyboard again.
+  ShowKeyboard();
+  RunAnimationForLayer(layer);
+  EXPECT_TRUE(keyboard_container()->IsVisible());
+  EXPECT_TRUE(keyboard_window()->IsVisible());
+  EXPECT_EQ(1.0, layer->opacity());
+  EXPECT_EQ(gfx::Transform(), layer->transform());
+}
+
 class KeyboardControllerUsabilityTest : public KeyboardControllerTest {
  public:
   KeyboardControllerUsabilityTest() {}