blob: 41c795cf707c4f217cbff3e3d9a32b29953f1f9b [file] [log] [blame]
// 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 <memory>
#include <utility>
#include "ash/public/cpp/shelf_model.h"
#include "ash/public/cpp/test/test_shelf_item_delegate.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/session/test_session_controller_client.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_app_button.h"
#include "ash/shelf/shelf_controller.h"
#include "ash/shelf/shelf_party_feature_pod_controller.h"
#include "ash/shelf/shelf_view.h"
#include "ash/shelf/shelf_view_test_api.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/unified/feature_pod_button.h"
#include "ash/test/ash_test_base.h"
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/session_manager/session_manager_types.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/wm/core/window_util.h"
namespace ash {
namespace {
class ShelfTest : public AshTestBase {
public:
ShelfTest() = default;
ShelfTest(const ShelfTest&) = delete;
ShelfTest& operator=(const ShelfTest&) = delete;
~ShelfTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
shelf_view_ = GetPrimaryShelf()->GetShelfViewForTesting();
shelf_model_ = shelf_view_->model();
test_ = std::make_unique<ShelfViewTestAPI>(shelf_view_);
}
ShelfView* shelf_view() { return shelf_view_; }
ShelfModel* shelf_model() { return shelf_model_; }
ShelfViewTestAPI* test_api() { return test_.get(); }
protected:
Shelf* GetSecondaryShelf() {
return Shell::GetRootWindowControllerWithDisplayId(
GetSecondaryDisplay().id())
->shelf();
}
private:
ShelfView* shelf_view_ = nullptr;
ShelfModel* shelf_model_ = nullptr;
std::unique_ptr<ShelfViewTestAPI> test_;
};
// Confirms that ShelfItem reflects the appropriated state.
TEST_F(ShelfTest, StatusReflection) {
// Initially we have the app list.
size_t button_count = test_api()->GetButtonCount();
// Add a running app.
ShelfItem item;
item.id = ShelfID("foo");
item.type = TYPE_APP;
item.status = STATUS_RUNNING;
int index = shelf_model()->Add(
item, std::make_unique<TestShelfItemDelegate>(item.id));
ASSERT_EQ(++button_count, test_api()->GetButtonCount());
ShelfAppButton* button = test_api()->GetButton(index);
EXPECT_EQ(ShelfAppButton::STATE_RUNNING, button->state());
// Remove it.
shelf_model()->RemoveItemAt(index);
ASSERT_EQ(--button_count, test_api()->GetButtonCount());
}
// Confirm that using the menu will clear the hover attribute. To avoid another
// browser test we check this here.
TEST_F(ShelfTest, CheckHoverAfterMenu) {
// Initially we have the app list.
size_t button_count = test_api()->GetButtonCount();
// Add a running app.
ShelfItem item;
item.id = ShelfID("foo");
item.type = TYPE_APP;
item.status = STATUS_RUNNING;
int index = shelf_model()->Add(
item, std::make_unique<TestShelfItemDelegate>(item.id));
ASSERT_EQ(++button_count, test_api()->GetButtonCount());
ShelfAppButton* button = test_api()->GetButton(index);
button->AddState(ShelfAppButton::STATE_HOVERED);
button->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE);
EXPECT_FALSE(button->state() & ShelfAppButton::STATE_HOVERED);
// Remove it.
shelf_model()->RemoveItemAt(index);
}
// Various assertions around auto-hide behavior.
TEST_F(ShelfTest, ToggleAutoHide) {
std::unique_ptr<aura::Window> window =
std::make_unique<aura::Window>(nullptr);
window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
window->SetType(aura::client::WINDOW_TYPE_NORMAL);
window->Init(ui::LAYER_TEXTURED);
ParentWindowInPrimaryRootWindow(window.get());
window->Show();
wm::ActivateWindow(window.get());
Shelf* shelf = GetPrimaryShelf();
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
}
// Tests if shelf is hidden on secondary display after the primary display is
// changed.
TEST_F(ShelfTest, ShelfHiddenOnScreenOnSecondaryDisplay) {
for (const auto& state : {session_manager::SessionState::LOCKED,
session_manager::SessionState::LOGIN_PRIMARY}) {
SCOPED_TRACE(base::StringPrintf("Testing state: %d", state));
GetSessionControllerClient()->SetSessionState(state);
UpdateDisplay("800x600,800x600");
EXPECT_EQ(SHELF_VISIBLE, GetPrimaryShelf()->GetVisibilityState());
EXPECT_EQ(SHELF_HIDDEN, GetSecondaryShelf()->GetVisibilityState());
SwapPrimaryDisplay();
EXPECT_EQ(SHELF_VISIBLE, GetPrimaryShelf()->GetVisibilityState());
EXPECT_EQ(SHELF_HIDDEN, GetSecondaryShelf()->GetVisibilityState());
}
}
using NoSessionShelfTest = NoSessionAshTestBase;
// Regression test for crash in Shelf::SetAlignment(). https://crbug.com/937495
TEST_F(NoSessionShelfTest, SetAlignmentDuringDisplayDisconnect) {
UpdateDisplay("1024x768,800x600");
base::RunLoop().RunUntilIdle();
// The task indirectly triggers Shelf::SetAlignment() via a SessionObserver.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
[](TestSessionControllerClient* session) {
session->SetSessionState(session_manager::SessionState::ACTIVE);
},
GetSessionControllerClient()));
// Remove the secondary display.
UpdateDisplay("1280x1024");
// The session activation task runs before the RootWindowController and the
// Shelf are deleted.
base::RunLoop().RunUntilIdle();
// No crash.
}
class ShelfPartyQsTileTest : public NoSessionAshTestBase {
public:
ShelfPartyQsTileTest() = default;
ShelfPartyQsTileTest(const ShelfPartyQsTileTest&) = delete;
ShelfPartyQsTileTest& operator=(const ShelfPartyQsTileTest&) = delete;
~ShelfPartyQsTileTest() override = default;
// AshTestBase:
void SetUp() override {
AshTestBase::SetUp();
shelf_model_ = GetPrimaryShelf()->GetShelfViewForTesting()->model();
qs_tile_controller_ = std::make_unique<ShelfPartyFeaturePodController>();
qs_tile_button_view_.reset(qs_tile_controller_->CreateButton());
}
void TearDown() override {
qs_tile_controller_.reset();
qs_tile_button_view_.reset();
AshTestBase::TearDown();
}
protected:
ShelfModel* shelf_model() { return shelf_model_; }
ShelfPartyFeaturePodController* qs_tile_controller() {
return qs_tile_controller_.get();
}
FeaturePodButton* qs_tile_button_view() { return qs_tile_button_view_.get(); }
private:
ShelfModel* shelf_model_ = nullptr;
std::unique_ptr<ShelfPartyFeaturePodController> qs_tile_controller_;
std::unique_ptr<FeaturePodButton> qs_tile_button_view_;
};
TEST_F(ShelfPartyQsTileTest, VisibleWhenUserSessionIsActive) {
EXPECT_FALSE(qs_tile_button_view()->GetVisible());
auto* session_controller = GetSessionControllerClient();
session_controller->SetSessionState(session_manager::SessionState::ACTIVE);
EXPECT_TRUE(qs_tile_button_view()->GetVisible());
session_controller->SetSessionState(session_manager::SessionState::LOCKED);
EXPECT_FALSE(qs_tile_button_view()->GetVisible());
}
TEST_F(ShelfPartyQsTileTest, InvisibleWhenEnterpriseManaged) {
auto* session_controller = GetSessionControllerClient();
session_controller->set_is_enterprise_managed(true);
session_controller->SetSessionState(session_manager::SessionState::ACTIVE);
EXPECT_FALSE(qs_tile_button_view()->GetVisible());
}
TEST_F(ShelfPartyQsTileTest, OnIconPressed) {
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
EXPECT_FALSE(shelf_model()->in_shelf_party());
EXPECT_FALSE(qs_tile_button_view()->IsToggled());
qs_tile_controller()->OnIconPressed();
EXPECT_TRUE(shelf_model()->in_shelf_party());
EXPECT_TRUE(qs_tile_button_view()->IsToggled());
qs_tile_controller()->OnIconPressed();
EXPECT_FALSE(shelf_model()->in_shelf_party());
EXPECT_FALSE(qs_tile_button_view()->IsToggled());
}
TEST_F(ShelfPartyQsTileTest, ShelfPartyToggled) {
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
EXPECT_FALSE(shelf_model()->in_shelf_party());
EXPECT_FALSE(qs_tile_button_view()->IsToggled());
shelf_model()->ToggleShelfParty();
EXPECT_TRUE(shelf_model()->in_shelf_party());
EXPECT_TRUE(qs_tile_button_view()->IsToggled());
shelf_model()->ToggleShelfParty();
EXPECT_FALSE(shelf_model()->in_shelf_party());
EXPECT_FALSE(qs_tile_button_view()->IsToggled());
}
} // namespace
} // namespace ash