unlock_manager_impl_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/proximity_auth/unlock_manager_impl.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "ash/components/multidevice/logging/logging.h"
  8. #include "ash/components/multidevice/remote_device_test_util.h"
  9. #include "ash/components/proximity_auth/fake_lock_handler.h"
  10. #include "ash/components/proximity_auth/fake_remote_device_life_cycle.h"
  11. #include "ash/components/proximity_auth/messenger.h"
  12. #include "ash/components/proximity_auth/mock_proximity_auth_client.h"
  13. #include "ash/components/proximity_auth/proximity_monitor.h"
  14. #include "ash/components/proximity_auth/remote_device_life_cycle.h"
  15. #include "ash/components/proximity_auth/remote_status_update.h"
  16. #include "ash/services/secure_channel/connection.h"
  17. #include "ash/services/secure_channel/public/cpp/client/fake_client_channel.h"
  18. #include "base/memory/ref_counted.h"
  19. #include "base/test/gmock_callback_support.h"
  20. #include "base/test/test_simple_task_runner.h"
  21. #include "base/threading/thread_task_runner_handle.h"
  22. #include "base/timer/mock_timer.h"
  23. #include "build/build_config.h"
  24. #include "chromeos/dbus/power/fake_power_manager_client.h"
  25. #include "chromeos/dbus/power/power_manager_client.h"
  26. #include "chromeos/dbus/power_manager/suspend.pb.h"
  27. #include "device/bluetooth/bluetooth_adapter_factory.h"
  28. #include "device/bluetooth/test/mock_bluetooth_adapter.h"
  29. #include "testing/gmock/include/gmock/gmock.h"
  30. #include "testing/gtest/include/gtest/gtest.h"
  31. using testing::_;
  32. using testing::AtLeast;
  33. using testing::Invoke;
  34. using testing::NiceMock;
  35. using testing::Return;
  36. namespace proximity_auth {
  37. namespace {
  38. using SmartLockState = ash::SmartLockState;
  39. // The sign-in challenge to send to the remote device.
  40. const char kChallenge[] = "sign-in challenge";
  41. const char kSignInSecret[] = "decrypted challenge";
  42. // Note that the trust agent state is currently ignored by the UnlockManager
  43. // implementation.
  44. RemoteStatusUpdate kRemoteScreenUnlocked = {
  45. USER_PRESENT, SECURE_SCREEN_LOCK_ENABLED, TRUST_AGENT_UNSUPPORTED};
  46. RemoteStatusUpdate kRemoteScreenLocked = {
  47. USER_ABSENT, SECURE_SCREEN_LOCK_ENABLED, TRUST_AGENT_UNSUPPORTED};
  48. RemoteStatusUpdate kRemoteScreenlockDisabled = {
  49. USER_PRESENT, SECURE_SCREEN_LOCK_DISABLED, TRUST_AGENT_UNSUPPORTED};
  50. RemoteStatusUpdate kRemoteScreenlockStateUnknown = {
  51. USER_PRESENCE_UNKNOWN, SECURE_SCREEN_LOCK_STATE_UNKNOWN,
  52. TRUST_AGENT_UNSUPPORTED};
  53. class MockMessenger : public Messenger {
  54. public:
  55. MockMessenger() {}
  56. MockMessenger(const MockMessenger&) = delete;
  57. MockMessenger& operator=(const MockMessenger&) = delete;
  58. ~MockMessenger() override {}
  59. MOCK_METHOD1(AddObserver, void(MessengerObserver* observer));
  60. MOCK_METHOD1(RemoveObserver, void(MessengerObserver* observer));
  61. MOCK_METHOD0(DispatchUnlockEvent, void());
  62. MOCK_METHOD1(RequestDecryption, void(const std::string& challenge));
  63. MOCK_METHOD0(RequestUnlock, void());
  64. MOCK_CONST_METHOD0(GetConnection, ash::secure_channel::Connection*());
  65. MOCK_CONST_METHOD0(GetChannel, ash::secure_channel::ClientChannel*());
  66. };
  67. class MockProximityMonitor : public ProximityMonitor {
  68. public:
  69. explicit MockProximityMonitor(base::OnceClosure destroy_callback)
  70. : destroy_callback_(std::move(destroy_callback)), started_(false) {
  71. ON_CALL(*this, IsUnlockAllowed()).WillByDefault(Return(true));
  72. }
  73. MockProximityMonitor(const MockProximityMonitor&) = delete;
  74. MockProximityMonitor& operator=(const MockProximityMonitor&) = delete;
  75. ~MockProximityMonitor() override { std::move(destroy_callback_).Run(); }
  76. void Start() override { started_ = true; }
  77. void Stop() override {}
  78. MOCK_CONST_METHOD0(IsUnlockAllowed, bool());
  79. MOCK_METHOD0(RecordProximityMetricsOnAuthSuccess, void());
  80. bool started() { return started_; }
  81. private:
  82. base::OnceClosure destroy_callback_;
  83. bool started_;
  84. };
  85. class TestUnlockManager : public UnlockManagerImpl {
  86. public:
  87. TestUnlockManager(ProximityAuthSystem::ScreenlockType screenlock_type,
  88. ProximityAuthClient* proximity_auth_client)
  89. : UnlockManagerImpl(screenlock_type, proximity_auth_client) {}
  90. TestUnlockManager(const TestUnlockManager&) = delete;
  91. TestUnlockManager& operator=(const TestUnlockManager&) = delete;
  92. ~TestUnlockManager() override {}
  93. using MessengerObserver::OnDecryptResponse;
  94. using MessengerObserver::OnDisconnected;
  95. using MessengerObserver::OnRemoteStatusUpdate;
  96. using MessengerObserver::OnUnlockEventSent;
  97. using MessengerObserver::OnUnlockResponse;
  98. using UnlockManager::OnAuthAttempted;
  99. MockProximityMonitor* proximity_monitor() { return proximity_monitor_; }
  100. bool proximity_monitor_destroyed() { return proximity_monitor_destroyed_; }
  101. private:
  102. std::unique_ptr<ProximityMonitor> CreateProximityMonitor(
  103. RemoteDeviceLifeCycle* life_cycle) override {
  104. std::unique_ptr<MockProximityMonitor> proximity_monitor(
  105. new NiceMock<MockProximityMonitor>(
  106. base::BindOnce(&TestUnlockManager::OnProximityMonitorDestroyed,
  107. base::Unretained(this))));
  108. proximity_monitor_destroyed_ = false;
  109. proximity_monitor_ = proximity_monitor.get();
  110. return proximity_monitor;
  111. }
  112. void OnProximityMonitorDestroyed() { proximity_monitor_destroyed_ = true; }
  113. // Owned by the super class.
  114. MockProximityMonitor* proximity_monitor_ = nullptr;
  115. bool proximity_monitor_destroyed_ = false;
  116. };
  117. // Creates a mock Bluetooth adapter and sets it as the global adapter for
  118. // testing.
  119. scoped_refptr<device::MockBluetoothAdapter>
  120. CreateAndRegisterMockBluetoothAdapter() {
  121. scoped_refptr<device::MockBluetoothAdapter> adapter =
  122. new NiceMock<device::MockBluetoothAdapter>();
  123. device::BluetoothAdapterFactory::SetAdapterForTesting(adapter);
  124. return adapter;
  125. }
  126. } // namespace
  127. class ProximityAuthUnlockManagerImplTest : public testing::Test {
  128. public:
  129. ProximityAuthUnlockManagerImplTest()
  130. : remote_device_(ash::multidevice::CreateRemoteDeviceRefForTest()),
  131. local_device_(ash::multidevice::CreateRemoteDeviceRefForTest()),
  132. life_cycle_(remote_device_, local_device_),
  133. fake_client_channel_(
  134. std::make_unique<ash::secure_channel::FakeClientChannel>()),
  135. bluetooth_adapter_(CreateAndRegisterMockBluetoothAdapter()),
  136. task_runner_(new base::TestSimpleTaskRunner()),
  137. thread_task_runner_handle_(task_runner_) {}
  138. ~ProximityAuthUnlockManagerImplTest() override = default;
  139. void SetUp() override {
  140. chromeos::PowerManagerClient::InitializeFake();
  141. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(true));
  142. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(true));
  143. ON_CALL(messenger_, GetChannel())
  144. .WillByDefault(Return(fake_client_channel_.get()));
  145. life_cycle_.set_messenger(&messenger_);
  146. life_cycle_.set_channel(fake_client_channel_.get());
  147. }
  148. void TearDown() override {
  149. // Make sure to verify the mock prior to the destruction of the unlock
  150. // manager, as otherwise it's impossible to tell whether calls to Stop()
  151. // occur as a side-effect of the destruction or from the code intended to be
  152. // under test.
  153. if (proximity_monitor())
  154. testing::Mock::VerifyAndClearExpectations(proximity_monitor());
  155. unlock_manager_.reset();
  156. chromeos::PowerManagerClient::Shutdown();
  157. }
  158. void CreateUnlockManager(
  159. ProximityAuthSystem::ScreenlockType screenlock_type) {
  160. unlock_manager_ = std::make_unique<TestUnlockManager>(
  161. screenlock_type, &proximity_auth_client_);
  162. auto mock_timer = std::make_unique<base::MockOneShotTimer>();
  163. mock_bluetooth_suspension_recovery_timer_ = mock_timer.get();
  164. unlock_manager_->SetBluetoothSuspensionRecoveryTimerForTesting(
  165. std::move(mock_timer));
  166. }
  167. void SimulateUserPresentState() {
  168. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  169. life_cycle_.ChangeState(
  170. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  171. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked);
  172. }
  173. void RunPendingTasks() { task_runner_->RunPendingTasks(); }
  174. MockProximityMonitor* proximity_monitor() {
  175. return unlock_manager_ ? unlock_manager_->proximity_monitor() : nullptr;
  176. }
  177. bool proximity_monitor_destroyed() {
  178. return unlock_manager_ ? unlock_manager_->proximity_monitor_destroyed()
  179. : false;
  180. }
  181. protected:
  182. ash::multidevice::RemoteDeviceRef remote_device_;
  183. ash::multidevice::RemoteDeviceRef local_device_;
  184. FakeRemoteDeviceLifeCycle life_cycle_;
  185. std::unique_ptr<ash::secure_channel::FakeClientChannel> fake_client_channel_;
  186. // Mock used for verifying interactions with the Bluetooth subsystem.
  187. scoped_refptr<device::MockBluetoothAdapter> bluetooth_adapter_;
  188. NiceMock<MockProximityAuthClient> proximity_auth_client_;
  189. NiceMock<MockMessenger> messenger_;
  190. std::unique_ptr<TestUnlockManager> unlock_manager_;
  191. base::MockOneShotTimer* mock_bluetooth_suspension_recovery_timer_ = nullptr;
  192. private:
  193. scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  194. base::ThreadTaskRunnerHandle thread_task_runner_handle_;
  195. FakeLockHandler lock_handler_;
  196. ash::multidevice::ScopedDisableLoggingForTesting disable_logging_;
  197. };
  198. TEST_F(ProximityAuthUnlockManagerImplTest, IsUnlockAllowed_InitialState) {
  199. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  200. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  201. }
  202. TEST_F(ProximityAuthUnlockManagerImplTest,
  203. IsUnlockAllowed_SessionLock_AllGood) {
  204. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  205. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  206. life_cycle_.ChangeState(
  207. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  208. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked);
  209. EXPECT_TRUE(unlock_manager_->IsUnlockAllowed());
  210. }
  211. TEST_F(ProximityAuthUnlockManagerImplTest, IsUnlockAllowed_SignIn_AllGood) {
  212. CreateUnlockManager(ProximityAuthSystem::SIGN_IN);
  213. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  214. life_cycle_.ChangeState(
  215. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  216. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked);
  217. EXPECT_TRUE(unlock_manager_->IsUnlockAllowed());
  218. }
  219. TEST_F(ProximityAuthUnlockManagerImplTest,
  220. IsUnlockAllowed_DisallowedByProximityMonitor) {
  221. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  222. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  223. life_cycle_.ChangeState(
  224. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  225. ON_CALL(*proximity_monitor(), IsUnlockAllowed()).WillByDefault(Return(false));
  226. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked);
  227. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  228. }
  229. TEST_F(ProximityAuthUnlockManagerImplTest,
  230. IsUnlockAllowed_RemoteDeviceLifeCycleIsNull) {
  231. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  232. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  233. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked);
  234. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  235. }
  236. TEST_F(ProximityAuthUnlockManagerImplTest,
  237. IsUnlockAllowed_RemoteScreenlockStateLocked) {
  238. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  239. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  240. life_cycle_.ChangeState(
  241. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  242. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenLocked);
  243. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  244. }
  245. TEST_F(ProximityAuthUnlockManagerImplTest, IsUnlockAllowed_UserIsSecondary) {
  246. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  247. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  248. life_cycle_.ChangeState(
  249. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  250. unlock_manager_->OnRemoteStatusUpdate({USER_PRESENCE_SECONDARY,
  251. SECURE_SCREEN_LOCK_ENABLED,
  252. TRUST_AGENT_UNSUPPORTED});
  253. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  254. }
  255. TEST_F(ProximityAuthUnlockManagerImplTest,
  256. IsUnlockAllowed_PrimaryUserInBackground) {
  257. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  258. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  259. life_cycle_.ChangeState(
  260. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  261. unlock_manager_->OnRemoteStatusUpdate({USER_PRESENCE_BACKGROUND,
  262. SECURE_SCREEN_LOCK_ENABLED,
  263. TRUST_AGENT_UNSUPPORTED});
  264. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  265. }
  266. TEST_F(ProximityAuthUnlockManagerImplTest,
  267. IsUnlockAllowed_RemoteScreenlockStateUnknown) {
  268. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  269. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  270. life_cycle_.ChangeState(
  271. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  272. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenlockStateUnknown);
  273. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  274. }
  275. TEST_F(ProximityAuthUnlockManagerImplTest,
  276. IsUnlockAllowed_RemoteScreenlockStateDisabled) {
  277. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  278. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  279. life_cycle_.ChangeState(
  280. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  281. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenlockDisabled);
  282. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  283. }
  284. TEST_F(ProximityAuthUnlockManagerImplTest,
  285. IsUnlockAllowed_RemoteScreenlockStateNotYetReceived) {
  286. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  287. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  288. life_cycle_.ChangeState(
  289. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  290. EXPECT_FALSE(unlock_manager_->IsUnlockAllowed());
  291. }
  292. TEST_F(ProximityAuthUnlockManagerImplTest, SetRemoteDeviceLifeCycle_SetToNull) {
  293. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  294. SimulateUserPresentState();
  295. EXPECT_CALL(proximity_auth_client_,
  296. UpdateSmartLockState(SmartLockState::kInactive));
  297. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  298. }
  299. TEST_F(ProximityAuthUnlockManagerImplTest,
  300. SetRemoteDeviceLifeCycle_ExistingRemoteDeviceLifeCycle) {
  301. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  302. SimulateUserPresentState();
  303. EXPECT_CALL(proximity_auth_client_,
  304. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  305. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  306. }
  307. TEST_F(ProximityAuthUnlockManagerImplTest,
  308. SetRemoteDeviceLifeCycle_AuthenticationFailed) {
  309. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  310. SimulateUserPresentState();
  311. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  312. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED);
  313. EXPECT_CALL(proximity_auth_client_,
  314. UpdateSmartLockState(SmartLockState::kPhoneNotAuthenticated));
  315. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  316. }
  317. TEST_F(ProximityAuthUnlockManagerImplTest, SetRemoteDeviceLifeCycle_WakingUp) {
  318. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  319. SimulateUserPresentState();
  320. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  321. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
  322. EXPECT_CALL(proximity_auth_client_,
  323. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  324. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  325. }
  326. TEST_F(ProximityAuthUnlockManagerImplTest,
  327. SetRemoteDeviceLifeCycle_TimesOutBeforeConnection) {
  328. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  329. life_cycle_.set_messenger(nullptr);
  330. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
  331. EXPECT_CALL(proximity_auth_client_,
  332. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  333. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  334. EXPECT_CALL(proximity_auth_client_,
  335. UpdateSmartLockState(SmartLockState::kPhoneNotFound));
  336. // Simulate timing out before a connection is established.
  337. RunPendingTasks();
  338. }
  339. TEST_F(ProximityAuthUnlockManagerImplTest,
  340. SetRemoteDeviceLifeCycle_NullRemoteDeviceLifeCycle_NoProximityMonitor) {
  341. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  342. SimulateUserPresentState();
  343. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  344. }
  345. TEST_F(
  346. ProximityAuthUnlockManagerImplTest,
  347. SetRemoteDeviceLifeCycle_ConnectingRemoteDeviceLifeCycle_StopsProximityMonitor) {
  348. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  349. SimulateUserPresentState();
  350. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
  351. EXPECT_TRUE(proximity_monitor_destroyed());
  352. }
  353. TEST_F(
  354. ProximityAuthUnlockManagerImplTest,
  355. SetRemoteDeviceLifeCycle_ConnectedRemoteDeviceLifeCycle_StartsProximityMonitor) {
  356. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  357. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  358. life_cycle_.ChangeState(
  359. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  360. EXPECT_TRUE(proximity_monitor()->started());
  361. }
  362. // Regression test for crbug.com/931929. Capture the case where the phone is
  363. // connected to, connection is lost, and then a new connection is made shortly
  364. // after.
  365. TEST_F(ProximityAuthUnlockManagerImplTest,
  366. SetRemoteDeviceLifeCycle_TwiceConnectedRemoteDeviceLifeCycle) {
  367. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  368. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  369. life_cycle_.ChangeState(
  370. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  371. EXPECT_TRUE(proximity_monitor()->started());
  372. // Simulate the phone connection being lost. The ProximityMonitor is stale
  373. // and should have been destroyed.
  374. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
  375. EXPECT_TRUE(proximity_monitor_destroyed());
  376. life_cycle_.ChangeState(
  377. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  378. EXPECT_FALSE(proximity_monitor_destroyed());
  379. EXPECT_TRUE(proximity_monitor()->started());
  380. }
  381. TEST_F(ProximityAuthUnlockManagerImplTest, BluetoothAdapterNotPresent) {
  382. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
  383. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  384. EXPECT_CALL(proximity_auth_client_,
  385. UpdateSmartLockState(SmartLockState::kBluetoothDisabled));
  386. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  387. EXPECT_FALSE(life_cycle_.started());
  388. }
  389. TEST_F(ProximityAuthUnlockManagerImplTest, BluetoothAdapterPowerChanges) {
  390. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(false));
  391. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  392. EXPECT_CALL(proximity_auth_client_,
  393. UpdateSmartLockState(SmartLockState::kBluetoothDisabled));
  394. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  395. EXPECT_FALSE(life_cycle_.started());
  396. EXPECT_CALL(proximity_auth_client_,
  397. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  398. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(true));
  399. bluetooth_adapter_->NotifyAdapterPoweredChanged(true);
  400. EXPECT_TRUE(life_cycle_.started());
  401. }
  402. TEST_F(
  403. ProximityAuthUnlockManagerImplTest,
  404. CacheBluetoothAdapterStateAfterSuspendAndResume_AttemptConnectionWhileBluetoothAdapterIsStillRecovering) {
  405. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  406. ASSERT_FALSE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  407. chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
  408. power_manager::SuspendImminent_Reason_LID_CLOSED);
  409. // Simulate https://crbug.com/986896 by returning false for presence and power
  410. // directly after resuming, but do not fire
  411. // |mock_bluetooth_suspension_recovery_timer_|, simulating that not enough
  412. // time has passed for the BluetoothAdapter to recover. It's expected under
  413. // these conditions that:
  414. // * ProximityAuthClient::UpdateSmartLockState() never be called with
  415. // SmartLockState::kBluetoothDisabled.
  416. // * ProximityAuthClient::UpdateSmartLockState() only be called once with
  417. // SmartLockState::BLUETOOTH_CONNECTING, because it should only be called
  418. // on when the SmartLockState value changes.
  419. EXPECT_CALL(proximity_auth_client_,
  420. UpdateSmartLockState(SmartLockState::kBluetoothDisabled))
  421. .Times(0);
  422. EXPECT_CALL(proximity_auth_client_,
  423. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  424. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
  425. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(false));
  426. chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  427. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  428. // Simulate how ProximityAuthSystem, the owner of UnlockManager, reacts to
  429. // resume: providing a new RemoteDeviceLifeCycle. This shouldn't trigger a new
  430. // call to ProximityAuthClient::UpdateSmartLockState().
  431. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  432. EXPECT_TRUE(life_cycle_.started());
  433. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  434. }
  435. TEST_F(
  436. ProximityAuthUnlockManagerImplTest,
  437. CacheBluetoothAdapterStateAfterSuspendAndResume_AttemptConnectionOnceBluetoothAdapterHasHadTimeToRecover) {
  438. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  439. ASSERT_FALSE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  440. chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
  441. power_manager::SuspendImminent_Reason_LID_CLOSED);
  442. // Simulate https://crbug.com/986896 by returning false for presence and power
  443. // directly after resuming, and then fire
  444. // |mock_bluetooth_suspension_recovery_timer_|, simulating that enough time
  445. // has passed for the BluetoothAdapter to recover - this means that Bluetooth
  446. // is truly off after resume and the user should be visually informed as such.
  447. // It's expected under these conditions that:
  448. // * ProximityAuthClient::UpdateSmartLockState() only be called once with
  449. // SmartLockState::kBluetoothDisabled, but after the timer fires (this is
  450. // impossible to explicitly do in code with mocks, unfortunately).
  451. // * ProximityAuthClient::UpdateSmartLockState() only be called once with
  452. // SmartLockState::BLUETOOTH_CONNECTING, directly after SuspendDone.
  453. EXPECT_CALL(proximity_auth_client_,
  454. UpdateSmartLockState(SmartLockState::kBluetoothDisabled));
  455. EXPECT_CALL(proximity_auth_client_,
  456. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  457. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
  458. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(false));
  459. chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  460. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  461. // Simulate how ProximityAuthSystem, the owner of UnlockManager, reacts to
  462. // resume: providing a new RemoteDeviceLifeCycle. This shouldn't trigger a new
  463. // call to ProximityAuthClient::UpdateSmartLockState().
  464. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  465. EXPECT_TRUE(life_cycle_.started());
  466. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
  467. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(false));
  468. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  469. // This leads to ProximityAuthClient::UpdateSmartLockState() being called
  470. // with SmartLockState::NO_BLUETOOTH.
  471. mock_bluetooth_suspension_recovery_timer_->Fire();
  472. }
  473. TEST_F(
  474. ProximityAuthUnlockManagerImplTest,
  475. InitialScanAfterSuspendResume_DontPerformInitialScanIfConnectionEstablished) {
  476. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  477. ASSERT_FALSE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  478. // Simulates the lid of chromebook closing resulting in suspension.
  479. chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
  480. power_manager::SuspendImminent_Reason_LID_CLOSED);
  481. EXPECT_CALL(
  482. proximity_auth_client_,
  483. UpdateSmartLockState(SmartLockState::kPhoneFoundLockedAndProximate))
  484. .Times(1);
  485. EXPECT_CALL(proximity_auth_client_,
  486. UpdateSmartLockState(SmartLockState::kConnectingToPhone))
  487. .Times(1);
  488. // We want to emulate a bluetooth adapter that is present and powered
  489. // upon lid reopen and resume, because we are testing the code path
  490. // within OnBluetoothAdapterPresentAndPowerChanged() after the
  491. // suspension timer concludes.
  492. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(true));
  493. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(true));
  494. // This event simulates reopen of lid resulting in resume.
  495. chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  496. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  497. // Start the life cycle for unlock manager.
  498. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  499. EXPECT_TRUE(life_cycle_.started());
  500. // Simulate a secure channel connection established with phone.
  501. life_cycle_.ChangeState(
  502. RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
  503. // Simulate the phone responding with locked and proximate.
  504. unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenLocked);
  505. EXPECT_TRUE(mock_bluetooth_suspension_recovery_timer_->IsRunning());
  506. // Time out the suspension recovery timer so we run
  507. // OnBluetoothAdapterPresentAndPowerChanged().
  508. mock_bluetooth_suspension_recovery_timer_->Fire();
  509. }
  510. TEST_F(ProximityAuthUnlockManagerImplTest,
  511. BluetoothOffMessageShownImmediatelyIfBluetoothWasOffBeforeSuspend) {
  512. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  513. ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
  514. ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(false));
  515. chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
  516. power_manager::SuspendImminent_Reason_LID_CLOSED);
  517. EXPECT_CALL(proximity_auth_client_,
  518. UpdateSmartLockState(SmartLockState::kBluetoothDisabled));
  519. EXPECT_CALL(proximity_auth_client_,
  520. UpdateSmartLockState(SmartLockState::kConnectingToPhone))
  521. .Times(0);
  522. chromeos::FakePowerManagerClient::Get()->SendSuspendDone();
  523. // Simulate how ProximityAuthSystem, the owner of UnlockManager, reacts to
  524. // resume: providing a new RemoteDeviceLifeCycle.
  525. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  526. EXPECT_FALSE(life_cycle_.started());
  527. }
  528. TEST_F(ProximityAuthUnlockManagerImplTest, StartsProximityMonitor) {
  529. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  530. SimulateUserPresentState();
  531. EXPECT_TRUE(proximity_monitor()->started());
  532. }
  533. TEST_F(ProximityAuthUnlockManagerImplTest,
  534. OnAuthenticationFailed_StopsProximityMonitor) {
  535. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  536. SimulateUserPresentState();
  537. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED);
  538. EXPECT_TRUE(proximity_monitor_destroyed());
  539. }
  540. TEST_F(ProximityAuthUnlockManagerImplTest,
  541. AuthenticationFailed_UpdatesSmartLockState) {
  542. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  543. SimulateUserPresentState();
  544. EXPECT_CALL(proximity_auth_client_,
  545. UpdateSmartLockState(SmartLockState::kPhoneNotAuthenticated));
  546. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED);
  547. }
  548. TEST_F(ProximityAuthUnlockManagerImplTest,
  549. FindingConnection_UpdatesSmartLockState) {
  550. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  551. // Regression test for https://crbug.com/890047, ensuring that the NO_PHONE
  552. // status doesn't incorrectly appear for a brief moment before the
  553. // BLUETOOTH_CONNECTING spinner.
  554. EXPECT_CALL(proximity_auth_client_,
  555. UpdateSmartLockState(SmartLockState::kPhoneNotFound))
  556. .Times(0);
  557. EXPECT_CALL(proximity_auth_client_,
  558. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  559. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  560. EXPECT_TRUE(life_cycle_.started());
  561. }
  562. TEST_F(ProximityAuthUnlockManagerImplTest,
  563. Authenticating_UpdatesSmartLockState) {
  564. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  565. // Regression test for https://crbug.com/890047, ensuring that the NO_PHONE
  566. // status doesn't incorrectly appear for a brief moment before the
  567. // BLUETOOTH_CONNECTING spinner.
  568. EXPECT_CALL(proximity_auth_client_,
  569. UpdateSmartLockState(SmartLockState::kPhoneNotFound))
  570. .Times(0);
  571. EXPECT_CALL(proximity_auth_client_,
  572. UpdateSmartLockState(SmartLockState::kConnectingToPhone));
  573. unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_);
  574. EXPECT_TRUE(life_cycle_.started());
  575. life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATING);
  576. }
  577. TEST_F(ProximityAuthUnlockManagerImplTest,
  578. OnDecryptResponse_NoAuthAttemptInProgress) {
  579. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  580. SimulateUserPresentState();
  581. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_)).Times(0);
  582. unlock_manager_.get()->OnDecryptResponse(kSignInSecret);
  583. }
  584. TEST_F(ProximityAuthUnlockManagerImplTest,
  585. OnUnlockEventSent_NoAuthAttemptInProgress) {
  586. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  587. SimulateUserPresentState();
  588. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_)).Times(0);
  589. unlock_manager_.get()->OnUnlockEventSent(true);
  590. }
  591. TEST_F(ProximityAuthUnlockManagerImplTest,
  592. OnUnlockResponse_NoAuthAttemptInProgress) {
  593. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  594. SimulateUserPresentState();
  595. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_)).Times(0);
  596. unlock_manager_.get()->OnUnlockResponse(true);
  597. }
  598. TEST_F(ProximityAuthUnlockManagerImplTest,
  599. OnAuthAttempted_NoRemoteDeviceLifeCycle) {
  600. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  601. SimulateUserPresentState();
  602. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  603. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(false));
  604. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  605. }
  606. TEST_F(ProximityAuthUnlockManagerImplTest, OnAuthAttempted_UnlockNotAllowed) {
  607. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  608. SimulateUserPresentState();
  609. ON_CALL(*proximity_monitor(), IsUnlockAllowed()).WillByDefault(Return(false));
  610. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(false));
  611. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  612. }
  613. TEST_F(ProximityAuthUnlockManagerImplTest, OnAuthAttempted_NotUserClick) {
  614. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  615. SimulateUserPresentState();
  616. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_)).Times(0);
  617. unlock_manager_->OnAuthAttempted(mojom::AuthType::EXPAND_THEN_USER_CLICK);
  618. }
  619. TEST_F(ProximityAuthUnlockManagerImplTest, OnAuthAttempted_DuplicateCall) {
  620. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  621. SimulateUserPresentState();
  622. EXPECT_CALL(messenger_, RequestUnlock());
  623. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  624. EXPECT_CALL(messenger_, RequestUnlock()).Times(0);
  625. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  626. }
  627. TEST_F(ProximityAuthUnlockManagerImplTest, OnAuthAttempted_TimesOut) {
  628. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  629. SimulateUserPresentState();
  630. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  631. // Simulate the timeout period elapsing.
  632. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(false));
  633. RunPendingTasks();
  634. }
  635. TEST_F(ProximityAuthUnlockManagerImplTest,
  636. OnAuthAttempted_DoesntTimeOutFollowingResponse) {
  637. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  638. SimulateUserPresentState();
  639. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  640. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_));
  641. unlock_manager_->OnUnlockResponse(false);
  642. // Simulate the timeout period elapsing.
  643. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(_)).Times(0);
  644. RunPendingTasks();
  645. }
  646. TEST_F(ProximityAuthUnlockManagerImplTest,
  647. OnAuthAttempted_Unlock_UnlockRequestFails) {
  648. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  649. SimulateUserPresentState();
  650. EXPECT_CALL(messenger_, RequestUnlock());
  651. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  652. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(false));
  653. unlock_manager_->OnUnlockResponse(false);
  654. }
  655. TEST_F(ProximityAuthUnlockManagerImplTest,
  656. OnAuthAttempted_Unlock_WithSignIn_RequestSucceeds_EventSendFails) {
  657. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  658. SimulateUserPresentState();
  659. EXPECT_CALL(messenger_, RequestUnlock());
  660. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  661. EXPECT_CALL(messenger_, DispatchUnlockEvent());
  662. unlock_manager_->OnUnlockResponse(true);
  663. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(false));
  664. unlock_manager_->OnUnlockEventSent(false);
  665. }
  666. TEST_F(ProximityAuthUnlockManagerImplTest,
  667. OnAuthAttempted_Unlock_RequestSucceeds_EventSendSucceeds) {
  668. CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK);
  669. SimulateUserPresentState();
  670. EXPECT_CALL(messenger_, RequestUnlock());
  671. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  672. EXPECT_CALL(messenger_, DispatchUnlockEvent());
  673. unlock_manager_->OnUnlockResponse(true);
  674. EXPECT_CALL(proximity_auth_client_, FinalizeUnlock(true));
  675. unlock_manager_->OnUnlockEventSent(true);
  676. }
  677. TEST_F(ProximityAuthUnlockManagerImplTest, OnAuthAttempted_SignIn_Success) {
  678. CreateUnlockManager(ProximityAuthSystem::SIGN_IN);
  679. SimulateUserPresentState();
  680. std::string channel_binding_data = "channel binding data";
  681. EXPECT_CALL(proximity_auth_client_,
  682. GetChallengeForUserAndDevice(remote_device_.user_email(),
  683. remote_device_.public_key(),
  684. channel_binding_data, _))
  685. .WillOnce(base::test::RunOnceCallback<3>(kChallenge));
  686. EXPECT_CALL(messenger_, RequestDecryption(kChallenge));
  687. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  688. std::vector<ash::secure_channel::mojom::ConnectionCreationDetail>
  689. creation_details{ash::secure_channel::mojom::ConnectionCreationDetail::
  690. REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING};
  691. ash::secure_channel::mojom::ConnectionMetadataPtr connection_metadata_ptr =
  692. ash::secure_channel::mojom::ConnectionMetadata::New(
  693. creation_details, nullptr /* bluetooth_connection_metadata */,
  694. channel_binding_data);
  695. fake_client_channel_->InvokePendingGetConnectionMetadataCallback(
  696. std::move(connection_metadata_ptr));
  697. EXPECT_CALL(messenger_, DispatchUnlockEvent());
  698. unlock_manager_->OnDecryptResponse(kSignInSecret);
  699. EXPECT_CALL(proximity_auth_client_, FinalizeSignin(kSignInSecret));
  700. unlock_manager_->OnUnlockEventSent(true);
  701. }
  702. } // namespace proximity_auth