1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
// Copyright 2013 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/display/mirror_window_controller.h"
#include "ash/display/mirror_window_test_api.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/cursor_manager_test_api.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/env.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/hit_test.h"
#include "ui/display/display_switches.h"
#include "ui/display/display_transform.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/display/types/display_constants.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/overlay_transform.h"
namespace ash {
namespace {
display::ManagedDisplayInfo CreateDisplayInfo(int64_t id,
const gfx::Rect& bounds,
float scale = 1.f) {
display::ManagedDisplayInfo info = display::CreateDisplayInfo(id, bounds);
info.set_device_scale_factor(scale);
return info;
}
class MirrorOnBootTest : public AshTestBase {
public:
MirrorOnBootTest() = default;
MirrorOnBootTest(const MirrorOnBootTest&) = delete;
MirrorOnBootTest& operator=(const MirrorOnBootTest&) = delete;
~MirrorOnBootTest() override = default;
void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
::switches::kHostWindowBounds, "1+1-400x300,1+301-400x300");
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableSoftwareMirroring);
AshTestBase::SetUp();
}
};
} // namespace
using MirrorWindowControllerTest = AshTestBase;
// Make sure that the compositor based mirroring can switch
// from/to dock mode.
TEST_F(MirrorWindowControllerTest, DockMode) {
const int64_t internal_id = 1;
const int64_t external_id = 2;
const display::ManagedDisplayInfo internal_display_info =
CreateDisplayInfo(internal_id, gfx::Rect(0, 0, 400, 500));
const display::ManagedDisplayInfo external_display_info =
CreateDisplayInfo(external_id, gfx::Rect(1, 1, 200, 100));
std::vector<display::ManagedDisplayInfo> display_info_list;
// software mirroring.
display_info_list.push_back(internal_display_info);
display_info_list.push_back(external_display_info);
display_manager()->OnNativeDisplaysChanged(display_info_list);
const int64_t internal_display_id =
display::test::DisplayManagerTestApi(display_manager())
.SetFirstDisplayAsInternalDisplay();
EXPECT_EQ(internal_id, internal_display_id);
display_manager()->SetMirrorMode(display::MirrorMode::kNormal, absl::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
EXPECT_EQ(external_id,
display_manager()->GetMirroringDestinationDisplayIdList()[0]);
// dock mode.
display_info_list.clear();
display_info_list.push_back(external_display_info);
display_manager()->OnNativeDisplaysChanged(display_info_list);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_FALSE(display_manager()->IsInMirrorMode());
// back to software mirroring.
display_info_list.clear();
display_info_list.push_back(internal_display_info);
display_info_list.push_back(external_display_info);
display_manager()->OnNativeDisplaysChanged(display_info_list);
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_TRUE(display_manager()->IsInMirrorMode());
EXPECT_EQ(external_id,
display_manager()->GetMirroringDestinationDisplayIdList()[0]);
}
TEST_F(MirrorOnBootTest, MirrorOnBoot) {
EXPECT_TRUE(display_manager()->IsInMirrorMode());
base::RunLoop().RunUntilIdle();
MirrorWindowTestApi test_api;
EXPECT_EQ(1U, test_api.GetHosts().size());
}
class MirrorWindowControllerRotationAndPanelOrientationTest
: public MirrorWindowControllerTest,
public testing::WithParamInterface<
std::tuple<display::Display::Rotation, display::PanelOrientation>> {};
// Test that the mirror display matches the size and rotation of the source.
TEST_P(MirrorWindowControllerRotationAndPanelOrientationTest, MirrorSize) {
const int64_t primary_id = 1;
const int64_t mirror_id = 2;
const display::Display::Rotation active_rotation = std::get<0>(GetParam());
const display::PanelOrientation panel_orientation = std::get<1>(GetParam());
// Run the test with and without display scaling.
int scale_factors[] = {1, 2};
for (int scale : scale_factors) {
display::ManagedDisplayInfo primary_display_info =
CreateDisplayInfo(primary_id, gfx::Rect(0, 0, 400, 300), scale);
primary_display_info.set_panel_orientation(panel_orientation);
primary_display_info.SetRotation(active_rotation,
display::Display::RotationSource::ACTIVE);
const display::ManagedDisplayInfo mirror_display_info =
CreateDisplayInfo(mirror_id, gfx::Rect(400, 0, 600, 500), scale);
std::vector<display::ManagedDisplayInfo> display_info_list = {
primary_display_info, mirror_display_info};
// Start software mirroring.
display_manager()->OnNativeDisplaysChanged(display_info_list);
display_manager()->SetMirrorMode(display::MirrorMode::kNormal,
absl::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, display_manager()->GetNumDisplays());
EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
// Check the size of the mirror window.
const display::Display& primary_display =
display_manager()->GetDisplayForId(primary_id);
aura::Window* root_window = Shell::GetRootWindowForDisplayId(mirror_id);
aura::Window* mirror_window = root_window->children()[0];
EXPECT_EQ(primary_display.GetSizeInPixel(), root_window->bounds().size());
EXPECT_EQ(primary_display.GetSizeInPixel(), mirror_window->bounds().size());
// Mirror should have a display transform hint that matches the active
// rotation (excluding the panel orientation) of the source.
EXPECT_EQ(display::DisplayRotationToOverlayTransform(active_rotation),
root_window->GetHost()->compositor()->display_transform_hint());
}
}
INSTANTIATE_TEST_SUITE_P(
All,
MirrorWindowControllerRotationAndPanelOrientationTest,
testing::Combine(testing::Values(display::Display::ROTATE_0,
display::Display::ROTATE_90,
display::Display::ROTATE_180,
display::Display::ROTATE_270),
testing::Values(display::PanelOrientation::kNormal,
display::PanelOrientation::kBottomUp,
display::PanelOrientation::kLeftUp,
display::PanelOrientation::kRightUp)));
} // namespace ash
|