123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/wm/screen_pinning_controller.h"
- #include <vector>
- #include "ash/accelerators/accelerator_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/wm/client_controlled_state.h"
- #include "ash/wm/screen_pinning_controller.h"
- #include "ash/wm/window_state.h"
- #include "ash/wm/window_util.h"
- #include "ash/wm/wm_event.h"
- #include "ui/aura/window.h"
- namespace ash {
- namespace {
- int FindIndex(const std::vector<aura::Window*>& windows,
- const aura::Window* target) {
- auto iter = std::find(windows.begin(), windows.end(), target);
- return iter != windows.end() ? iter - windows.begin() : -1;
- }
- class TestClientControlledStateDelegate
- : public ClientControlledState::Delegate {
- public:
- ~TestClientControlledStateDelegate() override = default;
- void HandleWindowStateRequest(WindowState* state,
- chromeos::WindowStateType type) override {}
- void HandleBoundsRequest(WindowState* state,
- chromeos::WindowStateType type,
- const gfx::Rect& requested_bounds,
- int64_t display_id) override {}
- };
- } // namespace
- using ScreenPinningControllerTest = AshTestBase;
- TEST_F(ScreenPinningControllerTest, IsPinned) {
- aura::Window* w1 = CreateTestWindowInShellWithId(0);
- wm::ActivateWindow(w1);
- window_util::PinWindow(w1, /* trusted */ false);
- EXPECT_TRUE(Shell::Get()->screen_pinning_controller()->IsPinned());
- }
- TEST_F(ScreenPinningControllerTest, OnlyOnePinnedWindow) {
- aura::Window* w1 = CreateTestWindowInShellWithId(0);
- aura::Window* w2 = CreateTestWindowInShellWithId(1);
- wm::ActivateWindow(w1);
- window_util::PinWindow(w1, /* trusted */ false);
- EXPECT_TRUE(WindowState::Get(w1)->IsPinned());
- EXPECT_FALSE(WindowState::Get(w2)->IsPinned());
- // Prohibit to pin two (or more) windows.
- window_util::PinWindow(w2, /* trusted */ false);
- EXPECT_TRUE(WindowState::Get(w1)->IsPinned());
- EXPECT_FALSE(WindowState::Get(w2)->IsPinned());
- }
- TEST_F(ScreenPinningControllerTest, FullscreenInPinnedMode) {
- aura::Window* w1 = CreateTestWindowInShellWithId(0);
- aura::Window* w2 = CreateTestWindowInShellWithId(1);
- wm::ActivateWindow(w1);
- window_util::PinWindow(w1, /* trusted */ false);
- {
- // Window w1 should be in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index1, index2);
- }
- // Set w2 to fullscreen.
- {
- wm::ActivateWindow(w2);
- const WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
- WindowState::Get(w2)->OnWMEvent(&event);
- }
- {
- // Verify that w1 is still in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index1, index2);
- }
- // Unset w2's fullscreen.
- {
- wm::ActivateWindow(w2);
- const WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
- WindowState::Get(w2)->OnWMEvent(&event);
- }
- {
- // Verify that w1 is still in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index1, index2);
- }
- // Maximize w2.
- {
- wm::ActivateWindow(w2);
- const WMEvent event(WM_EVENT_TOGGLE_MAXIMIZE);
- WindowState::Get(w2)->OnWMEvent(&event);
- }
- {
- // Verify that w1 is still in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index1, index2);
- }
- // Unset w2's maximize.
- {
- wm::ActivateWindow(w2);
- const WMEvent event(WM_EVENT_TOGGLE_MAXIMIZE);
- WindowState::Get(w2)->OnWMEvent(&event);
- }
- {
- // Verify that w1 is still in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index1, index2);
- }
- // Restore w1.
- WindowState::Get(w1)->Restore();
- // Now, fullscreen-ize w2 should put it in front of w1.
- {
- wm::ActivateWindow(w2);
- const WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
- WindowState::Get(w2)->OnWMEvent(&event);
- }
- {
- // Verify that w1 is still in front of w2.
- std::vector<aura::Window*> siblings = w1->parent()->children();
- int index1 = FindIndex(siblings, w1);
- int index2 = FindIndex(siblings, w2);
- EXPECT_NE(-1, index1);
- EXPECT_NE(-1, index2);
- EXPECT_GT(index2, index1);
- }
- }
- TEST_F(ScreenPinningControllerTest, TrustedPinnedWithAccelerator) {
- aura::Window* w1 = CreateTestWindowInShellWithId(0);
- wm::ActivateWindow(w1);
- window_util::PinWindow(w1, /* trusted */ true);
- EXPECT_TRUE(Shell::Get()->screen_pinning_controller()->IsPinned());
- Shell::Get()->accelerator_controller()->PerformActionIfEnabled(UNPIN, {});
- // The UNPIN accelerator key is disabled for trusted pinned and the window
- // must be still pinned.
- EXPECT_TRUE(Shell::Get()->screen_pinning_controller()->IsPinned());
- }
- TEST_F(ScreenPinningControllerTest, ExitUnifiedDisplay) {
- display_manager()->SetUnifiedDesktopEnabled(true);
- UpdateDisplay("400x300, 500x400");
- aura::Window* w1 = CreateTestWindowInShellWithId(0);
- wm::ActivateWindow(w1);
- auto* window_state = WindowState::Get(w1);
- window_util::PinWindow(w1, /*trusted=*/true);
- EXPECT_TRUE(window_state->IsPinned());
- EXPECT_TRUE(Shell::Get()->screen_pinning_controller()->IsPinned());
- UpdateDisplay("300x200");
- EXPECT_TRUE(window_state->IsPinned());
- EXPECT_TRUE(Shell::Get()->screen_pinning_controller()->IsPinned());
- }
- TEST_F(ScreenPinningControllerTest, CleanUpObserversAndDimmer) {
- // Create a window with ClientControlledState.
- auto w = CreateAppWindow(gfx::Rect(), AppType::CHROME_APP, 0);
- ash::WindowState* ws = ash::WindowState::Get(w.get());
- auto delegate = std::make_unique<TestClientControlledStateDelegate>();
- auto state = std::make_unique<ClientControlledState>(std::move(delegate));
- ws->SetStateObject(std::move(state));
- wm::ActivateWindow(w.get());
- // Observer should be added to |w|, and |w->parent()|.
- window_util::PinWindow(w.get(), /* truested */ false);
- EXPECT_TRUE(WindowState::Get(w.get())->IsPinned());
- const aura::Window* container = w->parent();
- // Destroying |w| clears |pinned_window_|. The observers should be removed
- // even if ClientControlledState doesn't call SetPinnedWindow when
- // WindowState::Restore() is called.
- w.reset();
- // It should clear all child windows in |container| when the pinned window is
- // destroyed.
- EXPECT_EQ(container->children().size(), 0u);
- // Add a sibling window. It should not crash.
- CreateTestWindowInShellWithId(2);
- }
- } // namespace ash
|