12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190 |
- // Copyright (c) 2013 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/shelf/shelf_widget.h"
- #include "ash/bubble/bubble_constants.h"
- #include "ash/constants/ash_features.h"
- #include "ash/constants/ash_switches.h"
- #include "ash/keyboard/ui/keyboard_ui_controller.h"
- #include "ash/keyboard/ui/keyboard_util.h"
- #include "ash/keyboard/ui/test/keyboard_test_util.h"
- #include "ash/public/cpp/keyboard/keyboard_switches.h"
- #include "ash/public/cpp/shelf_config.h"
- #include "ash/public/cpp/shelf_types.h"
- #include "ash/public/cpp/tablet_mode.h"
- #include "ash/root_window_controller.h"
- #include "ash/screen_util.h"
- #include "ash/shelf/drag_handle.h"
- #include "ash/shelf/hotseat_transition_animator.h"
- #include "ash/shelf/login_shelf_view.h"
- #include "ash/shelf/shelf.h"
- #include "ash/shelf/shelf_layout_manager.h"
- #include "ash/shelf/shelf_navigation_widget.h"
- #include "ash/shelf/shelf_test_util.h"
- #include "ash/shelf/shelf_view.h"
- #include "ash/shelf/shelf_view_test_api.h"
- #include "ash/shell.h"
- #include "ash/style/dark_light_mode_controller_impl.h"
- #include "ash/system/message_center/unified_message_center_bubble.h"
- #include "ash/system/status_area_widget.h"
- #include "ash/system/unified/unified_system_tray.h"
- #include "ash/system/unified/unified_system_tray_bubble.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/test/ash_test_helper.h"
- #include "ash/test_shell_delegate.h"
- #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
- #include "ash/wm/window_util.h"
- #include "base/callback_helpers.h"
- #include "base/command_line.h"
- #include "base/i18n/rtl.h"
- #include "base/run_loop.h"
- #include "base/test/icu_test_util.h"
- #include "base/test/scoped_feature_list.h"
- #include "chromeos/constants/chromeos_features.h"
- #include "components/session_manager/session_manager_types.h"
- #include "ui/aura/window_event_dispatcher.h"
- #include "ui/base/models/image_model.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/scoped_animation_duration_scale_mode.h"
- #include "ui/display/display.h"
- #include "ui/events/event_utils.h"
- #include "ui/events/test/event_generator.h"
- #include "ui/message_center/message_center.h"
- #include "ui/message_center/public/cpp/notification.h"
- #include "ui/message_center/public/cpp/notification_types.h"
- #include "ui/message_center/public/cpp/notifier_id.h"
- #include "ui/views/view.h"
- #include "ui/views/widget/widget.h"
- #include "url/gurl.h"
- namespace ash {
- namespace {
- ShelfWidget* GetShelfWidget() {
- return AshTestBase::GetPrimaryShelf()->shelf_widget();
- }
- ShelfLayoutManager* GetShelfLayoutManager() {
- return GetShelfWidget()->shelf_layout_manager();
- }
- void TestLauncherAlignment(aura::Window* root,
- ShelfAlignment alignment,
- const gfx::Rect& expected) {
- Shelf::ForWindow(root)->SetAlignment(alignment);
- EXPECT_EQ(expected.ToString(), display::Screen::GetScreen()
- ->GetDisplayNearestWindow(root)
- .work_area()
- .ToString());
- }
- using SessionState = session_manager::SessionState;
- using ShelfWidgetTest = AshTestBase;
- TEST_F(ShelfWidgetTest, TestAlignment) {
- UpdateDisplay("401x400");
- const int bottom_inset = 400 - ShelfConfig::Get()->shelf_size();
- {
- SCOPED_TRACE("Single Bottom");
- TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
- ShelfAlignment::kBottom,
- gfx::Rect(0, 0, 401, bottom_inset));
- }
- {
- SCOPED_TRACE("Single Locked");
- TestLauncherAlignment(Shell::GetPrimaryRootWindow(),
- ShelfAlignment::kBottomLocked,
- gfx::Rect(0, 0, 401, bottom_inset));
- }
- {
- SCOPED_TRACE("Single Right");
- TestLauncherAlignment(Shell::GetPrimaryRootWindow(), ShelfAlignment::kRight,
- gfx::Rect(0, 0, bottom_inset + 1, 400));
- }
- {
- SCOPED_TRACE("Single Left");
- TestLauncherAlignment(
- Shell::GetPrimaryRootWindow(), ShelfAlignment::kLeft,
- gfx::Rect(ShelfConfig::Get()->shelf_size(), 0, bottom_inset + 1, 400));
- }
- }
- TEST_F(ShelfWidgetTest, TestAlignmentForMultipleDisplays) {
- UpdateDisplay("301x300,501x500");
- const int shelf_inset_first = 300 - ShelfConfig::Get()->shelf_size();
- const int shelf_inset_second = 500 - ShelfConfig::Get()->shelf_size();
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- {
- SCOPED_TRACE("Primary Bottom");
- TestLauncherAlignment(root_windows[0], ShelfAlignment::kBottom,
- gfx::Rect(0, 0, 301, shelf_inset_first));
- }
- {
- SCOPED_TRACE("Primary Locked");
- TestLauncherAlignment(root_windows[0], ShelfAlignment::kBottomLocked,
- gfx::Rect(0, 0, 301, shelf_inset_first));
- }
- {
- SCOPED_TRACE("Primary Right");
- TestLauncherAlignment(root_windows[0], ShelfAlignment::kRight,
- gfx::Rect(0, 0, shelf_inset_first + 1, 300));
- }
- {
- SCOPED_TRACE("Primary Left");
- TestLauncherAlignment(root_windows[0], ShelfAlignment::kLeft,
- gfx::Rect(ShelfConfig::Get()->shelf_size(), 0,
- shelf_inset_first + 1, 300));
- }
- {
- SCOPED_TRACE("Secondary Bottom");
- TestLauncherAlignment(root_windows[1], ShelfAlignment::kBottom,
- gfx::Rect(301, 0, 501, shelf_inset_second));
- }
- {
- SCOPED_TRACE("Secondary Locked");
- TestLauncherAlignment(root_windows[1], ShelfAlignment::kBottomLocked,
- gfx::Rect(301, 0, 501, shelf_inset_second));
- }
- {
- SCOPED_TRACE("Secondary Right");
- TestLauncherAlignment(root_windows[1], ShelfAlignment::kRight,
- gfx::Rect(301, 0, shelf_inset_second + 1, 500));
- }
- {
- SCOPED_TRACE("Secondary Left");
- TestLauncherAlignment(root_windows[1], ShelfAlignment::kLeft,
- gfx::Rect(301 + ShelfConfig::Get()->shelf_size(), 0,
- shelf_inset_second + 1, 500));
- }
- }
- class ShelfWidgetDarkLightModeTest : public ShelfWidgetTest {
- public:
- ShelfWidgetDarkLightModeTest() {
- scoped_feature_list_.InitAndEnableFeature(
- chromeos::features::kDarkLightMode);
- }
- void SetUp() override {
- ShelfWidgetTest::SetUp();
- // Enable tablet mode transition screenshots to simulate production behavior
- // where shelf layers get recreated during the tablet mode transition.
- TabletModeController::SetUseScreenshotForTest(true);
- }
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- };
- TEST_F(ShelfWidgetDarkLightModeTest, TabletModeTransition) {
- ShelfWidget* const shelf_widget = GetShelfWidget();
- TabletMode::Waiter enter_waiter(/*enable=*/true);
- TabletModeControllerTestApi().EnterTabletMode();
- enter_waiter.Wait();
- shelf_widget->background_animator_for_testing()
- ->CompleteAnimationForTesting();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent60),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_EQ(0.0, shelf_widget->GetOpaqueBackground()->background_blur());
- auto* dark_light_mode_controller = ash::DarkLightModeControllerImpl::Get();
- dark_light_mode_controller->ToggleColorMode();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent60),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_EQ(0.0f, shelf_widget->GetOpaqueBackground()->background_blur());
- TabletMode::Waiter leave_waiter(/*enable=*/false);
- TabletModeControllerTestApi().LeaveTabletMode();
- leave_waiter.Wait();
- shelf_widget->background_animator_for_testing()
- ->CompleteAnimationForTesting();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent80),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_GT(shelf_widget->GetOpaqueBackground()->background_blur(), 0.0f);
- dark_light_mode_controller->ToggleColorMode();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent80),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_GT(shelf_widget->GetOpaqueBackground()->background_blur(), 0.0f);
- }
- TEST_F(ShelfWidgetDarkLightModeTest, TabletModeTransitionWithWindowOpen) {
- ShelfWidget* const shelf_widget = GetShelfWidget();
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- TabletMode::Waiter enter_waiter(/*enable=*/true);
- TabletModeControllerTestApi().EnterTabletMode();
- enter_waiter.Wait();
- shelf_widget->background_animator_for_testing()
- ->CompleteAnimationForTesting();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kOpaque),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_EQ(0.0f, shelf_widget->GetOpaqueBackground()->background_blur());
- auto* dark_light_mode_controller = ash::DarkLightModeControllerImpl::Get();
- dark_light_mode_controller->ToggleColorMode();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kOpaque),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_EQ(0.0f, shelf_widget->GetOpaqueBackground()->background_blur());
- TabletMode::Waiter leave_waiter(/*enable=*/false);
- TabletModeControllerTestApi().LeaveTabletMode();
- leave_waiter.Wait();
- shelf_widget->background_animator_for_testing()
- ->CompleteAnimationForTesting();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent80),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_GT(shelf_widget->GetOpaqueBackground()->background_blur(), 0.0f);
- dark_light_mode_controller->ToggleColorMode();
- EXPECT_EQ(AshColorProvider::Get()->GetBaseLayerColor(
- AshColorProvider::BaseLayerType::kTransparent80),
- shelf_widget->GetShelfBackgroundColor());
- EXPECT_GT(shelf_widget->GetOpaqueBackground()->background_blur(), 0.0f);
- }
- class ShelfWidgetLayoutBasicsTest
- : public ShelfWidgetTest,
- public testing::WithParamInterface<std::tuple<bool, bool>> {
- public:
- ShelfWidgetLayoutBasicsTest() {
- scoped_feature_list_.InitWithFeatureState(
- features::kHideShelfControlsInTabletMode, std::get<1>(GetParam()));
- }
- ~ShelfWidgetLayoutBasicsTest() override = default;
- void SetUp() override {
- ShelfWidgetTest::SetUp();
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(
- std::get<0>(GetParam()));
- }
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- };
- // First parameter - whether test should run in tablet mode.
- // Second parameter - whether shelf navigation buttons are enabled in tablet
- // mode.
- INSTANTIATE_TEST_SUITE_P(All,
- ShelfWidgetLayoutBasicsTest,
- testing::Combine(testing::Bool(), testing::Bool()));
- // Makes sure the shelf is initially sized correctly in clamshell/tablet.
- TEST_P(ShelfWidgetLayoutBasicsTest, LauncherInitiallySized) {
- ShelfWidget* shelf_widget = GetShelfWidget();
- ShelfLayoutManager* shelf_layout_manager = GetShelfLayoutManager();
- ASSERT_TRUE(shelf_layout_manager);
- ASSERT_TRUE(shelf_widget->status_area_widget());
- int status_width =
- shelf_widget->status_area_widget()->GetWindowBoundsInScreen().width();
- // Test only makes sense if the status is > 0, which it better be.
- EXPECT_GT(status_width, 0);
- const int total_width =
- screen_util::GetDisplayBoundsWithShelf(shelf_widget->GetNativeWindow())
- .width();
- const gfx::Rect nav_widget_clip_rect =
- shelf_widget->navigation_widget()->GetLayer()->clip_rect();
- if (!nav_widget_clip_rect.IsEmpty())
- EXPECT_EQ(gfx::Point(), nav_widget_clip_rect.origin());
- int nav_width =
- nav_widget_clip_rect.IsEmpty()
- ? shelf_widget->navigation_widget()->GetWindowBoundsInScreen().width()
- : nav_widget_clip_rect.width();
- ASSERT_GE(nav_width, 0);
- if (nav_width) {
- nav_width -= ShelfConfig::Get()->control_button_edge_spacing(
- true /* is_primary_axis_edge */);
- }
- const int hotseat_width =
- shelf_widget->hotseat_widget()->GetWindowBoundsInScreen().width();
- const int margins = 2 * ShelfConfig::Get()->GetAppIconGroupMargin();
- EXPECT_EQ(status_width, total_width - nav_width - hotseat_width - margins);
- }
- TEST_F(ShelfWidgetTest, CheckVerticalShelfCornersInOverviewMode) {
- // Verify corners of the shelf on the left alignment.
- Shelf* shelf = GetPrimaryShelf();
- shelf->SetAlignment(ShelfAlignment::kLeft);
- EXPECT_EQ(ShelfAlignment::kLeft, GetPrimaryShelf()->alignment());
- ShelfWidget* const shelf_widget = GetShelfWidget();
- ui::Layer* opaque_background_layer =
- shelf_widget->GetDelegateViewOpaqueBackgroundLayerForTesting();
- // The gfx::RoundedCornersF object is considered empty when all of the
- // corners are squared (no effective radius).
- EXPECT_FALSE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- OverviewController* overview_controller = Shell::Get()->overview_controller();
- // Enter overview mode. Expect the shelf with square corners.
- EnterOverview();
- WaitForOverviewAnimation(/*enter=*/true);
- EXPECT_TRUE(overview_controller->InOverviewSession());
- EXPECT_TRUE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- // Exit overview mode. Expect the shelf with rounded corners.
- ExitOverview();
- WaitForOverviewAnimation(/*enter=*/false);
- EXPECT_FALSE(overview_controller->InOverviewSession());
- EXPECT_FALSE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- // Verify corners of the shelf on the right alignment.
- shelf->SetAlignment(ShelfAlignment::kRight);
- EXPECT_EQ(ShelfAlignment::kRight, GetPrimaryShelf()->alignment());
- EXPECT_FALSE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- // Enter overview mode. Expect the shelf with square corners.
- EnterOverview();
- WaitForOverviewAnimation(/*enter=*/true);
- EXPECT_TRUE(overview_controller->InOverviewSession());
- EXPECT_TRUE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- // Exit overview mode. Expect the shelf with rounded corners.
- ExitOverview();
- WaitForOverviewAnimation(/*enter=*/false);
- EXPECT_FALSE(overview_controller->InOverviewSession());
- EXPECT_FALSE(opaque_background_layer->rounded_corner_radii().IsEmpty());
- }
- // Verifies when the shell is deleted with a full screen window we don't crash.
- TEST_F(ShelfWidgetTest, DontReferenceShelfAfterDeletion) {
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
- params.bounds = gfx::Rect(0, 0, 200, 200);
- params.context = GetContext();
- // Widget is now owned by the parent window.
- widget->Init(std::move(params));
- widget->SetFullscreen(true);
- }
- // Verifies shelf is created with correct size after user login and when its
- // container and status widget has finished sizing.
- // See http://crbug.com/252533
- TEST_F(ShelfWidgetTest, ShelfInitiallySizedAfterLogin) {
- ClearLogin();
- UpdateDisplay("300x200,400x300");
- // Both displays have a shelf controller.
- aura::Window::Windows roots = Shell::GetAllRootWindows();
- Shelf* shelf1 = Shelf::ForWindow(roots[0]);
- Shelf* shelf2 = Shelf::ForWindow(roots[1]);
- ASSERT_TRUE(shelf1);
- ASSERT_TRUE(shelf2);
- // Both shelf controllers have a shelf widget.
- ShelfWidget* shelf_widget1 = shelf1->shelf_widget();
- ShelfWidget* shelf_widget2 = shelf2->shelf_widget();
- ASSERT_TRUE(shelf_widget1);
- ASSERT_TRUE(shelf_widget2);
- // Simulate login.
- CreateUserSessions(1);
- const int total_width1 =
- screen_util::GetDisplayBoundsWithShelf(shelf_widget1->GetNativeWindow())
- .width();
- const int nav_width1 =
- shelf_widget1->navigation_widget()->GetWindowBoundsInScreen().width() -
- ShelfConfig::Get()->control_button_edge_spacing(
- true /* is_primary_axis_edge */);
- const int hotseat_width1 =
- shelf_widget1->hotseat_widget()->GetWindowBoundsInScreen().width();
- const int margins = 2 * ShelfConfig::Get()->GetAppIconGroupMargin();
- const int total_width2 =
- screen_util::GetDisplayBoundsWithShelf(shelf_widget2->GetNativeWindow())
- .width();
- const int nav_width2 =
- shelf_widget2->navigation_widget()->GetWindowBoundsInScreen().width() -
- ShelfConfig::Get()->control_button_edge_spacing(
- true /* is_primary_axis_edge */);
- const int hotseat_width2 =
- shelf_widget2->hotseat_widget()->GetWindowBoundsInScreen().width();
- // The shelf view and status area horizontally fill the shelf widget.
- const int status_width1 =
- shelf_widget1->status_area_widget()->GetWindowBoundsInScreen().width();
- EXPECT_GT(status_width1, 0);
- EXPECT_EQ(total_width1,
- nav_width1 + hotseat_width1 + margins + status_width1);
- const int status_width2 =
- shelf_widget2->status_area_widget()->GetWindowBoundsInScreen().width();
- EXPECT_GT(status_width2, 0);
- EXPECT_EQ(total_width2,
- nav_width2 + hotseat_width2 + margins + status_width2);
- }
- // Tests that the shelf has a slightly larger hit-region for touch-events when
- // it's in the auto-hidden state.
- TEST_F(ShelfWidgetTest, HiddenShelfHitTestTouch) {
- Shelf* shelf = GetPrimaryShelf();
- ShelfWidget* shelf_widget = GetShelfWidget();
- gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(!shelf_bounds.IsEmpty());
- ShelfLayoutManager* shelf_layout_manager =
- shelf_widget->shelf_layout_manager();
- ASSERT_TRUE(shelf_layout_manager);
- EXPECT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
- // Create a widget to make sure that the shelf does auto-hide.
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
- params.bounds = gfx::Rect(0, 0, 200, 200);
- params.context = GetContext();
- // Widget is now owned by the parent window.
- widget->Init(std::move(params));
- widget->Show();
- aura::Window* root = shelf_widget->GetNativeWindow()->GetRootWindow();
- ui::EventTargeter* targeter =
- root->GetHost()->dispatcher()->GetDefaultEventTargeter();
- // Touch just over the shelf. Since the shelf is visible, the window-targeter
- // should not find the shelf as the target.
- {
- gfx::Point event_location(20, shelf_bounds.y() - 1);
- ui::TouchEvent touch(ui::ET_TOUCH_PRESSED, event_location,
- ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::kTouch, 0));
- EXPECT_NE(shelf_widget->GetNativeWindow(),
- targeter->FindTargetForEvent(root, &touch));
- }
- // Now auto-hide (hidden) the shelf.
- shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- shelf_layout_manager->LayoutShelf();
- EXPECT_EQ(SHELF_AUTO_HIDE, shelf_layout_manager->visibility_state());
- EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_layout_manager->auto_hide_state());
- shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(!shelf_bounds.IsEmpty());
- // Touch just over the shelf again. This time, the targeter should find the
- // shelf as the target.
- {
- gfx::Point event_location(20, shelf_bounds.y() - 1);
- ui::TouchEvent touch(ui::ET_TOUCH_PRESSED, event_location,
- ui::EventTimeForNow(),
- ui::PointerDetails(ui::EventPointerType::kTouch, 0));
- EXPECT_EQ(shelf_widget->GetNativeWindow(),
- targeter->FindTargetForEvent(root, &touch));
- }
- }
- class LtrRtlShelfWidgetTest : public ShelfWidgetTest,
- public testing::WithParamInterface<bool> {
- public:
- LtrRtlShelfWidgetTest() : scoped_locale_(GetParam() ? "he" : "") {}
- LtrRtlShelfWidgetTest(const LtrRtlShelfWidgetTest&) = delete;
- LtrRtlShelfWidgetTest& operator=(const LtrRtlShelfWidgetTest&) = delete;
- ~LtrRtlShelfWidgetTest() override = default;
- private:
- // Restores locale to the default when destructor is called.
- base::test::ScopedRestoreICUDefaultLocale scoped_locale_;
- };
- INSTANTIATE_TEST_SUITE_P(All, LtrRtlShelfWidgetTest, testing::Bool());
- TEST_P(LtrRtlShelfWidgetTest, MessageCenterBounds) {
- // Add a notification to force the message center bubble to show with the
- // UnifiedSystemTrayBubble.
- message_center::MessageCenter::Get()->AddNotification(
- std::make_unique<message_center::Notification>(
- message_center::NOTIFICATION_TYPE_SIMPLE, base::NumberToString(0),
- u"test title", u"test message", ui::ImageModel(), std::u16string(),
- GURL(), message_center::NotifierId(),
- message_center::RichNotificationData(),
- new message_center::NotificationDelegate()));
- auto shelf_alignments = {ShelfAlignment::kBottom, ShelfAlignment::kLeft,
- ShelfAlignment::kRight};
- for (const auto& alignment : shelf_alignments) {
- GetPrimaryShelf()->SetAlignment(alignment);
- // Show UnifiedSystemTrayBubble, which shows a message center bubble as well
- // in a separate widget.
- GetPrimaryUnifiedSystemTray()->ShowBubble();
- gfx::Rect message_center_bubble_bounds_in_screen =
- GetPrimaryUnifiedSystemTray()
- ->message_center_bubble()
- ->GetBoundsInScreen();
- gfx::Rect unified_system_tray_bubble_bounds_in_screen =
- GetPrimaryUnifiedSystemTray()->bubble()->GetBoundsInScreen();
- // The MessageCenterBubble and UnifiedSystemTrayBubble should be flush
- // despite the shelf alignment.
- EXPECT_EQ(message_center_bubble_bounds_in_screen.x(),
- unified_system_tray_bubble_bounds_in_screen.x());
- EXPECT_EQ(message_center_bubble_bounds_in_screen.width(),
- unified_system_tray_bubble_bounds_in_screen.width());
- GetPrimaryUnifiedSystemTray()->CloseBubble();
- }
- }
- // Tests that the shelf lets mouse-events close to the edge fall through to the
- // window underneath.
- TEST_F(ShelfWidgetTest, ShelfEdgeOverlappingWindowHitTestMouse) {
- UpdateDisplay("500x400");
- ShelfWidget* shelf_widget = GetShelfWidget();
- gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(!shelf_bounds.IsEmpty());
- ShelfLayoutManager* shelf_layout_manager =
- shelf_widget->shelf_layout_manager();
- ASSERT_TRUE(shelf_layout_manager);
- EXPECT_EQ(SHELF_VISIBLE, shelf_layout_manager->visibility_state());
- // Create a Widget which overlaps the shelf in both left and bottom
- // alignments.
- const int kOverlapSize = 15;
- const int kWindowHeight = 200;
- const int kWindowWidth = 200;
- const gfx::Rect bounds(shelf_bounds.height() - kOverlapSize,
- shelf_bounds.y() - kWindowHeight + kOverlapSize,
- kWindowWidth, kWindowHeight);
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
- params.bounds = bounds;
- params.context = GetContext();
- // Widget is now owned by the parent window.
- widget->Init(std::move(params));
- // Explicitly set the bounds which will allow the widget to overlap the shelf.
- widget->SetBounds(bounds);
- widget->Show();
- gfx::Rect widget_bounds = widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(widget_bounds.Intersects(shelf_bounds));
- aura::Window* root = widget->GetNativeWindow()->GetRootWindow();
- ui::EventTargeter* targeter =
- root->GetHost()->dispatcher()->GetDefaultEventTargeter();
- {
- // Create a mouse-event targeting the top of the shelf widget. The
- // window-targeter should find |widget| as the target (instead of the
- // shelf).
- gfx::Point event_location(widget_bounds.x() + 5, shelf_bounds.y() + 1);
- ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
- ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
- ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
- EXPECT_EQ(widget->GetNativeWindow(), target);
- }
- // Change shelf alignment to verify that the targeter insets are updated.
- Shelf* shelf = GetPrimaryShelf();
- shelf->SetAlignment(ShelfAlignment::kLeft);
- shelf_layout_manager->LayoutShelf();
- shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- {
- // Create a mouse-event targeting the right edge of the shelf widget. The
- // window-targeter should find |widget| as the target (instead of the
- // shelf).
- gfx::Point event_location(shelf_bounds.right() - 1, widget_bounds.y() + 5);
- ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
- ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
- ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
- EXPECT_EQ(widget->GetNativeWindow(), target);
- }
- // Now restore shelf alignment (bottom) and auto-hide (hidden) the shelf.
- shelf->SetAlignment(ShelfAlignment::kBottom);
- shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- shelf_layout_manager->LayoutShelf();
- EXPECT_EQ(SHELF_AUTO_HIDE, shelf_layout_manager->visibility_state());
- EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_layout_manager->auto_hide_state());
- shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(!shelf_bounds.IsEmpty());
- // Move |widget| so it still overlaps the shelf.
- widget->SetBounds(gfx::Rect(0,
- shelf_bounds.y() - kWindowHeight + kOverlapSize,
- kWindowWidth, kWindowHeight));
- widget_bounds = widget->GetWindowBoundsInScreen();
- EXPECT_TRUE(widget_bounds.Intersects(shelf_bounds));
- {
- // Create a mouse-event targeting the top of the shelf widget. This time,
- // window-target should find the shelf as the target.
- gfx::Point event_location(widget_bounds.x() + 5, shelf_bounds.y() + 1);
- ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
- ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
- ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
- EXPECT_EQ(shelf_widget->GetNativeWindow(), target);
- }
- }
- class TransitionAnimationWaiter
- : public HotseatTransitionAnimator::TestObserver {
- public:
- explicit TransitionAnimationWaiter(
- HotseatTransitionAnimator* hotseat_transition_animator)
- : hotseat_transition_animator_(hotseat_transition_animator) {
- hotseat_transition_animator_->SetTestObserver(this);
- }
- ~TransitionAnimationWaiter() override {
- hotseat_transition_animator_->SetTestObserver(nullptr);
- }
- void Wait() {
- run_loop_ = std::make_unique<base::RunLoop>();
- run_loop_->Run();
- }
- private:
- void OnTransitionTestAnimationEnded() override {
- DCHECK(run_loop_.get());
- run_loop_->Quit();
- }
- HotseatTransitionAnimator* hotseat_transition_animator_ = nullptr;
- std::unique_ptr<base::RunLoop> run_loop_;
- };
- // Tests the drag handle bounds and visibility when the in-app shelf is shown.
- TEST_F(ShelfWidgetTest, OpaqueBackgroundAndDragHandleTransition) {
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- UpdateDisplay("800x700");
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- // Create a window to transition to the in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- {
- TransitionAnimationWaiter waiter(
- GetShelfWidget()->hotseat_transition_animator());
- waiter.Wait();
- }
- // Ensure the ShelfWidget and drag handle have the correct bounds and
- // visibility for in-app shelf.
- EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
- gfx::Rect(0, 660, 800, 40));
- EXPECT_EQ(GetShelfWidget()->GetDragHandle()->bounds(),
- gfx::Rect(360, 18, 80, 4));
- ASSERT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- window->Hide();
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- }
- // Tests the shelf widget does not animate for hotseat transitions during tablet
- // mode start.
- TEST_F(ShelfWidgetTest, NoAnimatingBackgroundDuringTabletModeStartToInApp) {
- UpdateDisplay("800x700");
- // Create a window so tablet mode uses in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- }
- // Tests the shelf widget does not animate for hotseat transitions during tablet
- // mode end.
- TEST_F(ShelfWidgetTest, NoAnimatingBackgroundDuringTabletModeEndFromInApp) {
- UpdateDisplay("800x700");
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- // Create a window so tablet mode uses in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- }
- // Tests the shelf widget does not animate for hotseat transitions during tablet
- // mode start with no app windows.
- TEST_F(ShelfWidgetTest, NoAnimatingBackgroundDuringTabletModeStartToHome) {
- UpdateDisplay("800x700");
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- }
- // Tests the shelf widget does not animate for hotseat transitions during tablet
- // mode end with no app windows.
- TEST_F(ShelfWidgetTest, NoAnimatingBackgroundDuringTabletModeEndFromHome) {
- UpdateDisplay("800x700");
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- EXPECT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- EXPECT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- EXPECT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- }
- // Tests the shelf widget does not animate for hotseat transitions if the screen
- // is locked.
- TEST_F(ShelfWidgetTest, NoAnimatingBackgroundOnLockScreen) {
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- UpdateDisplay("800x700");
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- // Create a window to transition to the in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- // At this point animations have zero duration, so the transition happens
- // immediately.
- ASSERT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- GetSessionControllerClient()->SetSessionState(SessionState::LOCKED);
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- // Hide the test window, and verify that does not start shelf animation.
- window->Hide();
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- // Ensure the ShelfWidget and the drag handle are still hidden (i.e. in home
- // screen state) when the screen is unlocked.
- GetSessionControllerClient()->SetSessionState(SessionState::ACTIVE);
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- }
- // Tests the shelf widget animations for hotseat transitions are stopped when
- // the screen is locked.
- TEST_F(ShelfWidgetTest, ScreenLockStopsHotseatTransitionAnimation) {
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- UpdateDisplay("800x700");
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- // Create a window to transition to the in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- GetSessionControllerClient()->SetSessionState(SessionState::LOCKED);
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- GetSessionControllerClient()->SetSessionState(SessionState::ACTIVE);
- // Ensure the ShelfWidget and the drag handle have the correct bounds and
- // visibility for in-app shelf when the screen is unlocked.
- ASSERT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- EXPECT_EQ(GetShelfWidget()->GetWindowBoundsInScreen(),
- gfx::Rect(0, 660, 800, 40));
- EXPECT_EQ(GetShelfWidget()->GetDragHandle()->bounds(),
- gfx::Rect(360, 18, 80, 4));
- }
- // Tests the shelf widget's opaque background gets reshown if hotseat transition
- // from kShown state gets interrupted by a transition back to kShown state.
- TEST_F(ShelfWidgetTest,
- OpaqueBackgroundReshownAfterTransitionFromHomeChangesBackToHome) {
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- UpdateDisplay("800x700");
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- // Create a window to transition to the in-app shelf.
- auto window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- const gfx::Rect animating_background_bounds =
- GetShelfWidget()->GetAnimatingBackground()->bounds();
- EXPECT_NE(GetShelfWidget()->GetAnimatingBackground()->transform(),
- GetShelfWidget()->GetAnimatingBackground()->GetTargetTransform());
- // Go back home before the transition to in-app shelf finishes.
- window->Hide();
- // The shelf background should still be animating at this point, but to
- // different bounds.
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()->GetAnimatingBackground()->visible());
- ASSERT_TRUE(GetShelfWidget()
- ->GetAnimatingBackground()
- ->GetAnimator()
- ->is_animating());
- EXPECT_EQ(animating_background_bounds,
- GetShelfWidget()->GetAnimatingBackground()->bounds());
- // The original animation did not have a chance to update the transform yet,
- // so the current transform matches the original state, that matches the new
- // target state.
- EXPECT_EQ(GetShelfWidget()->GetAnimatingBackground()->transform(),
- GetShelfWidget()->GetAnimatingBackground()->GetTargetTransform());
- // Run the current animation to the end, end verify the opaque background is
- // reshown after ending tablet mode.
- GetShelfWidget()->GetAnimatingBackground()->GetAnimator()->StopAnimating();
- ASSERT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- ASSERT_TRUE(GetShelfWidget()->GetOpaqueBackground()->visible());
- ASSERT_FALSE(GetShelfWidget()->GetAnimatingBackground()->visible());
- }
- class ShelfWidgetAfterLoginTest : public AshTestBase {
- public:
- ShelfWidgetAfterLoginTest() { set_start_session(false); }
- ShelfWidgetAfterLoginTest(const ShelfWidgetAfterLoginTest&) = delete;
- ShelfWidgetAfterLoginTest& operator=(const ShelfWidgetAfterLoginTest&) =
- delete;
- ~ShelfWidgetAfterLoginTest() override = default;
- void TestShelf(ShelfAlignment alignment,
- ShelfAutoHideBehavior auto_hide_behavior,
- ShelfVisibilityState expected_shelf_visibility_state,
- ShelfAutoHideState expected_shelf_auto_hide_state) {
- // Simulate login.
- CreateUserSessions(1);
- // Simulate shelf settings being applied from profile prefs.
- Shelf* shelf = GetPrimaryShelf();
- ASSERT_NE(nullptr, shelf);
- shelf->SetAlignment(alignment);
- shelf->SetAutoHideBehavior(auto_hide_behavior);
- shelf->UpdateVisibilityState();
- // Ensure settings are applied correctly.
- EXPECT_EQ(alignment, shelf->alignment());
- EXPECT_EQ(auto_hide_behavior, shelf->auto_hide_behavior());
- EXPECT_EQ(expected_shelf_visibility_state, shelf->GetVisibilityState());
- EXPECT_EQ(expected_shelf_auto_hide_state, shelf->GetAutoHideState());
- }
- };
- TEST_F(ShelfWidgetAfterLoginTest, InitialValues) {
- // Ensure shelf components are created.
- Shelf* shelf = GetPrimaryShelf();
- ASSERT_NE(nullptr, shelf);
- ShelfWidget* shelf_widget = GetShelfWidget();
- ASSERT_NE(nullptr, shelf_widget);
- ASSERT_NE(nullptr, shelf_widget->shelf_view_for_testing());
- ASSERT_NE(nullptr, shelf_widget->GetLoginShelfView());
- ASSERT_NE(nullptr, shelf_widget->shelf_layout_manager());
- // Ensure settings are correct before login.
- EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
- EXPECT_EQ(ShelfAlignment::kBottomLocked, shelf->alignment());
- EXPECT_EQ(ShelfAutoHideBehavior::kAlwaysHidden, shelf->auto_hide_behavior());
- EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
- // Simulate login.
- CreateUserSessions(1);
- // Ensure settings are correct after login.
- EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
- EXPECT_EQ(ShelfAlignment::kBottom, shelf->alignment());
- EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
- // "Hidden" is the default state when auto-hide is turned off.
- EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
- }
- TEST_F(ShelfWidgetAfterLoginTest, CreateAutoHideAlwaysShelf) {
- // The actual auto hide state is shown because there are no open windows.
- TestShelf(ShelfAlignment::kBottom, ShelfAutoHideBehavior::kAlways,
- SHELF_AUTO_HIDE, SHELF_AUTO_HIDE_SHOWN);
- }
- TEST_F(ShelfWidgetAfterLoginTest, CreateAutoHideNeverShelf) {
- // The auto hide state 'HIDDEN' is returned for any non-auto-hide behavior.
- TestShelf(ShelfAlignment::kLeft, ShelfAutoHideBehavior::kNever, SHELF_VISIBLE,
- SHELF_AUTO_HIDE_HIDDEN);
- }
- TEST_F(ShelfWidgetAfterLoginTest, CreateAutoHideAlwaysHideShelf) {
- // The auto hide state 'HIDDEN' is returned for any non-auto-hide behavior.
- TestShelf(ShelfAlignment::kRight, ShelfAutoHideBehavior::kAlwaysHidden,
- SHELF_HIDDEN, SHELF_AUTO_HIDE_HIDDEN);
- }
- TEST_F(ShelfWidgetAfterLoginTest, CreateLockedShelf) {
- // The auto hide state 'HIDDEN' is returned for any non-auto-hide behavior.
- TestShelf(ShelfAlignment::kBottomLocked, ShelfAutoHideBehavior::kNever,
- SHELF_VISIBLE, SHELF_AUTO_HIDE_HIDDEN);
- }
- class ShelfWidgetViewsVisibilityTest : public AshTestBase {
- public:
- ShelfWidgetViewsVisibilityTest() { set_start_session(false); }
- ShelfWidgetViewsVisibilityTest(const ShelfWidgetViewsVisibilityTest&) =
- delete;
- ShelfWidgetViewsVisibilityTest& operator=(
- const ShelfWidgetViewsVisibilityTest&) = delete;
- ~ShelfWidgetViewsVisibilityTest() override = default;
- enum ShelfVisibility {
- kNone, // Shelf views hidden.
- kShelf, // ShelfView visible.
- kLoginShelf, // LoginShelfView visible.
- };
- void InitShelfVariables() {
- // Create setup with 2 displays primary and secondary.
- UpdateDisplay("800x600,800x600");
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- ASSERT_EQ(2u, root_windows.size());
- primary_shelf_widget_ = Shelf::ForWindow(root_windows[0])->shelf_widget();
- ASSERT_NE(nullptr, primary_shelf_widget_);
- secondary_shelf_widget_ = Shelf::ForWindow(root_windows[1])->shelf_widget();
- ASSERT_NE(nullptr, secondary_shelf_widget_);
- }
- void ExpectVisible(session_manager::SessionState state,
- ShelfVisibility primary_shelf_visibility,
- ShelfVisibility secondary_shelf_visibility) {
- GetSessionControllerClient()->SetSessionState(state);
- EXPECT_EQ(primary_shelf_visibility == kNone,
- !primary_shelf_widget_->IsVisible());
- if (primary_shelf_visibility != kNone) {
- EXPECT_EQ(primary_shelf_visibility == kLoginShelf,
- primary_shelf_widget_->GetLoginShelfView()->GetVisible());
- EXPECT_EQ(primary_shelf_visibility == kShelf,
- primary_shelf_widget_->shelf_view_for_testing()->GetVisible());
- }
- EXPECT_EQ(secondary_shelf_visibility == kNone,
- !secondary_shelf_widget_->IsVisible());
- if (secondary_shelf_visibility != kNone) {
- EXPECT_EQ(secondary_shelf_visibility == kLoginShelf,
- secondary_shelf_widget_->GetLoginShelfView()->GetVisible());
- EXPECT_EQ(
- secondary_shelf_visibility == kShelf,
- secondary_shelf_widget_->shelf_view_for_testing()->GetVisible());
- }
- }
- private:
- ShelfWidget* primary_shelf_widget_ = nullptr;
- ShelfWidget* secondary_shelf_widget_ = nullptr;
- };
- TEST_F(ShelfWidgetViewsVisibilityTest, LoginViewsLockViews) {
- ASSERT_NO_FATAL_FAILURE(InitShelfVariables());
- ExpectVisible(SessionState::UNKNOWN, kNone /*primary*/, kNone /*secondary*/);
- ExpectVisible(SessionState::OOBE, kLoginShelf, kNone);
- ExpectVisible(SessionState::LOGIN_PRIMARY, kLoginShelf, kNone);
- SimulateUserLogin("user1@test.com");
- ExpectVisible(SessionState::LOGGED_IN_NOT_ACTIVE, kLoginShelf, kNone);
- ExpectVisible(SessionState::ACTIVE, kShelf, kShelf);
- ExpectVisible(SessionState::LOCKED, kLoginShelf, kNone);
- ExpectVisible(SessionState::ACTIVE, kShelf, kShelf);
- ExpectVisible(SessionState::LOGIN_SECONDARY, kLoginShelf, kNone);
- ExpectVisible(SessionState::ACTIVE, kShelf, kShelf);
- }
- class ShelfWidgetVirtualKeyboardTest : public AshTestBase {
- protected:
- void SetUp() override {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- keyboard::switches::kEnableVirtualKeyboard);
- AshTestBase::SetUp();
- ASSERT_TRUE(keyboard::IsKeyboardEnabled());
- keyboard::test::WaitUntilLoaded();
- // These tests only apply to the floating virtual keyboard, as it is the
- // only case where both the virtual keyboard and the shelf are visible.
- const gfx::Rect keyboard_bounds(0, 0, 1, 1);
- keyboard_ui_controller()->SetContainerType(
- keyboard::ContainerType::kFloating, keyboard_bounds, base::DoNothing());
- }
- keyboard::KeyboardUIController* keyboard_ui_controller() {
- return keyboard::KeyboardUIController::Get();
- }
- };
- TEST_F(ShelfWidgetVirtualKeyboardTest, ClickingHidesVirtualKeyboard) {
- keyboard_ui_controller()->ShowKeyboard(false /* locked */);
- ASSERT_TRUE(keyboard::WaitUntilShown());
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->set_current_screen_location(
- GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint());
- generator->ClickLeftButton();
- // Times out if test fails.
- ASSERT_TRUE(keyboard::WaitUntilHidden());
- }
- TEST_F(ShelfWidgetVirtualKeyboardTest, TappingHidesVirtualKeyboard) {
- keyboard_ui_controller()->ShowKeyboard(false /* locked */);
- ASSERT_TRUE(keyboard::WaitUntilShown());
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->set_current_screen_location(
- GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint());
- generator->PressTouch();
- // Times out if test fails.
- ASSERT_TRUE(keyboard::WaitUntilHidden());
- }
- TEST_F(ShelfWidgetVirtualKeyboardTest, DoesNotHideLockedVirtualKeyboard) {
- keyboard_ui_controller()->ShowKeyboard(true /* locked */);
- ASSERT_TRUE(keyboard::WaitUntilShown());
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->set_current_screen_location(
- GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint());
- generator->ClickLeftButton();
- EXPECT_FALSE(keyboard::IsKeyboardHiding());
- generator->PressTouch();
- EXPECT_FALSE(keyboard::IsKeyboardHiding());
- }
- } // namespace
- } // namespace ash
|