display_animator.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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.
  4. #include "ash/display/display_animator.h"
  5. #include <memory>
  6. #include "ash/public/cpp/shell_window_ids.h"
  7. #include "ash/shell.h"
  8. #include "base/bind.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/threading/thread_task_runner_handle.h"
  11. #include "base/time/time.h"
  12. #include "ui/aura/window.h"
  13. #include "ui/aura/window_event_dispatcher.h"
  14. #include "ui/compositor/layer.h"
  15. #include "ui/compositor/layer_animation_observer.h"
  16. #include "ui/compositor/layer_animation_sequence.h"
  17. #include "ui/compositor/layer_animator.h"
  18. #include "ui/compositor/scoped_layer_animation_settings.h"
  19. namespace ash {
  20. namespace {
  21. const int kFadingAnimationDurationInMS = 200;
  22. const int kFadingTimeoutDurationInSeconds = 10;
  23. // CallbackRunningObserver accepts multiple layer animations and
  24. // runs the specified |callback| when all of the animations have finished.
  25. class CallbackRunningObserver {
  26. public:
  27. CallbackRunningObserver(base::OnceClosure callback)
  28. : completed_counter_(0),
  29. animation_aborted_(false),
  30. callback_(std::move(callback)) {}
  31. CallbackRunningObserver(const CallbackRunningObserver&) = delete;
  32. CallbackRunningObserver& operator=(const CallbackRunningObserver&) = delete;
  33. void AddNewAnimator(ui::LayerAnimator* animator) {
  34. auto observer = std::make_unique<Observer>(animator, this);
  35. animator->AddObserver(observer.get());
  36. observer_list_.push_back(std::move(observer));
  37. }
  38. private:
  39. void OnSingleTaskCompleted() {
  40. completed_counter_++;
  41. if (completed_counter_ >= observer_list_.size()) {
  42. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
  43. if (!animation_aborted_)
  44. base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
  45. std::move(callback_));
  46. }
  47. }
  48. void OnSingleTaskAborted() {
  49. animation_aborted_ = true;
  50. OnSingleTaskCompleted();
  51. }
  52. // The actual observer to listen each animation completion.
  53. class Observer : public ui::LayerAnimationObserver {
  54. public:
  55. Observer(ui::LayerAnimator* animator, CallbackRunningObserver* observer)
  56. : animator_(animator), observer_(observer) {}
  57. Observer(const Observer&) = delete;
  58. Observer& operator=(const Observer&) = delete;
  59. protected:
  60. // ui::LayerAnimationObserver overrides:
  61. void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
  62. animator_->RemoveObserver(this);
  63. observer_->OnSingleTaskCompleted();
  64. }
  65. void OnLayerAnimationAborted(
  66. ui::LayerAnimationSequence* sequence) override {
  67. animator_->RemoveObserver(this);
  68. observer_->OnSingleTaskAborted();
  69. }
  70. void OnLayerAnimationScheduled(
  71. ui::LayerAnimationSequence* sequence) override {}
  72. bool RequiresNotificationWhenAnimatorDestroyed() const override {
  73. return true;
  74. }
  75. private:
  76. ui::LayerAnimator* animator_;
  77. CallbackRunningObserver* observer_;
  78. };
  79. size_t completed_counter_;
  80. bool animation_aborted_;
  81. std::vector<std::unique_ptr<Observer>> observer_list_;
  82. base::OnceClosure callback_;
  83. };
  84. } // namespace
  85. DisplayAnimator::DisplayAnimator() {
  86. Shell::Get()->display_configurator()->AddObserver(this);
  87. }
  88. DisplayAnimator::~DisplayAnimator() {
  89. Shell::Get()->display_configurator()->RemoveObserver(this);
  90. ClearHidingLayers();
  91. }
  92. void DisplayAnimator::StartFadeOutAnimation(base::OnceClosure callback) {
  93. CallbackRunningObserver* observer =
  94. new CallbackRunningObserver(std::move(callback));
  95. ClearHidingLayers();
  96. // Make the fade-out animation for all root windows. Instead of actually
  97. // hiding the root windows, we put a black layer over a root window for
  98. // safety. These layers remain to hide root windows and will be deleted
  99. // after the animation of OnDisplayModeChanged().
  100. for (aura::Window* root_window : Shell::Get()->GetAllRootWindows()) {
  101. std::unique_ptr<ui::Layer> hiding_layer =
  102. std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  103. hiding_layer->SetColor(SK_ColorBLACK);
  104. hiding_layer->SetBounds(root_window->bounds());
  105. ui::Layer* parent =
  106. Shell::GetContainer(root_window, kShellWindowId_OverlayContainer)
  107. ->layer();
  108. parent->Add(hiding_layer.get());
  109. hiding_layer->SetOpacity(0.0);
  110. ui::ScopedLayerAnimationSettings settings(hiding_layer->GetAnimator());
  111. settings.SetTransitionDuration(
  112. base::Milliseconds(kFadingAnimationDurationInMS));
  113. observer->AddNewAnimator(hiding_layer->GetAnimator());
  114. hiding_layer->SetOpacity(1.0f);
  115. hiding_layer->SetVisible(true);
  116. hiding_layers_[root_window] = std::move(hiding_layer);
  117. }
  118. // In case that OnDisplayModeChanged() isn't called or its animator is
  119. // canceled due to some unknown errors, we set a timer to clear these
  120. // hiding layers.
  121. timer_ = std::make_unique<base::OneShotTimer>();
  122. timer_->Start(FROM_HERE, base::Seconds(kFadingTimeoutDurationInSeconds), this,
  123. &DisplayAnimator::ClearHidingLayers);
  124. }
  125. void DisplayAnimator::StartFadeInAnimation() {
  126. // We want to make sure clearing all of hiding layers after the animation
  127. // finished. Note that this callback can be canceled, but the cancel only
  128. // happens when the next animation is scheduled. Thus the hiding layers
  129. // should be deleted eventually.
  130. CallbackRunningObserver* observer =
  131. new CallbackRunningObserver(base::BindOnce(
  132. &DisplayAnimator::ClearHidingLayers, weak_ptr_factory_.GetWeakPtr()));
  133. // Ensure that layers are not animating.
  134. for (auto& e : hiding_layers_) {
  135. ui::LayerAnimator* animator = e.second->GetAnimator();
  136. if (animator->is_animating())
  137. animator->StopAnimating();
  138. }
  139. // Schedules the fade-in effect for all root windows. Because we put the
  140. // black layers for fade-out, here we actually turn those black layers
  141. // invisible.
  142. for (aura::Window* root_window : Shell::Get()->GetAllRootWindows()) {
  143. ui::Layer* hiding_layer = nullptr;
  144. if (hiding_layers_.find(root_window) == hiding_layers_.end()) {
  145. // In case of the transition from mirroring->non-mirroring, new root
  146. // windows appear and we do not have the black layers for them. Thus
  147. // we need to create the layer and make it visible.
  148. hiding_layer = new ui::Layer(ui::LAYER_SOLID_COLOR);
  149. hiding_layer->SetColor(SK_ColorBLACK);
  150. hiding_layer->SetBounds(root_window->bounds());
  151. ui::Layer* parent =
  152. Shell::GetContainer(root_window, kShellWindowId_OverlayContainer)
  153. ->layer();
  154. parent->Add(hiding_layer);
  155. hiding_layer->SetOpacity(1.0f);
  156. hiding_layer->SetVisible(true);
  157. hiding_layers_[root_window] = base::WrapUnique(hiding_layer);
  158. } else {
  159. hiding_layer = hiding_layers_[root_window].get();
  160. if (hiding_layer->bounds() != root_window->bounds())
  161. hiding_layer->SetBounds(root_window->bounds());
  162. }
  163. ui::ScopedLayerAnimationSettings settings(hiding_layer->GetAnimator());
  164. settings.SetTransitionDuration(
  165. base::Milliseconds(kFadingAnimationDurationInMS));
  166. observer->AddNewAnimator(hiding_layer->GetAnimator());
  167. hiding_layer->SetOpacity(0.0f);
  168. hiding_layer->SetVisible(false);
  169. }
  170. }
  171. void DisplayAnimator::OnDisplayModeChanged(
  172. const display::DisplayConfigurator::DisplayStateList& displays) {
  173. if (!hiding_layers_.empty())
  174. StartFadeInAnimation();
  175. }
  176. void DisplayAnimator::OnDisplayModeChangeFailed(
  177. const display::DisplayConfigurator::DisplayStateList& displays,
  178. display::MultipleDisplayState failed_new_state) {
  179. if (!hiding_layers_.empty())
  180. StartFadeInAnimation();
  181. }
  182. void DisplayAnimator::ClearHidingLayers() {
  183. if (timer_) {
  184. timer_->Stop();
  185. timer_.reset();
  186. }
  187. hiding_layers_.clear();
  188. }
  189. } // namespace ash