| // Copyright 2018 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/detachable_base/detachable_base_notification_controller.h" |
| |
| #include <string> |
| |
| #include "ash/detachable_base/detachable_base_handler.h" |
| #include "ash/public/cpp/session/user_info.h" |
| #include "ash/session/session_controller_impl.h" |
| #include "ash/session/test_session_controller_client.h" |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "base/time/time.h" |
| #include "chromeos/dbus/power/fake_power_manager_client.h" |
| #include "components/account_id/account_id.h" |
| #include "components/user_manager/user_type.h" |
| #include "ui/message_center/message_center.h" |
| |
| namespace ash { |
| |
| UserInfo CreateTestUserInfo(const std::string& user_email) { |
| UserInfo user_info; |
| user_info.type = user_manager::UserType::kRegular; |
| user_info.account_id = AccountId::FromUserEmail(user_email); |
| user_info.display_name = "Test user"; |
| user_info.display_email = user_email; |
| user_info.is_ephemeral = false; |
| user_info.is_new_profile = false; |
| return user_info; |
| } |
| |
| class DetachableBaseNotificationControllerTest : public NoSessionAshTestBase { |
| public: |
| DetachableBaseNotificationControllerTest() = default; |
| |
| DetachableBaseNotificationControllerTest( |
| const DetachableBaseNotificationControllerTest&) = delete; |
| DetachableBaseNotificationControllerTest& operator=( |
| const DetachableBaseNotificationControllerTest&) = delete; |
| |
| ~DetachableBaseNotificationControllerTest() override = default; |
| |
| void SetUp() override { |
| AshTestBase::SetUp(); |
| |
| chromeos::FakePowerManagerClient::Get()->SetTabletMode( |
| chromeos::PowerManagerClient::TabletMode::OFF, base::TimeTicks()); |
| } |
| |
| bool IsBaseChangedNotificationVisible() { |
| return message_center::MessageCenter::Get()->FindVisibleNotificationById( |
| DetachableBaseNotificationController::kBaseChangedNotificationId); |
| } |
| |
| bool IsBaseRequiresUpdateNotificationVisible() { |
| return message_center::MessageCenter::Get()->FindVisibleNotificationById( |
| DetachableBaseNotificationController:: |
| kBaseRequiresUpdateNotificationId); |
| } |
| |
| void CloseBaseChangedNotification() { |
| message_center::MessageCenter::Get()->RemoveNotification( |
| DetachableBaseNotificationController::kBaseChangedNotificationId, |
| true /*by_user*/); |
| } |
| |
| DetachableBaseHandler* detachable_base_handler() { |
| return Shell::Get()->detachable_base_handler(); |
| } |
| |
| SessionControllerImpl* session_controller() { |
| return Shell::Get()->session_controller(); |
| } |
| }; |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| ShowPairingNotificationIfSessionNotBlocked) { |
| CreateUserSessions(1); |
| |
| // The first detachable base used by the user - no notification expected. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| // If the user changes the paired base in session, the detachable base change |
| // notification should be shown. |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| |
| CloseBaseChangedNotification(); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| // Verify that the notification is reshown if the base changes again. |
| detachable_base_handler()->PairChallengeSucceeded({0x03, 0x03}); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| ShowNotificationOnNonAuthenticatedBases) { |
| CreateUserSessions(1); |
| |
| detachable_base_handler()->PairChallengeFailed(); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| UpdateNotificationOnUserSwitch) { |
| CreateUserSessions(1); |
| |
| // The first detachable base used by the user - no notification expected. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| SimulateUserLogin("secondary_user@test.com"); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| CloseBaseChangedNotification(); |
| |
| GetSessionControllerClient()->SwitchActiveUser( |
| session_controller()->GetUserSession(1)->user_info.account_id); |
| |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NonAuthenticatedBaseNotificationOnUserSwitch) { |
| CreateUserSessions(1); |
| |
| detachable_base_handler()->PairChallengeFailed(); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| CloseBaseChangedNotification(); |
| |
| SimulateUserLogin("secondary_user@test.com"); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NoNotificationIfSessionNotStarted) { |
| const char kTestUser[] = "user_1@test.com"; |
| UserInfo test_user_info = CreateTestUserInfo(kTestUser); |
| // Set a detachable base as previously used by the user before log in. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| EXPECT_TRUE( |
| detachable_base_handler()->SetPairedBaseAsLastUsedByUser(test_user_info)); |
| |
| // Set up another detachable base as attached when the user logs in. |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| // No active user, so the notification should not be shown, yet. |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| SimulateUserLogin(kTestUser); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NoNotificationOnSessionStartIfBaseMarkedAsLastUsed) { |
| const char kTestUser[] = "user_1@test.com"; |
| UserInfo test_user_info = CreateTestUserInfo(kTestUser); |
| // Set a detachable base as previously used by the user before log in. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| EXPECT_TRUE( |
| detachable_base_handler()->SetPairedBaseAsLastUsedByUser(test_user_info)); |
| |
| // Set up another detachable base as attached when the user logs in. |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| // No active user, so the notification should not be shown, yet. |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| // Mark the current device as last used by the user, and verify there is no |
| // notification when the user logs in. |
| EXPECT_TRUE( |
| detachable_base_handler()->SetPairedBaseAsLastUsedByUser(test_user_info)); |
| SimulateUserLogin(kTestUser); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| } |
| |
| // Tests that a notification for non authenticated base is not shown before the |
| // session is started - the login UI will show a custom UI to inform the user |
| // about the base. |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NonAuthenticatedBaseNotificationNotShownBeforeLogin) { |
| detachable_base_handler()->PairChallengeFailed(); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| CreateUserSessions(1); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, NoNotificationOnLockScreen) { |
| CreateUserSessions(1); |
| // The first detachable base used by the user - no notification expected. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| |
| BlockUserSession(UserSessionBlockReason::BLOCKED_BY_LOCK_SCREEN); |
| |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| UnblockUserSession(); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NoNotificationAfterLockScreenIfSetAsUsed) { |
| CreateUserSessions(1); |
| // The first detachable base used by the user - no notification expected. |
| detachable_base_handler()->PairChallengeSucceeded({0x01, 0x01}); |
| BlockUserSession(UserSessionBlockReason::BLOCKED_BY_LOCK_SCREEN); |
| |
| detachable_base_handler()->PairChallengeSucceeded({0x02, 0x02}); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| EXPECT_TRUE(detachable_base_handler()->SetPairedBaseAsLastUsedByUser( |
| session_controller()->GetUserSession(0)->user_info)); |
| |
| UnblockUserSession(); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| } |
| |
| // Tests that a notification for non authenticated base is not shown before the |
| // session is started - the lock UI will show a custom UI to inform the user |
| // about the base. |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NonAuthenticatedBaseNotificationNotShownOnLock) { |
| BlockUserSession(UserSessionBlockReason::BLOCKED_BY_LOCK_SCREEN); |
| detachable_base_handler()->PairChallengeFailed(); |
| EXPECT_FALSE(IsBaseChangedNotificationVisible()); |
| |
| UnblockUserSession(); |
| EXPECT_TRUE(IsBaseChangedNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, NotificationOnUpdateRequired) { |
| CreateUserSessions(1); |
| |
| detachable_base_handler()->BaseFirmwareUpdateNeeded(); |
| EXPECT_TRUE(IsBaseRequiresUpdateNotificationVisible()); |
| |
| // The notification should be removed when the base gets detached. |
| chromeos::FakePowerManagerClient::Get()->SetTabletMode( |
| chromeos::PowerManagerClient::TabletMode::ON, base::TimeTicks()); |
| EXPECT_FALSE(IsBaseRequiresUpdateNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NotificationOnUpdateRequiredBeforeLogin) { |
| // Update requirement detected before login - expect the update required |
| // notification to be hidden. |
| detachable_base_handler()->BaseFirmwareUpdateNeeded(); |
| EXPECT_FALSE(IsBaseRequiresUpdateNotificationVisible()); |
| |
| // Login, expect the notification to be shown. |
| CreateUserSessions(1); |
| EXPECT_TRUE(IsBaseRequiresUpdateNotificationVisible()); |
| |
| // The notification should be removed when the base gets detached. |
| chromeos::FakePowerManagerClient::Get()->SetTabletMode( |
| chromeos::PowerManagerClient::TabletMode::ON, base::TimeTicks()); |
| EXPECT_FALSE(IsBaseRequiresUpdateNotificationVisible()); |
| } |
| |
| TEST_F(DetachableBaseNotificationControllerTest, |
| NotificationOnUpdateRequiredOnLockScreen) { |
| // Update requirement detected while the session is blocked by the lock |
| // screen - expect the update required notification to be shown. |
| BlockUserSession(UserSessionBlockReason::BLOCKED_BY_LOCK_SCREEN); |
| |
| detachable_base_handler()->BaseFirmwareUpdateNeeded(); |
| EXPECT_TRUE(IsBaseRequiresUpdateNotificationVisible()); |
| |
| // The notification should be removed when the base gets detached. |
| chromeos::FakePowerManagerClient::Get()->SetTabletMode( |
| chromeos::PowerManagerClient::TabletMode::ON, base::TimeTicks()); |
| EXPECT_FALSE(IsBaseRequiresUpdateNotificationVisible()); |
| } |
| |
| } // namespace ash |