
See chromium-dev announcement: https://groups.google.com/a/chromium.org/g/chromium-dev/c/sKckMpzHQgY/m/M3SWxEg3AQAJ?utm_medium=email&utm_source=footer Code review: - First patch: Automatic rewrite - Later patches: Manual fixes The automatic rewrite used the script: ./tools/clang/rewrite_templated_container_fields/rewrite-multiple-platforms.sh Binary size increase: The increase is only 33% (+5kB) above the per-patch limit (+16kB). This is not a lot given the size of the rewrite. Increase of around 500kb was approved for MiraclePtr. AX-Relnotes: n/a. Binary-Size: See commit description. Bug: 1432993 Change-Id: I8dfc4c2b274b724b99cf408f010da5c821edae9c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5140028 Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org> Owners-Override: Arthur Sonzogni <arthursonzogni@chromium.org> Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org> Cr-Commit-Position: refs/heads/main@{#1239777}
221 lines
7.6 KiB
C++
221 lines
7.6 KiB
C++
// Copyright 2019 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "ash/public/cpp/autotest_private_api_utils.h"
|
|
|
|
#include <optional>
|
|
|
|
#include "ash/app_list/app_list_controller_impl.h"
|
|
#include "ash/app_list/app_list_presenter_impl.h"
|
|
#include "ash/frame/non_client_frame_view_ash.h"
|
|
#include "ash/shell.h"
|
|
#include "ash/wm/mru_window_tracker.h"
|
|
#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
|
|
#include "base/functional/bind.h"
|
|
#include "base/functional/callback_helpers.h"
|
|
#include "base/memory/raw_ptr.h"
|
|
#include "base/scoped_observation.h"
|
|
#include "ui/compositor/layer.h"
|
|
#include "ui/compositor/layer_animation_observer.h"
|
|
#include "ui/compositor/layer_animator.h"
|
|
#include "ui/display/screen.h"
|
|
|
|
namespace ash {
|
|
namespace {
|
|
|
|
class HomeLauncherStateWaiter {
|
|
public:
|
|
HomeLauncherStateWaiter(bool target_shown, base::OnceClosure closure)
|
|
: target_shown_(target_shown), closure_(std::move(closure)) {
|
|
Shell::Get()
|
|
->app_list_controller()
|
|
->SetHomeLauncherAnimationCallbackForTesting(base::BindRepeating(
|
|
&HomeLauncherStateWaiter::OnHomeLauncherAnimationCompleted,
|
|
base::Unretained(this)));
|
|
}
|
|
|
|
HomeLauncherStateWaiter(const HomeLauncherStateWaiter&) = delete;
|
|
HomeLauncherStateWaiter& operator=(const HomeLauncherStateWaiter&) = delete;
|
|
|
|
~HomeLauncherStateWaiter() {
|
|
Shell::Get()
|
|
->app_list_controller()
|
|
->SetHomeLauncherAnimationCallbackForTesting(base::NullCallback());
|
|
}
|
|
|
|
private:
|
|
// Passed to AppListControllerImpl as a callback to run when home launcher
|
|
// transition animation is complete.
|
|
void OnHomeLauncherAnimationCompleted(bool shown) {
|
|
if (shown == target_shown_) {
|
|
std::move(closure_).Run();
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
bool target_shown_;
|
|
base::OnceClosure closure_;
|
|
};
|
|
|
|
// A waiter that waits until the animation ended with the target state, and
|
|
// execute the callback. This self destruction upon completion.
|
|
class LauncherStateWaiter {
|
|
public:
|
|
LauncherStateWaiter(ash::AppListViewState state, base::OnceClosure closure)
|
|
: target_state_(state), closure_(std::move(closure)) {
|
|
Shell::Get()
|
|
->app_list_controller()
|
|
->SetStateTransitionAnimationCallbackForTesting(base::BindRepeating(
|
|
&LauncherStateWaiter::OnStateChanged, base::Unretained(this)));
|
|
}
|
|
|
|
LauncherStateWaiter(const LauncherStateWaiter&) = delete;
|
|
LauncherStateWaiter& operator=(const LauncherStateWaiter&) = delete;
|
|
|
|
~LauncherStateWaiter() {
|
|
Shell::Get()
|
|
->app_list_controller()
|
|
->SetStateTransitionAnimationCallbackForTesting(base::NullCallback());
|
|
}
|
|
|
|
void OnStateChanged(ash::AppListViewState state) {
|
|
if (target_state_ == state) {
|
|
std::move(closure_).Run();
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
private:
|
|
ash::AppListViewState target_state_;
|
|
base::OnceClosure closure_;
|
|
};
|
|
|
|
class LauncherAnimationWaiter : public ui::LayerAnimationObserver {
|
|
public:
|
|
LauncherAnimationWaiter(AppListView* view, base::OnceClosure closure)
|
|
: closure_(std::move(closure)) {
|
|
observation_.Observe(view->GetWidget()->GetLayer()->GetAnimator());
|
|
}
|
|
~LauncherAnimationWaiter() override = default;
|
|
LauncherAnimationWaiter(const LauncherAnimationWaiter&) = delete;
|
|
LauncherAnimationWaiter& operator=(const LauncherAnimationWaiter&) = delete;
|
|
|
|
private:
|
|
// ui::LayerAnimationObserver:
|
|
void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
|
|
std::move(closure_).Run();
|
|
delete this;
|
|
}
|
|
void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
|
|
OnLayerAnimationEnded(sequence);
|
|
}
|
|
void OnLayerAnimationScheduled(
|
|
ui::LayerAnimationSequence* sequence) override {}
|
|
|
|
base::OnceClosure closure_;
|
|
base::ScopedObservation<ui::LayerAnimator, ui::LayerAnimationObserver>
|
|
observation_{this};
|
|
};
|
|
|
|
bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
|
|
if (Shell::Get()->app_list_controller()->IsVisible(
|
|
/*display_id=*/std::nullopt) == target_visible) {
|
|
std::move(closure).Run();
|
|
return true;
|
|
}
|
|
|
|
new HomeLauncherStateWaiter(target_visible, std::move(closure));
|
|
return false;
|
|
}
|
|
|
|
bool WaitForLauncherAnimation(base::OnceClosure closure) {
|
|
auto* app_list_view =
|
|
Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
|
|
if (!app_list_view) {
|
|
std::move(closure).Run();
|
|
return true;
|
|
}
|
|
bool animating =
|
|
app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
|
|
if (!animating) {
|
|
std::move(closure).Run();
|
|
return true;
|
|
}
|
|
new LauncherAnimationWaiter(app_list_view, std::move(closure));
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::vector<raw_ptr<aura::Window, VectorExperimental>> GetAppWindowList() {
|
|
ScopedSkipUserSessionBlockedCheck skip_session_blocked;
|
|
return Shell::Get()->mru_window_tracker()->BuildAppWindowList(kAllDesks);
|
|
}
|
|
|
|
bool WaitForLauncherState(AppListViewState target_state,
|
|
base::OnceClosure closure) {
|
|
const bool in_tablet_mode = display::Screen::GetScreen()->InTabletMode();
|
|
if (in_tablet_mode) {
|
|
// App-list can't enter kPeeking or kHalf state in tablet mode. Thus
|
|
// |target_state| should be either kClosed, kFullscreenAllApps or
|
|
// kFullscreenSearch.
|
|
DCHECK(target_state == AppListViewState::kClosed ||
|
|
target_state == AppListViewState::kFullscreenAllApps ||
|
|
target_state == AppListViewState::kFullscreenSearch);
|
|
}
|
|
|
|
// In the tablet mode, home launcher visibility state needs special handling,
|
|
// as app list view visibility does not match home launcher visibility. The
|
|
// app list view is always visible, but the home launcher may be obscured by
|
|
// app windows. The waiter interprets waits for kClosed state as waits
|
|
// "home launcher not visible" state - note that the app list view
|
|
// is actually expected to be in a visible state.
|
|
AppListViewState effective_target_state =
|
|
in_tablet_mode && target_state == AppListViewState::kClosed
|
|
? AppListViewState::kFullscreenAllApps
|
|
: target_state;
|
|
|
|
std::optional<bool> target_home_launcher_visibility;
|
|
if (in_tablet_mode)
|
|
target_home_launcher_visibility = target_state != AppListViewState::kClosed;
|
|
|
|
// Don't wait if the launcher is already in the target state and not
|
|
// animating.
|
|
auto* app_list_view =
|
|
Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
|
|
bool animating =
|
|
app_list_view &&
|
|
app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
|
|
bool at_target_state =
|
|
(!app_list_view && effective_target_state == AppListViewState::kClosed) ||
|
|
(app_list_view &&
|
|
app_list_view->app_list_state() == effective_target_state);
|
|
|
|
if (at_target_state && !animating) {
|
|
// In tablet mode, ensure that the home launcher is in the expected state.
|
|
if (target_home_launcher_visibility.has_value()) {
|
|
return WaitForHomeLauncherState(*target_home_launcher_visibility,
|
|
std::move(closure));
|
|
}
|
|
std::move(closure).Run();
|
|
return true;
|
|
}
|
|
|
|
// In tablet mode, ensure that the home launcher is in the expected state.
|
|
base::OnceClosure callback =
|
|
target_home_launcher_visibility.has_value()
|
|
? base::BindOnce(base::IgnoreResult(&WaitForHomeLauncherState),
|
|
*target_home_launcher_visibility, std::move(closure))
|
|
: std::move(closure);
|
|
if (at_target_state)
|
|
return WaitForLauncherAnimation(std::move(callback));
|
|
new LauncherStateWaiter(
|
|
target_state,
|
|
base::BindOnce(base::IgnoreResult(&WaitForLauncherAnimation),
|
|
std::move(callback)));
|
|
return false;
|
|
}
|
|
|
|
} // namespace ash
|