#include "ash/wm/overview/overview_test_base.h"
#include <tuple>
#include "ash/public/cpp/test/test_saved_desk_delegate.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/style/close_button.h"
#include "ash/test_shell_delegate.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_item_view.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/overview/overview_wallpaper_controller.h"
#include "ash/wm/overview/scoped_overview_transform_window.h"
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
#include "ash/wm/window_preview_view.h"
#include "components/app_constants/constants.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/presentation_time_recorder.h"
#include "ui/compositor/test/test_utils.h"
#include "ui/gfx/geometry/transform_util.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/wm/core/coordinate_conversion.h"
namespace ash {
OverviewTestBase::~OverviewTestBase() = default;
void OverviewTestBase::EnterTabletMode() {
TabletModeControllerTestApi test_api;
test_api.DetachAllMice();
test_api.EnterTabletMode();
base::RunLoop().RunUntilIdle();
}
bool OverviewTestBase::InOverviewSession() {
return GetOverviewController()->InOverviewSession();
}
bool OverviewTestBase::WindowsOverlapping(aura::Window* window1,
aura::Window* window2) {
const gfx::Rect window1_bounds = GetTransformedTargetBounds(window1);
const gfx::Rect window2_bounds = GetTransformedTargetBounds(window2);
return window1_bounds.Intersects(window2_bounds);
}
std::unique_ptr<aura::Window> OverviewTestBase::CreateUnsnappableWindow(
const gfx::Rect& bounds) {
std::unique_ptr<aura::Window> window = CreateTestWindow(bounds);
window->SetProperty(aura::client::kResizeBehaviorKey,
aura::client::kResizeBehaviorNone);
return window;
}
void OverviewTestBase::ClickWindow(aura::Window* window) {
ui::test::EventGenerator event_generator(window->GetRootWindow(), window);
event_generator.ClickLeftButton();
}
OverviewController* OverviewTestBase::GetOverviewController() {
return Shell::Get()->overview_controller();
}
OverviewSession* OverviewTestBase::GetOverviewSession() {
return GetOverviewController()->overview_session();
}
SplitViewController* OverviewTestBase::GetSplitViewController() {
return SplitViewController::Get(Shell::GetPrimaryRootWindow());
}
gfx::Rect OverviewTestBase::GetTransformedBounds(aura::Window* window) {
gfx::RectF bounds(window->layer()->bounds());
wm::TranslateRectToScreen(window->parent(), &bounds);
const gfx::Transform transform =
gfx::TransformAboutPivot(bounds.origin(), window->layer()->transform());
return ToStableSizeRoundedRect(transform.MapRect(bounds));
}
gfx::Rect OverviewTestBase::GetTransformedTargetBounds(aura::Window* window) {
gfx::RectF bounds(window->layer()->GetTargetBounds());
wm::TranslateRectToScreen(window->parent(), &bounds);
const gfx::Transform transform = gfx::TransformAboutPivot(
bounds.origin(), window->layer()->GetTargetTransform());
return ToStableSizeRoundedRect(transform.MapRect(bounds));
}
gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow(
aura::Window* window) {
aura::Window* root = window->GetRootWindow();
CHECK(window->layer());
CHECK(root->layer());
gfx::Transform transform;
if (!window->layer()->GetTargetTransformRelativeTo(root->layer(),
&transform)) {
return gfx::Rect();
}
return transform.MapRect(gfx::Rect(window->bounds().size()));
}
OverviewItem* OverviewTestBase::GetDropTarget(int grid_index) {
return GetOverviewSession()->grid_list_[grid_index]->GetDropTarget();
}
CloseButton* OverviewTestBase::GetCloseButton(OverviewItem* item) {
return item->overview_item_view_->close_button();
}
views::Label* OverviewTestBase::GetLabelView(OverviewItem* item) {
return item->overview_item_view_->title_label();
}
views::View* OverviewTestBase::GetBackdropView(OverviewItem* item) {
return item->overview_item_view_->backdrop_view();
}
WindowPreviewView* OverviewTestBase::GetPreviewView(OverviewItem* item) {
return item->overview_item_view_->preview_view();
}
float OverviewTestBase::GetCloseButtonOpacity(OverviewItem* item) {
return GetCloseButton(item)->layer()->opacity();
}
float OverviewTestBase::GetTitlebarOpacity(OverviewItem* item) {
return item->overview_item_view_->header_view()->layer()->opacity();
}
const ScopedOverviewTransformWindow& OverviewTestBase::GetTransformWindow(
OverviewItem* item) const {
return item->transform_window_;
}
bool OverviewTestBase::HasRoundedCorner(OverviewItem* item) {
const ui::Layer* layer = item->transform_window_.IsMinimized()
? GetPreviewView(item)->layer()
: GetTransformWindow(item).window()->layer();
return !layer->rounded_corner_radii().IsEmpty();
}
void OverviewTestBase::CheckWindowAndCloseButtonInScreen(
aura::Window* window,
OverviewItem* window_item) {
const gfx::Rect screen_bounds =
window_item->root_window()->GetBoundsInScreen();
EXPECT_TRUE(window_item->Contains(window));
EXPECT_TRUE(screen_bounds.Contains(GetTransformedTargetBounds(window)));
EXPECT_TRUE(
screen_bounds.Contains(GetCloseButton(window_item)->GetBoundsInScreen()));
}
void OverviewTestBase::SetUp() {
AshTestBase::SetUp();
aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
shelf_view_test_api_ = std::make_unique<ShelfViewTestAPI>(
GetPrimaryShelf()->GetShelfViewForTesting());
shelf_view_test_api_->SetAnimationDuration(base::Milliseconds(1));
ScopedOverviewTransformWindow::SetImmediateCloseForTests(
true);
OverviewWallpaperController::SetDisableChangeWallpaperForTest(true);
ui::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
true);
}
void OverviewTestBase::TearDown() {
OverviewWallpaperController::SetDisableChangeWallpaperForTest(false);
ui::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
false);
trace_names_.clear();
AshTestBase::TearDown();
}
void OverviewTestBase::CheckForDuplicateTraceName(const std::string& trace) {
DCHECK(!base::Contains(trace_names_, trace)) << trace;
trace_names_.push_back(trace);
}
void OverviewTestBase::CheckA11yOverrides(const std::string& trace,
views::Widget* widget,
views::Widget* expected_previous,
views::Widget* expected_next) {
SCOPED_TRACE(trace);
views::View* contents_view = widget->GetContentsView();
views::ViewAccessibility& view_accessibility =
contents_view->GetViewAccessibility();
EXPECT_EQ(expected_previous, view_accessibility.GetPreviousWindowFocus());
EXPECT_EQ(expected_next, view_accessibility.GetNextWindowFocus());
}
void OverviewTestBase::CheckOverviewEnterExitHistogram(
const std::string& trace,
const std::vector<int>& enter_counts,
const std::vector<int>& exit_counts) {
CheckForDuplicateTraceName(trace);
std::ignore = ui::WaitForNextFrameToBePresented(
Shell::GetPrimaryRootWindow()->layer()->GetCompositor(),
base::Milliseconds(500));
{
SCOPED_TRACE(trace + ".Enter");
CheckOverviewHistogram("Ash.Overview.AnimationSmoothness.Enter",
enter_counts);
}
{
SCOPED_TRACE(trace + ".Exit");
CheckOverviewHistogram("Ash.Overview.AnimationSmoothness.Exit",
exit_counts);
}
}
gfx::Rect OverviewTestBase::GetGridBounds() {
if (GetOverviewSession())
return GetOverviewSession()->grid_list_[0]->bounds_;
return gfx::Rect();
}
void OverviewTestBase::SetGridBounds(OverviewGrid* grid,
const gfx::Rect& bounds) {
grid->bounds_ = bounds;
}
void OverviewTestBase::CheckOverviewHistogram(const std::string& histogram,
const std::vector<int>& counts) {
ASSERT_EQ(5u, counts.size());
histograms_.ExpectTotalCount(histogram + ".ClamshellMode", counts[0]);
histograms_.ExpectTotalCount(histogram + ".SingleClamshellMode", counts[1]);
histograms_.ExpectTotalCount(histogram + ".TabletMode", counts[2]);
histograms_.ExpectTotalCount(histogram + ".MinimizedTabletMode", counts[3]);
histograms_.ExpectTotalCount(histogram + ".SplitView", counts[4]);
}
}