autotest_private_api_utils.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright 2019 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/public/cpp/autotest_private_api_utils.h"
  5. #include "ash/app_list/app_list_controller_impl.h"
  6. #include "ash/app_list/app_list_presenter_impl.h"
  7. #include "ash/frame/non_client_frame_view_ash.h"
  8. #include "ash/shell.h"
  9. #include "ash/wm/mru_window_tracker.h"
  10. #include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
  11. #include "base/bind.h"
  12. #include "base/callback_helpers.h"
  13. #include "base/scoped_observation.h"
  14. #include "third_party/abseil-cpp/absl/types/optional.h"
  15. #include "ui/compositor/layer.h"
  16. #include "ui/compositor/layer_animation_observer.h"
  17. #include "ui/compositor/layer_animator.h"
  18. namespace ash {
  19. namespace {
  20. class HomeLauncherStateWaiter {
  21. public:
  22. HomeLauncherStateWaiter(bool target_shown, base::OnceClosure closure)
  23. : target_shown_(target_shown), closure_(std::move(closure)) {
  24. Shell::Get()
  25. ->app_list_controller()
  26. ->SetHomeLauncherAnimationCallbackForTesting(base::BindRepeating(
  27. &HomeLauncherStateWaiter::OnHomeLauncherAnimationCompleted,
  28. base::Unretained(this)));
  29. }
  30. HomeLauncherStateWaiter(const HomeLauncherStateWaiter&) = delete;
  31. HomeLauncherStateWaiter& operator=(const HomeLauncherStateWaiter&) = delete;
  32. ~HomeLauncherStateWaiter() {
  33. Shell::Get()
  34. ->app_list_controller()
  35. ->SetHomeLauncherAnimationCallbackForTesting(base::NullCallback());
  36. }
  37. private:
  38. // Passed to AppListControllerImpl as a callback to run when home launcher
  39. // transition animation is complete.
  40. void OnHomeLauncherAnimationCompleted(bool shown) {
  41. if (shown == target_shown_) {
  42. std::move(closure_).Run();
  43. delete this;
  44. }
  45. }
  46. bool target_shown_;
  47. base::OnceClosure closure_;
  48. };
  49. // A waiter that waits until the animation ended with the target state, and
  50. // execute the callback. This self destruction upon completion.
  51. class LauncherStateWaiter {
  52. public:
  53. LauncherStateWaiter(ash::AppListViewState state, base::OnceClosure closure)
  54. : target_state_(state), closure_(std::move(closure)) {
  55. Shell::Get()
  56. ->app_list_controller()
  57. ->SetStateTransitionAnimationCallbackForTesting(base::BindRepeating(
  58. &LauncherStateWaiter::OnStateChanged, base::Unretained(this)));
  59. }
  60. LauncherStateWaiter(const LauncherStateWaiter&) = delete;
  61. LauncherStateWaiter& operator=(const LauncherStateWaiter&) = delete;
  62. ~LauncherStateWaiter() {
  63. Shell::Get()
  64. ->app_list_controller()
  65. ->SetStateTransitionAnimationCallbackForTesting(base::NullCallback());
  66. }
  67. void OnStateChanged(ash::AppListViewState state) {
  68. if (target_state_ == state) {
  69. std::move(closure_).Run();
  70. delete this;
  71. }
  72. }
  73. private:
  74. ash::AppListViewState target_state_;
  75. base::OnceClosure closure_;
  76. };
  77. class LauncherAnimationWaiter : public ui::LayerAnimationObserver {
  78. public:
  79. LauncherAnimationWaiter(AppListView* view, base::OnceClosure closure)
  80. : closure_(std::move(closure)) {
  81. observation_.Observe(view->GetWidget()->GetLayer()->GetAnimator());
  82. }
  83. ~LauncherAnimationWaiter() override = default;
  84. LauncherAnimationWaiter(const LauncherAnimationWaiter&) = delete;
  85. LauncherAnimationWaiter& operator=(const LauncherAnimationWaiter&) = delete;
  86. private:
  87. // ui::LayerAnimationObserver:
  88. void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
  89. std::move(closure_).Run();
  90. delete this;
  91. }
  92. void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
  93. OnLayerAnimationEnded(sequence);
  94. }
  95. void OnLayerAnimationScheduled(
  96. ui::LayerAnimationSequence* sequence) override {}
  97. base::OnceClosure closure_;
  98. base::ScopedObservation<ui::LayerAnimator, ui::LayerAnimationObserver>
  99. observation_{this};
  100. };
  101. bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
  102. if (Shell::Get()->app_list_controller()->IsVisible(
  103. /*display_id=*/absl::nullopt) == target_visible) {
  104. std::move(closure).Run();
  105. return true;
  106. }
  107. new HomeLauncherStateWaiter(target_visible, std::move(closure));
  108. return false;
  109. }
  110. bool WaitForLauncherAnimation(base::OnceClosure closure) {
  111. auto* app_list_view =
  112. Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
  113. if (!app_list_view) {
  114. std::move(closure).Run();
  115. return true;
  116. }
  117. bool animating =
  118. app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
  119. if (!animating) {
  120. std::move(closure).Run();
  121. return true;
  122. }
  123. new LauncherAnimationWaiter(app_list_view, std::move(closure));
  124. return false;
  125. }
  126. } // namespace
  127. std::vector<aura::Window*> GetAppWindowList() {
  128. ScopedSkipUserSessionBlockedCheck skip_session_blocked;
  129. return Shell::Get()->mru_window_tracker()->BuildAppWindowList(kAllDesks);
  130. }
  131. bool WaitForLauncherState(AppListViewState target_state,
  132. base::OnceClosure closure) {
  133. const bool in_tablet_mode =
  134. Shell::Get()->tablet_mode_controller()->InTabletMode();
  135. if (in_tablet_mode) {
  136. // App-list can't enter kPeeking or kHalf state in tablet mode. Thus
  137. // |target_state| should be either kClosed, kFullscreenAllApps or
  138. // kFullscreenSearch.
  139. DCHECK(target_state == AppListViewState::kClosed ||
  140. target_state == AppListViewState::kFullscreenAllApps ||
  141. target_state == AppListViewState::kFullscreenSearch);
  142. }
  143. // In the tablet mode, home launcher visibility state needs special handling,
  144. // as app list view visibility does not match home launcher visibility. The
  145. // app list view is always visible, but the home launcher may be obscured by
  146. // app windows. The waiter interprets waits for kClosed state as waits
  147. // "home launcher not visible" state - note that the app list view
  148. // is actually expected to be in a visible state.
  149. AppListViewState effective_target_state =
  150. in_tablet_mode && target_state == AppListViewState::kClosed
  151. ? AppListViewState::kFullscreenAllApps
  152. : target_state;
  153. absl::optional<bool> target_home_launcher_visibility;
  154. if (in_tablet_mode)
  155. target_home_launcher_visibility = target_state != AppListViewState::kClosed;
  156. // Don't wait if the launcher is already in the target state and not
  157. // animating.
  158. auto* app_list_view =
  159. Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
  160. bool animating =
  161. app_list_view &&
  162. app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
  163. bool at_target_state =
  164. (!app_list_view && effective_target_state == AppListViewState::kClosed) ||
  165. (app_list_view &&
  166. app_list_view->app_list_state() == effective_target_state);
  167. if (at_target_state && !animating) {
  168. // In tablet mode, ensure that the home launcher is in the expected state.
  169. if (target_home_launcher_visibility.has_value()) {
  170. return WaitForHomeLauncherState(*target_home_launcher_visibility,
  171. std::move(closure));
  172. }
  173. std::move(closure).Run();
  174. return true;
  175. }
  176. // In tablet mode, ensure that the home launcher is in the expected state.
  177. base::OnceClosure callback =
  178. target_home_launcher_visibility.has_value()
  179. ? base::BindOnce(base::IgnoreResult(&WaitForHomeLauncherState),
  180. *target_home_launcher_visibility, std::move(closure))
  181. : std::move(closure);
  182. if (at_target_state)
  183. return WaitForLauncherAnimation(std::move(callback));
  184. new LauncherStateWaiter(
  185. target_state,
  186. base::BindOnce(base::IgnoreResult(&WaitForLauncherAnimation),
  187. std::move(callback)));
  188. return false;
  189. }
  190. } // namespace ash