123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- // Copyright 2014 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/components/proximity_auth/proximity_auth_system.h"
- #include <memory>
- #include "ash/components/multidevice/logging/logging.h"
- #include "ash/components/multidevice/remote_device_ref.h"
- #include "ash/components/multidevice/remote_device_test_util.h"
- #include "ash/components/multidevice/software_feature_state.h"
- #include "ash/components/proximity_auth/fake_lock_handler.h"
- #include "ash/components/proximity_auth/fake_remote_device_life_cycle.h"
- #include "ash/components/proximity_auth/mock_proximity_auth_client.h"
- #include "ash/components/proximity_auth/proximity_auth_profile_pref_manager.h"
- #include "ash/components/proximity_auth/unlock_manager.h"
- #include "ash/constants/ash_features.h"
- #include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
- #include "ash/services/secure_channel/public/cpp/client/fake_secure_channel_client.h"
- #include "base/command_line.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/test_simple_task_runner.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using testing::_;
- using testing::AnyNumber;
- using testing::AtLeast;
- using testing::InSequence;
- using testing::NiceMock;
- using testing::NotNull;
- using testing::Return;
- using testing::SaveArg;
- namespace proximity_auth {
- namespace {
- const char kUser1[] = "user1";
- const char kUser2[] = "user2";
- void CompareRemoteDeviceRefLists(
- const ash::multidevice::RemoteDeviceRefList& list1,
- const ash::multidevice::RemoteDeviceRefList& list2) {
- ASSERT_EQ(list1.size(), list2.size());
- for (size_t i = 0; i < list1.size(); ++i) {
- ash::multidevice::RemoteDeviceRef device1 = list1[i];
- ash::multidevice::RemoteDeviceRef device2 = list2[i];
- EXPECT_EQ(device1.public_key(), device2.public_key());
- }
- }
- // Creates a RemoteDeviceRef object for |user_id| with |name|.
- ash::multidevice::RemoteDeviceRef CreateRemoteDevice(
- const std::string& user_email,
- const std::string& name) {
- return ash::multidevice::RemoteDeviceRefBuilder()
- .SetUserEmail(user_email)
- .SetName(name)
- .Build();
- }
- // Mock implementation of UnlockManager.
- class MockUnlockManager : public UnlockManager {
- public:
- MockUnlockManager() {}
- MockUnlockManager(const MockUnlockManager&) = delete;
- MockUnlockManager& operator=(const MockUnlockManager&) = delete;
- ~MockUnlockManager() override {}
- MOCK_METHOD0(IsUnlockAllowed, bool());
- MOCK_METHOD1(SetRemoteDeviceLifeCycle, void(RemoteDeviceLifeCycle*));
- MOCK_METHOD1(OnAuthAttempted, void(mojom::AuthType));
- MOCK_METHOD0(CancelConnectionAttempt, void());
- MOCK_METHOD0(GetLastRemoteStatusUnlockForLogging, std::string());
- };
- // Mock implementation of ProximityAuthProfilePrefManager.
- class MockProximityAuthPrefManager : public ProximityAuthProfilePrefManager {
- public:
- MockProximityAuthPrefManager(
- ash::multidevice_setup::FakeMultiDeviceSetupClient*
- fake_multidevice_setup_client)
- : ProximityAuthProfilePrefManager(nullptr,
- fake_multidevice_setup_client) {}
- MockProximityAuthPrefManager(const MockProximityAuthPrefManager&) = delete;
- MockProximityAuthPrefManager& operator=(const MockProximityAuthPrefManager&) =
- delete;
- ~MockProximityAuthPrefManager() override {}
- MOCK_CONST_METHOD0(GetLastPasswordEntryTimestampMs, int64_t());
- };
- // Harness for ProximityAuthSystem to make it testable.
- class TestableProximityAuthSystem : public ProximityAuthSystem {
- public:
- TestableProximityAuthSystem(
- ash::secure_channel::SecureChannelClient* secure_channel_client,
- std::unique_ptr<UnlockManager> unlock_manager,
- ProximityAuthPrefManager* pref_manager)
- : ProximityAuthSystem(secure_channel_client, std::move(unlock_manager)),
- life_cycle_(nullptr) {}
- TestableProximityAuthSystem(const TestableProximityAuthSystem&) = delete;
- TestableProximityAuthSystem& operator=(const TestableProximityAuthSystem&) =
- delete;
- ~TestableProximityAuthSystem() override {}
- FakeRemoteDeviceLifeCycle* life_cycle() { return life_cycle_; }
- private:
- std::unique_ptr<RemoteDeviceLifeCycle> CreateRemoteDeviceLifeCycle(
- ash::multidevice::RemoteDeviceRef remote_device,
- absl::optional<ash::multidevice::RemoteDeviceRef> local_device) override {
- std::unique_ptr<FakeRemoteDeviceLifeCycle> life_cycle(
- new FakeRemoteDeviceLifeCycle(remote_device, local_device));
- life_cycle_ = life_cycle.get();
- return life_cycle;
- }
- FakeRemoteDeviceLifeCycle* life_cycle_;
- };
- } // namespace
- class ProximityAuthSystemTest : public testing::Test {
- public:
- ProximityAuthSystemTest(const ProximityAuthSystemTest&) = delete;
- ProximityAuthSystemTest& operator=(const ProximityAuthSystemTest&) = delete;
- protected:
- ProximityAuthSystemTest()
- : user1_local_device_(CreateRemoteDevice(kUser1, "user1_local_device")),
- user2_local_device_(CreateRemoteDevice(kUser2, "user2_local_device")),
- task_runner_(new base::TestSimpleTaskRunner()),
- thread_task_runner_handle_(task_runner_) {}
- void TearDown() override {
- UnlockScreen();
- pref_manager_.reset();
- }
- void SetUp() override {
- fake_multidevice_setup_client_ =
- std::make_unique<ash::multidevice_setup::FakeMultiDeviceSetupClient>();
- pref_manager_ = std::make_unique<NiceMock<MockProximityAuthPrefManager>>(
- fake_multidevice_setup_client_.get());
- user1_remote_devices_.push_back(
- CreateRemoteDevice(kUser1, "user1_device1"));
- user1_remote_devices_.push_back(
- CreateRemoteDevice(kUser1, "user1_device2"));
- user2_remote_devices_.push_back(
- CreateRemoteDevice(kUser2, "user2_device1"));
- user2_remote_devices_.push_back(
- CreateRemoteDevice(kUser2, "user2_device2"));
- user2_remote_devices_.push_back(
- CreateRemoteDevice(kUser2, "user2_device3"));
- std::unique_ptr<MockUnlockManager> unlock_manager(
- new NiceMock<MockUnlockManager>());
- unlock_manager_ = unlock_manager.get();
- fake_secure_channel_client_ =
- std::make_unique<ash::secure_channel::FakeSecureChannelClient>();
- proximity_auth_system_ = std::make_unique<TestableProximityAuthSystem>(
- fake_secure_channel_client_.get(), std::move(unlock_manager),
- pref_manager_.get());
- proximity_auth_system_->SetRemoteDevicesForUser(
- AccountId::FromUserEmail(kUser1), user1_remote_devices_,
- user1_local_device_);
- proximity_auth_system_->Start();
- LockScreen();
- }
- void LockScreen() {
- ScreenlockBridge::Get()->SetFocusedUser(AccountId());
- ScreenlockBridge::Get()->SetLockHandler(&lock_handler_);
- }
- void FocusUser(const std::string& user_email) {
- ScreenlockBridge::Get()->SetFocusedUser(
- AccountId::FromUserEmail(user_email));
- }
- void UnlockScreen() { ScreenlockBridge::Get()->SetLockHandler(nullptr); }
- void SimulateSuspend() {
- proximity_auth_system_->OnSuspend();
- proximity_auth_system_->OnSuspendDone();
- task_runner_->RunUntilIdle();
- }
- void SimulateScreenOff() {
- proximity_auth_system_->OnScreenOff();
- proximity_auth_system_->OnScreenOffDone();
- task_runner_->RunUntilIdle();
- }
- FakeRemoteDeviceLifeCycle* life_cycle() {
- return proximity_auth_system_->life_cycle();
- }
- FakeLockHandler lock_handler_;
- NiceMock<MockProximityAuthClient> proximity_auth_client_;
- std::unique_ptr<ash::secure_channel::FakeSecureChannelClient>
- fake_secure_channel_client_;
- std::unique_ptr<TestableProximityAuthSystem> proximity_auth_system_;
- MockUnlockManager* unlock_manager_;
- std::unique_ptr<MockProximityAuthPrefManager> pref_manager_;
- std::unique_ptr<ash::multidevice_setup::FakeMultiDeviceSetupClient>
- fake_multidevice_setup_client_;
- ash::multidevice::RemoteDeviceRef user1_local_device_;
- ash::multidevice::RemoteDeviceRef user2_local_device_;
- ash::multidevice::RemoteDeviceRefList user1_remote_devices_;
- ash::multidevice::RemoteDeviceRefList user2_remote_devices_;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
- base::ThreadTaskRunnerHandle thread_task_runner_handle_;
- private:
- ash::multidevice::ScopedDisableLoggingForTesting disable_logging_;
- };
- TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_NotStarted) {
- AccountId account1 = AccountId::FromUserEmail(kUser1);
- AccountId account2 = AccountId::FromUserEmail(kUser2);
- proximity_auth_system_->SetRemoteDevicesForUser(
- account1, user1_remote_devices_, user1_local_device_);
- proximity_auth_system_->SetRemoteDevicesForUser(
- account2, user2_remote_devices_, user1_local_device_);
- CompareRemoteDeviceRefLists(
- user1_remote_devices_,
- proximity_auth_system_->GetRemoteDevicesForUser(account1));
- CompareRemoteDeviceRefLists(
- user2_remote_devices_,
- proximity_auth_system_->GetRemoteDevicesForUser(account2));
- CompareRemoteDeviceRefLists(
- ash::multidevice::RemoteDeviceRefList(),
- proximity_auth_system_->GetRemoteDevicesForUser(
- AccountId::FromUserEmail("non_existent_user@google.com")));
- }
- TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_Started) {
- AccountId account1 = AccountId::FromUserEmail(kUser1);
- AccountId account2 = AccountId::FromUserEmail(kUser2);
- proximity_auth_system_->SetRemoteDevicesForUser(
- account1, user1_remote_devices_, user1_local_device_);
- proximity_auth_system_->Start();
- proximity_auth_system_->SetRemoteDevicesForUser(
- account2, user2_remote_devices_, user2_local_device_);
- CompareRemoteDeviceRefLists(
- user1_remote_devices_,
- proximity_auth_system_->GetRemoteDevicesForUser(account1));
- CompareRemoteDeviceRefLists(
- user2_remote_devices_,
- proximity_auth_system_->GetRemoteDevicesForUser(account2));
- }
- TEST_F(ProximityAuthSystemTest, FocusRegisteredUser) {
- EXPECT_FALSE(life_cycle());
- EXPECT_EQ(std::string(),
- ScreenlockBridge::Get()->focused_account_id().GetUserEmail());
- RemoteDeviceLifeCycle* unlock_manager_life_cycle = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&unlock_manager_life_cycle));
- FocusUser(kUser1);
- EXPECT_EQ(life_cycle(), unlock_manager_life_cycle);
- EXPECT_TRUE(life_cycle());
- EXPECT_FALSE(life_cycle()->started());
- EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- TEST_F(ProximityAuthSystemTest, FocusUnregisteredUser) {
- EXPECT_FALSE(life_cycle());
- EXPECT_EQ(std::string(),
- ScreenlockBridge::Get()->focused_account_id().GetUserEmail());
- EXPECT_FALSE(life_cycle());
- FocusUser(kUser2);
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredUsers) {
- proximity_auth_system_->SetRemoteDevicesForUser(
- AccountId::FromUserEmail(kUser1), user1_remote_devices_,
- user1_local_device_);
- proximity_auth_system_->SetRemoteDevicesForUser(
- AccountId::FromUserEmail(kUser2), user2_remote_devices_,
- user2_local_device_);
- RemoteDeviceLifeCycle* life_cycle1 = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&life_cycle1));
- FocusUser(kUser1);
- EXPECT_EQ(kUser1, life_cycle1->GetRemoteDevice().user_email());
- EXPECT_EQ(user1_local_device_, life_cycle()->local_device());
- RemoteDeviceLifeCycle* life_cycle2 = nullptr;
- {
- InSequence sequence;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&life_cycle2));
- }
- FocusUser(kUser2);
- EXPECT_EQ(kUser2, life_cycle2->GetRemoteDevice().user_email());
- EXPECT_EQ(user2_local_device_, life_cycle()->local_device());
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- TEST_F(ProximityAuthSystemTest, ToggleFocus_UnregisteredUsers) {
- FocusUser(kUser2);
- EXPECT_FALSE(life_cycle());
- FocusUser("unregistered-user");
- EXPECT_FALSE(life_cycle());
- FocusUser(kUser2);
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredAndUnregisteredUsers) {
- // Focus User 1, who is registered. This should create a new life cycle.
- RemoteDeviceLifeCycle* life_cycle = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&life_cycle));
- FocusUser(kUser1);
- EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
- // User 2 has not been registered yet, so focusing them should not create a
- // new life cycle.
- life_cycle = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr));
- FocusUser(kUser2);
- EXPECT_FALSE(life_cycle);
- // Focusing back to User 1 should recreate a new life cycle.
- life_cycle = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&life_cycle));
- FocusUser(kUser1);
- EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- TEST_F(ProximityAuthSystemTest, ToggleFocus_SameUserRefocused) {
- RemoteDeviceLifeCycle* life_cycle = nullptr;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
- .WillOnce(SaveArg<0>(&life_cycle));
- FocusUser(kUser1);
- EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_email());
- // Focusing the user again should be idempotent. The screenlock UI may call
- // focus on the same user multiple times.
- // SetRemoteDeviceLifeCycle() is only expected to be called once.
- FocusUser(kUser1);
- // The RemoteDeviceLifeCycle should be nulled upon destruction.
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- TEST_F(ProximityAuthSystemTest, RestartSystem_UnregisteredUserFocused) {
- FocusUser(kUser2);
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AnyNumber());
- proximity_auth_system_->Stop();
- proximity_auth_system_->Start();
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, StopSystem_RegisteredUserFocused) {
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
- FocusUser(kUser1);
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- proximity_auth_system_->Stop();
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
- proximity_auth_system_->Start();
- EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
- }
- TEST_F(ProximityAuthSystemTest, OnAuthAttempted) {
- FocusUser(kUser1);
- EXPECT_CALL(*unlock_manager_, OnAuthAttempted(_));
- proximity_auth_system_->OnAuthAttempted();
- }
- TEST_F(ProximityAuthSystemTest, Suspend_ScreenUnlocked) {
- UnlockScreen();
- EXPECT_FALSE(life_cycle());
- SimulateSuspend();
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, Suspend_UnregisteredUserFocused) {
- SimulateSuspend();
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, Suspend_RegisteredUserFocused) {
- FocusUser(kUser1);
- {
- InSequence sequence;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
- SimulateSuspend();
- }
- EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- TEST_F(ProximityAuthSystemTest, ScreenOff_ScreenUnlocked) {
- base::test::ScopedFeatureList feature_list(
- ash::features::kSmartLockBluetoothScreenOffFix);
- UnlockScreen();
- EXPECT_FALSE(life_cycle());
- SimulateScreenOff();
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, ScreenOff_UnregisteredUserFocused) {
- base::test::ScopedFeatureList feature_list(
- ash::features::kSmartLockBluetoothScreenOffFix);
- SimulateScreenOff();
- EXPECT_FALSE(life_cycle());
- }
- TEST_F(ProximityAuthSystemTest, ScreenOff_RegisteredUserFocused) {
- base::test::ScopedFeatureList feature_list(
- ash::features::kSmartLockBluetoothScreenOffFix);
- FocusUser(kUser1);
- {
- InSequence sequence;
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
- SimulateScreenOff();
- }
- EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_email());
- EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
- .Times(AtLeast(1));
- }
- } // namespace proximity_auth
|