window_animations_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. // Copyright (c) 2012 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.
  4. #include "ash/wm/window_animations.h"
  5. #include "ash/public/cpp/keyboard/keyboard_switches.h"
  6. #include "ash/public/cpp/shelf_config.h"
  7. #include "ash/public/cpp/shell_window_ids.h"
  8. #include "ash/public/cpp/window_animation_types.h"
  9. #include "ash/shell.h"
  10. #include "ash/test/ash_test_base.h"
  11. #include "ash/wm/window_state.h"
  12. #include "ash/wm/wm_event.h"
  13. #include "ash/wm/workspace_controller.h"
  14. #include "base/command_line.h"
  15. #include "base/time/time.h"
  16. #include "ui/aura/test/test_windows.h"
  17. #include "ui/aura/window.h"
  18. #include "ui/compositor/layer.h"
  19. #include "ui/compositor/layer_animation_observer.h"
  20. #include "ui/compositor/layer_animator.h"
  21. #include "ui/compositor/layer_tree_owner.h"
  22. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  23. #include "ui/compositor/scoped_layer_animation_settings.h"
  24. #include "ui/wm/core/window_util.h"
  25. using aura::Window;
  26. using ui::Layer;
  27. namespace ash {
  28. namespace {
  29. void WaitForMilliseconds(int ms) {
  30. base::RunLoop loop;
  31. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  32. FROM_HERE, loop.QuitClosure(), base::Milliseconds(ms));
  33. loop.Run();
  34. }
  35. } // namespace
  36. class WindowAnimationsTest : public AshTestBase {
  37. public:
  38. WindowAnimationsTest() = default;
  39. WindowAnimationsTest(const WindowAnimationsTest&) = delete;
  40. WindowAnimationsTest& operator=(const WindowAnimationsTest&) = delete;
  41. void SetUp() override {
  42. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  43. keyboard::switches::kEnableVirtualKeyboard);
  44. AshTestBase::SetUp();
  45. }
  46. };
  47. // Listens to animation scheduled notifications. Remembers the transition
  48. // duration of the first sequence.
  49. class MinimizeAnimationObserver : public ui::LayerAnimationObserver {
  50. public:
  51. explicit MinimizeAnimationObserver(ui::LayerAnimator* animator)
  52. : animator_(animator) {
  53. animator_->AddObserver(this);
  54. // RemoveObserver is called when the first animation is scheduled and so
  55. // there should be no need for now to remove it in destructor.
  56. }
  57. MinimizeAnimationObserver(const MinimizeAnimationObserver&) = delete;
  58. MinimizeAnimationObserver& operator=(const MinimizeAnimationObserver&) =
  59. delete;
  60. base::TimeDelta duration() { return duration_; }
  61. protected:
  62. // ui::LayerAnimationObserver:
  63. void OnLayerAnimationScheduled(
  64. ui::LayerAnimationSequence* sequence) override {
  65. duration_ = animator_->GetTransitionDuration();
  66. animator_->RemoveObserver(this);
  67. }
  68. void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {}
  69. void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {}
  70. private:
  71. ui::LayerAnimator* animator_;
  72. base::TimeDelta duration_;
  73. };
  74. // This is the class that simulates the behavior of
  75. // `FrameHeader::FrameAnimatorView` which may recreate the window layer in the
  76. // middle of setting the animation of the old and new layer.
  77. class FrameAnimator : public ui::ImplicitAnimationObserver {
  78. public:
  79. explicit FrameAnimator(aura::Window* window) : window_(window) {
  80. // Set up an animation which will be stopped before the old layer animation.
  81. SetOpacityAnimation(window_->layer());
  82. }
  83. FrameAnimator(const FrameAnimator&) = delete;
  84. FrameAnimator& operator=(const FrameAnimator&) = delete;
  85. ~FrameAnimator() override = default;
  86. // ui::ImplicitAnimationObserver:
  87. void OnImplicitAnimationsCompleted() override {
  88. // Once the initial animation is stopped by the old layer, start a new
  89. // opacity animation and recreate the window layer at the same time. The
  90. // opacity animation will be stopped when the layer set opacity and the
  91. // layer is destroyed.
  92. if (!animation_started_)
  93. StartAnimation();
  94. else
  95. layer_owner_.reset();
  96. }
  97. private:
  98. // Set an opacity animation which should last longer than the cross fade
  99. // animation.
  100. void SetOpacityAnimation(ui::Layer* layer) {
  101. layer->SetOpacity(1.f);
  102. ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  103. settings.AddObserver(this);
  104. settings.SetTransitionDuration(base::Milliseconds(1000));
  105. layer->SetOpacity(0.f);
  106. }
  107. // Recreate the window layer and start a new opacity animation.
  108. void StartAnimation() {
  109. layer_owner_ =
  110. std::make_unique<ui::LayerTreeOwner>(window_->RecreateLayer());
  111. SetOpacityAnimation(layer_owner_->root());
  112. animation_started_ = true;
  113. }
  114. aura::Window* window_;
  115. std::unique_ptr<ui::LayerTreeOwner> layer_owner_;
  116. bool animation_started_ = false;
  117. };
  118. TEST_F(WindowAnimationsTest, HideShowBrightnessGrayscaleAnimation) {
  119. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  120. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  121. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  122. window->Show();
  123. EXPECT_TRUE(window->layer()->visible());
  124. // Hiding.
  125. wm::SetWindowVisibilityAnimationType(
  126. window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
  127. AnimateOnChildWindowVisibilityChanged(window.get(), false);
  128. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  129. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  130. EXPECT_FALSE(window->layer()->visible());
  131. // Showing.
  132. wm::SetWindowVisibilityAnimationType(
  133. window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
  134. AnimateOnChildWindowVisibilityChanged(window.get(), true);
  135. EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
  136. EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
  137. EXPECT_TRUE(window->layer()->visible());
  138. // Stays shown.
  139. window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
  140. base::Seconds(5));
  141. EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
  142. EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
  143. EXPECT_TRUE(window->layer()->visible());
  144. }
  145. TEST_F(WindowAnimationsTest, LayerTargetVisibility) {
  146. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  147. // Layer target visibility changes according to Show/Hide.
  148. window->Show();
  149. EXPECT_TRUE(window->layer()->GetTargetVisibility());
  150. window->Hide();
  151. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  152. window->Show();
  153. EXPECT_TRUE(window->layer()->GetTargetVisibility());
  154. }
  155. TEST_F(WindowAnimationsTest, CrossFadeToBounds) {
  156. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  157. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  158. std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
  159. window->SetBounds(gfx::Rect(5, 10, 320, 240));
  160. window->Show();
  161. Layer* old_layer = window->layer();
  162. EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
  163. // Cross fade to a larger size, as in a maximize animation.
  164. WindowState::Get(window.get())
  165. ->SetBoundsDirectCrossFade(gfx::Rect(0, 0, 640, 480));
  166. // Window's layer has been replaced.
  167. EXPECT_NE(old_layer, window->layer());
  168. // Original layer stays opaque and stretches to new size.
  169. EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
  170. EXPECT_EQ("5,10 320x240", old_layer->bounds().ToString());
  171. gfx::Transform grow_transform;
  172. grow_transform.Translate(-5.f, -10.f);
  173. grow_transform.Scale(640.f / 320.f, 480.f / 240.f);
  174. EXPECT_EQ(grow_transform, old_layer->GetTargetTransform());
  175. // New layer animates in to the identity transform.
  176. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  177. EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
  178. // Run the animations to completion.
  179. old_layer->GetAnimator()->Step(base::TimeTicks::Now() + base::Seconds(1));
  180. window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
  181. base::Seconds(1));
  182. // Cross fade to a smaller size, as in a restore animation.
  183. old_layer = window->layer();
  184. WindowState::Get(window.get())
  185. ->SetBoundsDirectCrossFade(gfx::Rect(5, 10, 320, 240));
  186. // Again, window layer has been replaced.
  187. EXPECT_NE(old_layer, window->layer());
  188. // Original layer fades out and stretches down to new size.
  189. EXPECT_EQ(0.0f, old_layer->GetTargetOpacity());
  190. EXPECT_EQ("0,0 640x480", old_layer->bounds().ToString());
  191. gfx::Transform shrink_transform;
  192. shrink_transform.Translate(5.f, 10.f);
  193. shrink_transform.Scale(320.f / 640.f, 240.f / 480.f);
  194. EXPECT_EQ(shrink_transform, old_layer->GetTargetTransform());
  195. // New layer animates in to the identity transform.
  196. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  197. EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
  198. old_layer->GetAnimator()->Step(base::TimeTicks::Now() + base::Seconds(1));
  199. window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
  200. base::Seconds(1));
  201. }
  202. // Tests that when crossfading from a window which has a transform, the cross
  203. // fading animation should be ignored and the window should set to its desired
  204. // bounds directly.
  205. TEST_F(WindowAnimationsTest, CrossFadeToBoundsFromTransform) {
  206. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  207. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  208. std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
  209. window->SetBounds(gfx::Rect(10, 10, 320, 240));
  210. gfx::Transform half_size;
  211. half_size.Translate(10, 10);
  212. half_size.Scale(0.5f, 0.5f);
  213. window->SetTransform(half_size);
  214. window->Show();
  215. Layer* old_layer = window->layer();
  216. EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
  217. // Cross fade to a larger size, as in a maximize animation.
  218. WindowState::Get(window.get())
  219. ->SetBoundsDirectCrossFade(gfx::Rect(0, 0, 640, 480));
  220. // Window's layer has not been replaced.
  221. EXPECT_EQ(old_layer, window->layer());
  222. // Original layer stays opaque and set to new size directly.
  223. EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
  224. EXPECT_EQ("0,0 640x480", old_layer->bounds().ToString());
  225. // Window still has its old transform before crossfading animation.
  226. EXPECT_EQ(half_size, old_layer->transform());
  227. }
  228. // Tests that if we recreate the window layers during a cross fade animation,
  229. // there is no crash.
  230. // Regression test for https://crbug.com/1088169.
  231. TEST_F(WindowAnimationsTest, CrossFadeThenRecreate) {
  232. auto window = CreateTestWindow(gfx::Rect(100, 100));
  233. // Use a bit more time than NON_ZERO_DURATION as its possible with non zero we
  234. // finish the animation instantly.
  235. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  236. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  237. WindowState* window_state = WindowState::Get(window.get());
  238. window_state->Maximize();
  239. ASSERT_TRUE(window->layer()->GetAnimator()->is_animating());
  240. // Recreate the layers and then delete |window|. There should be no crash when
  241. // stopping the old layers animation.
  242. std::unique_ptr<ui::LayerTreeOwner> tree = wm::RecreateLayers(window.get());
  243. window.reset();
  244. tree->root()->GetAnimator()->StopAnimating();
  245. }
  246. // Tests that if the window layer is recreated after setting the old layer's
  247. // animation (e.g., by `FrameHeader::FrameAnimatorView::StartAnimation`). There
  248. // should be no crash. Regression test for https://crbug.com/1313977.
  249. TEST_F(WindowAnimationsTest, RecreateWhenSettingCrossFade) {
  250. auto window = CreateTestWindow(gfx::Rect(100, 100));
  251. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  252. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  253. auto frame_animator = std::make_unique<FrameAnimator>(window.get());
  254. WindowState::Get(window.get())->Maximize();
  255. }
  256. TEST_F(WindowAnimationsTest, LockAnimationDuration) {
  257. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  258. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  259. std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
  260. Layer* layer = window->layer();
  261. window->SetBounds(gfx::Rect(5, 10, 320, 240));
  262. window->Show();
  263. // Test that it is possible to override transition duration when it is not
  264. // locked.
  265. {
  266. ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
  267. settings1.SetTransitionDuration(base::Milliseconds(1000));
  268. {
  269. ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
  270. // Duration is not locked so it gets overridden.
  271. settings2.SetTransitionDuration(base::Milliseconds(50));
  272. WindowState::Get(window.get())->Minimize();
  273. EXPECT_TRUE(layer->GetAnimator()->is_animating());
  274. // Expect duration from the inner scope
  275. EXPECT_EQ(50,
  276. layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
  277. }
  278. window->Show();
  279. layer->GetAnimator()->StopAnimating();
  280. }
  281. // Test that it is possible to lock transition duration
  282. {
  283. // Update layer as minimizing will replace the window's layer.
  284. layer = window->layer();
  285. ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
  286. settings1.SetTransitionDuration(base::Milliseconds(1000));
  287. // Duration is locked in outer scope.
  288. settings1.LockTransitionDuration();
  289. {
  290. ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
  291. // Transition duration setting is ignored.
  292. settings2.SetTransitionDuration(base::Milliseconds(50));
  293. WindowState::Get(window.get())->Minimize();
  294. EXPECT_TRUE(layer->GetAnimator()->is_animating());
  295. // Expect duration from the outer scope
  296. EXPECT_EQ(1000,
  297. layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
  298. }
  299. window->Show();
  300. layer->GetAnimator()->StopAnimating();
  301. }
  302. // Test that duration respects default.
  303. {
  304. layer = window->layer();
  305. // Query default duration.
  306. MinimizeAnimationObserver observer(layer->GetAnimator());
  307. WindowState::Get(window.get())->Minimize();
  308. EXPECT_TRUE(layer->GetAnimator()->is_animating());
  309. base::TimeDelta default_duration(observer.duration());
  310. window->Show();
  311. layer->GetAnimator()->StopAnimating();
  312. layer = window->layer();
  313. ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
  314. settings.LockTransitionDuration();
  315. // Setting transition duration is ignored since duration is locked
  316. settings.SetTransitionDuration(base::Milliseconds(1000));
  317. WindowState::Get(window.get())->Minimize();
  318. EXPECT_TRUE(layer->GetAnimator()->is_animating());
  319. // Expect default duration (200ms for stock ash minimizing animation).
  320. EXPECT_EQ(default_duration.InMilliseconds(),
  321. layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
  322. window->Show();
  323. layer->GetAnimator()->StopAnimating();
  324. }
  325. }
  326. // Test that a slide out animation slides the window off the screen while
  327. // modifying the opacity.
  328. TEST_F(WindowAnimationsTest, SlideOutAnimation) {
  329. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  330. ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  331. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  332. window->SetBounds(gfx::Rect(0, 0, 100, 100));
  333. window->Show();
  334. EXPECT_TRUE(window->layer()->visible());
  335. ::wm::SetWindowVisibilityAnimationType(
  336. window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_FADE_IN_SLIDE_OUT);
  337. AnimateOnChildWindowVisibilityChanged(window.get(), false);
  338. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  339. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  340. EXPECT_FALSE(window->layer()->visible());
  341. EXPECT_EQ(gfx::Rect(-150, 0, 100, 100), window->layer()->GetTargetBounds());
  342. }
  343. // Test that a fade in slide out animation fades in.
  344. TEST_F(WindowAnimationsTest, FadeInAnimation) {
  345. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  346. ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  347. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  348. window->SetBounds(gfx::Rect(0, 0, 100, 100));
  349. window->Hide();
  350. EXPECT_FALSE(window->layer()->visible());
  351. ::wm::SetWindowVisibilityAnimationType(
  352. window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_FADE_IN_SLIDE_OUT);
  353. AnimateOnChildWindowVisibilityChanged(window.get(), true);
  354. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  355. EXPECT_TRUE(window->layer()->GetTargetVisibility());
  356. EXPECT_TRUE(window->layer()->visible());
  357. EXPECT_EQ(gfx::Rect(0, 0, 100, 100), window->layer()->GetTargetBounds());
  358. }
  359. TEST_F(WindowAnimationsTest, SlideOutAnimationPlaysTwiceForPipWindow) {
  360. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  361. ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  362. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  363. window->SetBounds(gfx::Rect(8, 8, 100, 100));
  364. WindowState* window_state = WindowState::Get(window.get());
  365. const WMEvent enter_pip(WM_EVENT_PIP);
  366. window_state->OnWMEvent(&enter_pip);
  367. EXPECT_TRUE(window_state->IsPip());
  368. window->Show();
  369. EXPECT_TRUE(window->layer()->visible());
  370. EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
  371. window->Hide();
  372. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  373. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  374. EXPECT_FALSE(window->layer()->visible());
  375. EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
  376. // Reset the position and try again.
  377. window->Show();
  378. window->SetBounds(gfx::Rect(8, 8, 100, 100));
  379. EXPECT_TRUE(window->layer()->visible());
  380. EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
  381. window->Hide();
  382. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  383. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  384. EXPECT_FALSE(window->layer()->visible());
  385. EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
  386. }
  387. TEST_F(WindowAnimationsTest, ResetAnimationAfterDismissingArcPip) {
  388. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  389. ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  390. std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  391. window->SetBounds(gfx::Rect(8, 8, 100, 100));
  392. WindowState* window_state = WindowState::Get(window.get());
  393. const WMEvent enter_pip(WM_EVENT_PIP);
  394. window_state->OnWMEvent(&enter_pip);
  395. EXPECT_TRUE(window_state->IsPip());
  396. window->Show();
  397. EXPECT_TRUE(window->layer()->visible());
  398. EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
  399. // Ensure the window is slided out.
  400. WindowState::Get(window.get())->Minimize();
  401. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  402. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  403. EXPECT_FALSE(window->layer()->visible());
  404. EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
  405. WindowState::Get(window.get())->Maximize();
  406. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  407. EXPECT_TRUE(window->layer()->visible());
  408. EXPECT_EQ(gfx::Rect(0, 0, 800, 600 - ShelfConfig::Get()->shelf_size()),
  409. window->layer()->GetTargetBounds());
  410. // Ensure the window is not slided out.
  411. window->Hide();
  412. EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
  413. EXPECT_FALSE(window->layer()->GetTargetVisibility());
  414. EXPECT_FALSE(window->layer()->visible());
  415. EXPECT_EQ(gfx::Rect(0, 0, 800, 600 - ShelfConfig::Get()->shelf_size()),
  416. window->layer()->GetTargetBounds());
  417. }
  418. // Tests a version of the cross fade animation which animates the transform and
  419. // opacity of the new layer, but only the opacity of the old layer. The old
  420. // layer transform is updated manually when the animation ticks so that it
  421. // has the same visible bounds as the new layer.
  422. // Flaky on Chrome OS. https://crbug.com/1113901
  423. TEST_F(WindowAnimationsTest, DISABLED_CrossFadeAnimateNewLayerOnly) {
  424. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  425. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  426. std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
  427. window->SetBounds(gfx::Rect(10, 10, 200, 200));
  428. window->Show();
  429. window->layer()->GetAnimator()->StopAnimating();
  430. Layer* old_layer = window->layer();
  431. EXPECT_EQ(1.f, old_layer->GetTargetOpacity());
  432. const gfx::Rect target_bounds(40, 40, 400, 400);
  433. CrossFadeAnimationAnimateNewLayerOnly(
  434. window.get(), target_bounds, base::Milliseconds(200), gfx::Tween::LINEAR,
  435. "test-histogram-name");
  436. // Window's layer has been replaced.
  437. EXPECT_NE(old_layer, window->layer());
  438. // Original layer fades away. Transform is updated as the animation steps.
  439. EXPECT_EQ(0.f, old_layer->GetTargetOpacity());
  440. EXPECT_EQ(gfx::Rect(10, 10, 200, 200), old_layer->bounds());
  441. EXPECT_EQ(gfx::Transform(), old_layer->GetTargetTransform());
  442. // New layer animates in to the identity transform.
  443. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  444. EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
  445. // Start the animations, then set the bounds of the new window during the
  446. // animation.
  447. WaitForMilliseconds(10);
  448. // Set the bounds halfway through the animation. The bounds of the old layer
  449. // remain the same, but the transform has updated to match the bounds of the
  450. // new layer.
  451. window->SetBounds(gfx::Rect(80, 80, 200, 200));
  452. WaitForMilliseconds(100);
  453. EXPECT_EQ(gfx::Rect(10, 10, 200, 200), old_layer->bounds());
  454. EXPECT_NE(gfx::Transform(), old_layer->GetTargetTransform());
  455. // New layer targets remain the same.
  456. EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
  457. EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
  458. WaitForMilliseconds(300);
  459. EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
  460. }
  461. } // namespace ash