Commit 52558bf8 authored by xiyuan's avatar xiyuan Committed by Commit bot

cros: Fix unlock crash with multi-display

SessionController::RunUnlockAnimation expects the callback to be
invoked only once. SessionStateAnimatorImpl uses the callback per
animation per container. Mulit-display would have multiple containers
involved hence multiple animation and callbacks. The multiple
callback would cause a mojo CHECK failure. SessionStateAnimator
should only run the callback once after all animations finish.
The CL use a BarrierClosure to combine the animation callbacks.

BUG=712422
TEST=SessionStateAnimatiorImplContainersTest.AnimationCallbackOnMultiDisplay

Review-Url: https://codereview.chromium.org/2823343006
Cr-Commit-Position: refs/heads/master@{#465670}
parent 79d9b867
...@@ -192,8 +192,8 @@ class ASH_EXPORT SessionStateAnimator { ...@@ -192,8 +192,8 @@ class ASH_EXPORT SessionStateAnimator {
AnimationSpeed speed) = 0; AnimationSpeed speed) = 0;
// Apply animation |type| to all containers included in |container_mask| with // Apply animation |type| to all containers included in |container_mask| with
// specified |speed| and call a |callback| at the end of the animation, if it // specified |speed| and call a |callback| once at the end of the animations,
// is not null. // if it is not null.
virtual void StartAnimationWithCallback(int container_mask, virtual void StartAnimationWithCallback(int container_mask,
AnimationType type, AnimationType type,
AnimationSpeed speed, AnimationSpeed speed,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/wm_window_animations.h" #include "ash/wm/wm_window_animations.h"
#include "base/barrier_closure.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_event_dispatcher.h"
...@@ -548,10 +549,12 @@ void SessionStateAnimatorImpl::StartAnimationWithCallback( ...@@ -548,10 +549,12 @@ void SessionStateAnimatorImpl::StartAnimationWithCallback(
base::Closure callback) { base::Closure callback) {
aura::Window::Windows containers; aura::Window::Windows containers;
GetContainers(container_mask, &containers); GetContainers(container_mask, &containers);
base::Closure animation_done_closure =
base::BarrierClosure(containers.size(), callback);
for (aura::Window::Windows::const_iterator it = containers.begin(); for (aura::Window::Windows::const_iterator it = containers.begin();
it != containers.end(); ++it) { it != containers.end(); ++it) {
ui::LayerAnimationObserver* observer = ui::LayerAnimationObserver* observer =
new CallbackAnimationObserver(callback); new CallbackAnimationObserver(animation_done_closure);
RunAnimationForWindow(*it, type, speed, observer); RunAnimationForWindow(*it, type, speed, observer);
} }
} }
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ash/wm/session_state_animator_impl.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/wm/session_state_animator.h" #include "ash/wm/session_state_animator.h"
#include "ash/wm/session_state_animator_impl.h" #include "base/bind.h"
#include "base/run_loop.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
typedef ash::test::AshTestBase SessionStateAnimatiorImplContainersTest; typedef ash::test::AshTestBase SessionStateAnimatiorImplContainersTest;
...@@ -80,4 +83,22 @@ TEST_F(SessionStateAnimatiorImplContainersTest, ContainersHaveIdTest) { ...@@ -80,4 +83,22 @@ TEST_F(SessionStateAnimatiorImplContainersTest, ContainersHaveIdTest) {
EXPECT_TRUE(containers.empty()); EXPECT_TRUE(containers.empty());
} }
// Test that SessionStateAnimatorImpl invokes the callback only once on
// multi-display env, where it needs to run multiple animations on multiple
// containers. See http://crbug.com/712422 for details.
TEST_F(SessionStateAnimatiorImplContainersTest,
AnimationCallbackOnMultiDisplay) {
UpdateDisplay("200x200,400x400");
int callback_count = 0;
SessionStateAnimatorImpl animator;
animator.StartAnimationWithCallback(
SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
SessionStateAnimator::ANIMATION_LIFT,
SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE,
base::Bind([](int* count) { ++(*count); }, &callback_count));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, callback_count);
}
} // namespace ash } // namespace ash
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment