diff options
author | tengs <tengs@chromium.org> | 2015-08-12 11:56:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-12 18:56:55 +0000 |
commit | 07c8036dd0a183b69299136eb921576129300771 (patch) | |
tree | 7eecd45e94e8d2185ff314f10967376c03141a81 /components/proximity_auth | |
parent | fdd36a8329fb60fc5c50612643e310cc40204f07 (diff) | |
download | chromium_src-07c8036dd0a183b69299136eb921576129300771.zip chromium_src-07c8036dd0a183b69299136eb921576129300771.tar.gz chromium_src-07c8036dd0a183b69299136eb921576129300771.tar.bz2 |
Hook up Bluetooth Low Energy Smart Lock experiment with existing lock screen UI.
If the --enable-proximity-auth-bluetooth-low-energy-discovery flag is set, the
user now can click the user pod to unlock the lock screen rather than
automatically unlocking.
This CL also refactors ProximityAuthBleSystem now that ScreenlockBridge is part
of the proximity_auth component.
BUG=517641
TEST=manual
Review URL: https://codereview.chromium.org/1273153004
Cr-Commit-Position: refs/heads/master@{#343065}
Diffstat (limited to 'components/proximity_auth')
8 files changed, 263 insertions, 147 deletions
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.cc b/components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.cc index 60d15c5..77803cd 100644 --- a/components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.cc +++ b/components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.cc @@ -90,15 +90,10 @@ void BluetoothLowEnergyCharacteristicsFinder::ScanRemoteCharacteristics( std::vector<BluetoothGattService*> services = device->GetGattServices(); for (const auto& service : services) { if (service->GetUUID() == service_uuid) { - PA_LOG(INFO) << "Service " << service_uuid.canonical_value() - << " found."; // Right service found, now scaning its characteristics. std::vector<device::BluetoothGattCharacteristic*> characteristics = service->GetCharacteristics(); for (const auto& characteristic : characteristics) { - PA_LOG(INFO) << "Char: " - << characteristic->GetUUID().canonical_value() - << " found."; HandleCharacteristicUpdate(characteristic); } break; @@ -113,6 +108,7 @@ void BluetoothLowEnergyCharacteristicsFinder::HandleCharacteristicUpdate( if (!to_peripheral_char_.id.empty() && !from_peripheral_char_.id.empty() && !success_callback_.is_null()) { + PA_LOG(INFO) << "Found write and read characteristics on remote device."; success_callback_.Run(remote_service_, to_peripheral_char_, from_peripheral_char_); ResetCallbacks(); diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc index 9513f99..dabf64e 100644 --- a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc +++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc @@ -98,7 +98,6 @@ void BluetoothLowEnergyConnectionFinder::DeviceAdded(BluetoothAdapter* adapter, BluetoothDevice* device) { DCHECK_EQ(adapter_.get(), adapter); DCHECK(device); - PA_LOG(INFO) << "Device added: " << device->GetAddress(); // Note: Only consider |device| when it was actually added/updated during a // scanning, otherwise the device is stale and the GATT connection will fail. @@ -120,11 +119,8 @@ void BluetoothLowEnergyConnectionFinder::DeviceChanged( // For instance, when |adapter_| change status from unpowered to powered, // |DeviceAdded| is called for each paired |device|. if (adapter_->IsPowered() && discovery_session_ && - discovery_session_->IsActive()) { - if (device_whitelist_->HasDeviceWithAddress(device->GetAddress())) - PA_LOG(INFO) << "Whitelisted device changed: " << device->GetAddress(); + discovery_session_->IsActive()) HandleDeviceUpdated(device); - } } void BluetoothLowEnergyConnectionFinder::HandleDeviceUpdated( @@ -147,6 +143,7 @@ void BluetoothLowEnergyConnectionFinder::HandleDeviceUpdated( connection_->AddObserver(this); connection_->Connect(); + adapter_->RemoveObserver(this); StopDiscoverySession(); } } @@ -162,12 +159,6 @@ void BluetoothLowEnergyConnectionFinder::OnAdapterInitialized( // temporary MAC may not be resolved automatically (see crbug.com/495402). The // Bluetooth adapter will fire |OnDeviceChanged| notifications for all // Bluetooth Low Energy devices that are advertising. - std::vector<BluetoothDevice*> devices = adapter_->GetDevices(); - for (auto* device : devices) { - PA_LOG(INFO) << "Ignoring device " << device->GetAddress() - << " present when adapter was initialized."; - } - StartDiscoverySession(); } diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.cc b/components/proximity_auth/ble/proximity_auth_ble_system.cc index 9b55912..73ab88c 100644 --- a/components/proximity_auth/ble/proximity_auth_ble_system.cc +++ b/components/proximity_auth/ble/proximity_auth_ble_system.cc @@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/location.h" -#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" #include "base/thread_task_runner_handle.h" #include "base/time/default_tick_clock.h" #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h" @@ -47,6 +47,9 @@ const int kPollingIntervalSeconds = 5; // String received when the remote device's screen is unlocked. const char kScreenUnlocked[] = "Screen Unlocked"; +// String received when the remote device's screen is locked. +const char kScreenLocked[] = "Screen Locked"; + // String send to poll the remote device screen state. const char kPollScreenState[] = "PollScreenState"; @@ -57,63 +60,31 @@ const char kPublicKeyMessagePrefix[] = "PublicKey:"; // request before failing. const int kMaxNumberOfTries = 2; -} // namespace - -ProximityAuthBleSystem::ScreenlockBridgeAdapter::ScreenlockBridgeAdapter( - ScreenlockBridge* screenlock_bridge) - : screenlock_bridge_(screenlock_bridge) { -} - -ProximityAuthBleSystem::ScreenlockBridgeAdapter::ScreenlockBridgeAdapter() { -} - -ProximityAuthBleSystem::ScreenlockBridgeAdapter::~ScreenlockBridgeAdapter() { -} +// The time, in seconds, to show a spinner for the user pod immediately after +// the screen is locked. +const int kSpinnerTimeSeconds = 15; -void ProximityAuthBleSystem::ScreenlockBridgeAdapter::AddObserver( - ScreenlockBridge::Observer* observer) { - screenlock_bridge_->AddObserver(observer); -} +// Text shown on the user pod when unlock is allowed. +const char kUserPodUnlockText[] = "Click your photo"; -void ProximityAuthBleSystem::ScreenlockBridgeAdapter::RemoveObserver( - ScreenlockBridge::Observer* observer) { - screenlock_bridge_->RemoveObserver(observer); -} +// Text of tooltip shown on when hovering over the user pod icon when unlock is +// not allowed. +const char kUserPodIconLockedTooltip[] = "Unable to find an unlocked phone."; -void ProximityAuthBleSystem::ScreenlockBridgeAdapter::Unlock( - ProximityAuthClient* client) { - screenlock_bridge_->Unlock(client->GetAuthenticatedUsername()); -} +} // namespace ProximityAuthBleSystem::ProximityAuthBleSystem( ScreenlockBridge* screenlock_bridge, ProximityAuthClient* proximity_auth_client, scoped_ptr<CryptAuthClientFactory> cryptauth_client_factory, PrefService* pref_service) - : screenlock_bridge_(new ProximityAuthBleSystem::ScreenlockBridgeAdapter( - screenlock_bridge)), + : screenlock_bridge_(screenlock_bridge), proximity_auth_client_(proximity_auth_client), cryptauth_client_factory_(cryptauth_client_factory.Pass()), device_whitelist_(new BluetoothLowEnergyDeviceWhitelist(pref_service)), bluetooth_throttler_(new BluetoothThrottlerImpl( make_scoped_ptr(new base::DefaultTickClock()))), device_authenticated_(false), - unlock_requested_(false), - is_polling_screen_state_(false), - unlock_keys_requested_(false), - weak_ptr_factory_(this) { - PA_LOG(INFO) << "Starting Proximity Auth over Bluetooth Low Energy."; - screenlock_bridge_->AddObserver(this); -} - -ProximityAuthBleSystem::ProximityAuthBleSystem( - scoped_ptr<ScreenlockBridgeAdapter> screenlock_bridge, - ProximityAuthClient* proximity_auth_client) - : screenlock_bridge_(screenlock_bridge.Pass()), - proximity_auth_client_(proximity_auth_client), - bluetooth_throttler_(new BluetoothThrottlerImpl( - make_scoped_ptr(new base::DefaultTickClock()))), - unlock_requested_(false), is_polling_screen_state_(false), unlock_keys_requested_(false), weak_ptr_factory_(this) { @@ -200,7 +171,6 @@ void ProximityAuthBleSystem::OnScreenDidLock( break; case ScreenlockBridge::LockHandler::LOCK_SCREEN: DCHECK(!connection_finder_); - unlock_requested_ = false; connection_finder_.reset(CreateConnectionFinder()); connection_finder_->Find( base::Bind(&ProximityAuthBleSystem::OnConnectionFound, @@ -210,6 +180,15 @@ void ProximityAuthBleSystem::OnScreenDidLock( connection_finder_.reset(); break; } + + // Reset the screen lock UI state to the default state. + is_remote_screen_locked_ = true; + screenlock_ui_state_ = ScreenlockUIState::NO_SCREENLOCK; + last_focused_user_ = screenlock_bridge_->focused_user_id(); + spinner_timer_.Start(FROM_HERE, + base::TimeDelta::FromSeconds(kSpinnerTimeSeconds), this, + &ProximityAuthBleSystem::OnSpinnerTimerFired); + UpdateLockScreenUI(); } ConnectionFinder* ProximityAuthBleSystem::CreateConnectionFinder() { @@ -232,13 +211,16 @@ void ProximityAuthBleSystem::OnScreenDidUnlock( device_authenticated_ = false; } - unlock_requested_ = false; connection_.reset(); connection_finder_.reset(); } void ProximityAuthBleSystem::OnFocusedUserChanged(const std::string& user_id) { PA_LOG(INFO) << "OnFocusedUserChanged: " << user_id; + // TODO(tengs): We assume that the last focused user is the one with Smart + // Lock enabled. This may not be the case for multiprofile scenarios. + last_focused_user_ = user_id; + UpdateLockScreenUI(); } void ProximityAuthBleSystem::OnMessageReceived(const Connection& connection, @@ -289,18 +271,30 @@ void ProximityAuthBleSystem::OnMessageReceived(const Connection& connection, return; } - // Unlock the screen when the remote device sends an unlock signal. - // - // Note that this magically unlocks Chrome (no user interaction is needed). - // This user experience for this operation will be greately improved once - // the Proximity Auth Unlock Manager migration to C++ is done. - if (message.payload() == kScreenUnlocked && !unlock_requested_) { - PA_LOG(INFO) << "Device unlocked. Unlock."; - screenlock_bridge_->Unlock(proximity_auth_client_); - unlock_requested_ = true; + if (message.payload() == kScreenUnlocked) { + is_remote_screen_locked_ = false; + spinner_timer_.Stop(); + UpdateLockScreenUI(); + } else if (message.payload() == kScreenLocked) { + is_remote_screen_locked_ = true; + UpdateLockScreenUI(); } } +void ProximityAuthBleSystem::OnAuthAttempted(const std::string& user_id) { + if (user_id != last_focused_user_) { + PA_LOG(ERROR) << "Unexpected user: " << last_focused_user_ + << " != " << user_id; + return; + } + + // Accept the auth attempt and authorize the screen unlock if the remote + // device is connected and its screen is unlocked. + bool accept_auth_attempt = connection_ && connection_->IsConnected() && + device_authenticated_ && !is_remote_screen_locked_; + proximity_auth_client_->FinalizeUnlock(accept_auth_attempt); +} + void ProximityAuthBleSystem::OnConnectionFound( scoped_ptr<Connection> connection) { PA_LOG(INFO) << "Connection found."; @@ -319,7 +313,9 @@ void ProximityAuthBleSystem::OnConnectionStatusChanged( if (old_status == Connection::CONNECTED && new_status == Connection::DISCONNECTED) { device_authenticated_ = false; + is_remote_screen_locked_ = true; StopPollingScreenState(); + UpdateLockScreenUI(); // Note: it's not necessary to destroy the |connection_| here, as it's // already in a DISCONNECTED state. Moreover, destroying it here can cause @@ -372,4 +368,70 @@ bool ProximityAuthBleSystem::HasUnlockKey(const std::string& message, device_whitelist_->HasDeviceWithPublicKey(public_key); } +void ProximityAuthBleSystem::OnSpinnerTimerFired() { + UpdateLockScreenUI(); +} + +void ProximityAuthBleSystem::UpdateLockScreenUI() { + ScreenlockUIState screenlock_ui_state = ScreenlockUIState::NO_SCREENLOCK; + + // TODO(tengs): We assume that the last focused user is the one with Smart + // Lock enabled. This may not be the case for multiprofile scenarios. + if (last_focused_user_.empty()) + return; + + // Check that the lock screen exists. + ScreenlockBridge::LockHandler* lock_handler = + screenlock_bridge_->lock_handler(); + if (!lock_handler) { + PA_LOG(WARNING) << "No LockHandler"; + return; + } + + // Check the current authentication state of the phone. + if (connection_ && connection_->IsConnected()) { + if (!device_authenticated_ || is_remote_screen_locked_) + screenlock_ui_state = ScreenlockUIState::UNAUTHENTICATED; + else + screenlock_ui_state = ScreenlockUIState::AUTHENTICATED; + } else if (spinner_timer_.IsRunning()) { + screenlock_ui_state = ScreenlockUIState::SPINNER; + } else { + screenlock_ui_state = ScreenlockUIState::UNAUTHENTICATED; + } + + if (screenlock_ui_state == screenlock_ui_state_) + return; + screenlock_ui_state_ = screenlock_ui_state; + + // Customize the user pod for the current UI state. + PA_LOG(INFO) << "Screenlock UI state changed: " + << static_cast<int>(screenlock_ui_state_); + ScreenlockBridge::UserPodCustomIconOptions icon_options; + ScreenlockBridge::LockHandler::AuthType auth_type = + ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; + base::string16 auth_value; + + switch (screenlock_ui_state_) { + case ScreenlockUIState::SPINNER: + icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_SPINNER); + break; + case ScreenlockUIState::UNAUTHENTICATED: + icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED); + break; + case ScreenlockUIState::AUTHENTICATED: + auth_value = base::UTF8ToUTF16(kUserPodUnlockText); + icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_UNLOCKED); + icon_options.SetTooltip(base::UTF8ToUTF16(kUserPodIconLockedTooltip), + false); + auth_type = ScreenlockBridge::LockHandler::USER_CLICK; + break; + default: + break; + } + + lock_handler->ShowUserPodCustomIcon(last_focused_user_, icon_options); + lock_handler->SetAuthType(last_focused_user_, auth_type, auth_value); +} + } // namespace proximity_auth diff --git a/components/proximity_auth/ble/proximity_auth_ble_system.h b/components/proximity_auth/ble/proximity_auth_ble_system.h index 2a82aea..2d3babd 100644 --- a/components/proximity_auth/ble/proximity_auth_ble_system.h +++ b/components/proximity_auth/ble/proximity_auth_ble_system.h @@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "components/proximity_auth/connection_observer.h" #include "components/proximity_auth/cryptauth/cryptauth_client.h" #include "components/proximity_auth/screenlock_bridge.h" @@ -63,28 +64,11 @@ class ProximityAuthBleSystem : public ScreenlockBridge::Observer, void OnMessageReceived(const Connection& connection, const WireMessage& message) override; - protected: - class ScreenlockBridgeAdapter { - public: - ScreenlockBridgeAdapter(ScreenlockBridge* screenlock_bridge); - virtual ~ScreenlockBridgeAdapter(); - - virtual void AddObserver(ScreenlockBridge::Observer* observer); - virtual void RemoveObserver(ScreenlockBridge::Observer* observer); - virtual void Unlock(ProximityAuthClient* client); - - protected: - ScreenlockBridgeAdapter(); - - private: - // Not owned. Must outlive this object. - ScreenlockBridge* screenlock_bridge_; - }; - - // Used for testing. - ProximityAuthBleSystem(scoped_ptr<ScreenlockBridgeAdapter> screenlock_bridge, - ProximityAuthClient* proximity_auth_client); + // Called by EasyUnlockService when the user clicks their user pod and + // initiates an auth attempt. + void OnAuthAttempted(const std::string& user_id); + protected: // Virtual for testing. virtual ConnectionFinder* CreateConnectionFinder(); @@ -114,7 +98,15 @@ class ProximityAuthBleSystem : public ScreenlockBridge::Observer, // |unlock_keys_|). If so, returns the public key in |out_public_key|. bool HasUnlockKey(const std::string& message, std::string* out_public_key); - scoped_ptr<ScreenlockBridgeAdapter> screenlock_bridge_; + // Called when |spinner_timer_| is fired to stop showing the spinner on the + // user pod. + void OnSpinnerTimerFired(); + + // Called to update the lock screen's UI for the current authentication state + // with the remote device. + void UpdateLockScreenUI(); + + ScreenlockBridge* screenlock_bridge_; // Not owned. Must outlive this object. ProximityAuthClient* proximity_auth_client_; @@ -142,16 +134,34 @@ class ProximityAuthBleSystem : public ScreenlockBridge::Observer, // |device_whitelist_|. bool device_authenticated_; - // True if the screen is locked and call to |screenlock_bridge_->Unlock()| was - // made, but |OnScreenDidUnlock| was not called yet. This is a guard to avoid - // a double |screenlock_bridge_->Unlock()| call. - bool unlock_requested_; - + // True if |this| instance is currently polling the phone for the phone's + // screenlock state. bool is_polling_screen_state_; // True if a call to |GetUnlockKeys()| was already made. bool unlock_keys_requested_; + // The user id or email of the last focused user on the lock screen. + std::string last_focused_user_; + + // True if the the last status update from the phone reports that the phone's + // screen is locked. If no status update has been received, this value is true + // by default. + bool is_remote_screen_locked_; + + // The timer controlling the time the spinner for the user pod icon is shown + // right after the screen is locked. + base::OneShotTimer<ProximityAuthBleSystem> spinner_timer_; + + // The different UI states that the lock screen can be in. + enum class ScreenlockUIState { + NO_SCREENLOCK, + SPINNER, + UNAUTHENTICATED, + AUTHENTICATED + }; + ScreenlockUIState screenlock_ui_state_; + base::WeakPtrFactory<ProximityAuthBleSystem> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ProximityAuthBleSystem); diff --git a/components/proximity_auth/ble/proximity_auth_ble_system_unittest.cc b/components/proximity_auth/ble/proximity_auth_ble_system_unittest.cc index b223e4a..e178a0b 100644 --- a/components/proximity_auth/ble/proximity_auth_ble_system_unittest.cc +++ b/components/proximity_auth/ble/proximity_auth_ble_system_unittest.cc @@ -6,7 +6,12 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" +#include "base/prefs/testing_pref_service.h" +#include "base/test/test_mock_time_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "components/proximity_auth/ble/bluetooth_low_energy_device_whitelist.h" #include "components/proximity_auth/connection_finder.h" +#include "components/proximity_auth/cryptauth/mock_cryptauth_client.h" #include "components/proximity_auth/proximity_auth_client.h" #include "components/proximity_auth/screenlock_bridge.h" #include "testing/gmock/include/gmock/gmock.h" @@ -17,7 +22,9 @@ using testing::NiceMock; using testing::Return; namespace proximity_auth { + namespace { + class MockConnectionFinder : public ConnectionFinder { public: MockConnectionFinder() {} @@ -26,23 +33,63 @@ class MockConnectionFinder : public ConnectionFinder { MOCK_METHOD1(Find, void(const ConnectionCallback&)); }; -} // namespace +class MockLockHandler : public ScreenlockBridge::LockHandler { + public: + MockLockHandler() {} + ~MockLockHandler() {} + + // ScreenlockBridge::LockHandler: + MOCK_METHOD1(ShowBannerMessage, void(const base::string16& message)); + MOCK_METHOD2(ShowUserPodCustomIcon, + void(const std::string& user_email, + const ScreenlockBridge::UserPodCustomIconOptions& icon)); + MOCK_METHOD1(HideUserPodCustomIcon, void(const std::string& user_email)); + MOCK_METHOD0(EnableInput, void()); + MOCK_METHOD3(SetAuthType, + void(const std::string& user_email, + AuthType auth_type, + const base::string16& auth_value)); + MOCK_CONST_METHOD1(GetAuthType, AuthType(const std::string& user_email)); + MOCK_CONST_METHOD0(GetScreenType, ScreenType()); + MOCK_METHOD1(Unlock, void(const std::string& user_email)); + MOCK_METHOD3(AttemptEasySignin, + void(const std::string& user_email, + const std::string& secret, + const std::string& key_label)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockLockHandler); +}; -class ProximityAuthBleSystemTestable : public ProximityAuthBleSystem { +const char kTestUser[] = "example@gmail.com"; + +class MockProximityAuthClient : public ProximityAuthClient { public: - class MockScreenlockBridgeAdapter - : public ProximityAuthBleSystem::ScreenlockBridgeAdapter { - public: - MockScreenlockBridgeAdapter() {} - ~MockScreenlockBridgeAdapter() {} + MockProximityAuthClient() {} + ~MockProximityAuthClient() override {} - MOCK_METHOD1(AddObserver, void(ScreenlockBridge::Observer*)); - MOCK_METHOD1(RemoveObserver, void(ScreenlockBridge::Observer*)); - MOCK_METHOD1(Unlock, void(ProximityAuthClient*)); - }; + // ProximityAuthClient: + std::string GetAuthenticatedUsername() const override { return kTestUser; } - ProximityAuthBleSystemTestable(ScreenlockBridgeAdapter* screenlock_bridge) - : ProximityAuthBleSystem(make_scoped_ptr(screenlock_bridge), nullptr) {} + MOCK_METHOD1(FinalizeUnlock, void(bool)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockProximityAuthClient); +}; + +} // namespace + +class ProximityAuthBleSystemTestable : public ProximityAuthBleSystem { + public: + ProximityAuthBleSystemTestable( + ScreenlockBridge* screenlock_bridge, + ProximityAuthClient* proximity_auth_client, + scoped_ptr<CryptAuthClientFactory> cryptauth_client_factory, + PrefService* pref_service) + : ProximityAuthBleSystem(screenlock_bridge, + proximity_auth_client, + cryptauth_client_factory.Pass(), + pref_service) {} ConnectionFinder* CreateConnectionFinder() override { return new NiceMock<MockConnectionFinder>(); @@ -52,55 +99,60 @@ class ProximityAuthBleSystemTestable : public ProximityAuthBleSystem { class ProximityAuthBleSystemTest : public testing::Test { protected: ProximityAuthBleSystemTest() - : screenlock_bridge_(new NiceMock< - ProximityAuthBleSystemTestable::MockScreenlockBridgeAdapter>) {} + : task_runner_(new base::TestMockTimeTaskRunner), + runner_handle_(task_runner_) {} + + void SetUp() override { + BluetoothLowEnergyDeviceWhitelist::RegisterPrefs(pref_service_.registry()); - void SetExpectations() { - EXPECT_CALL(*screenlock_bridge_, AddObserver(_)); - EXPECT_CALL(*screenlock_bridge_, RemoveObserver(_)); + scoped_ptr<CryptAuthClientFactory> cryptauth_client_factory( + new MockCryptAuthClientFactory( + MockCryptAuthClientFactory::MockType::MAKE_NICE_MOCKS)); + + proximity_auth_system_.reset(new ProximityAuthBleSystemTestable( + ScreenlockBridge::Get(), &proximity_auth_client_, + cryptauth_client_factory.Pass(), &pref_service_)); } - ProximityAuthBleSystemTestable::MockScreenlockBridgeAdapter* - screenlock_bridge_; -}; + // Injects the thread's TaskRunner for testing. + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + base::ThreadTaskRunnerHandle runner_handle_; -TEST_F(ProximityAuthBleSystemTest, ConstructAndDestroyShouldNotCrash) { - SetExpectations(); + NiceMock<MockProximityAuthClient> proximity_auth_client_; + TestingPrefServiceSimple pref_service_; + scoped_ptr<ProximityAuthBleSystem> proximity_auth_system_; - ProximityAuthBleSystemTestable proximity_auth_system(screenlock_bridge_); -} + NiceMock<MockLockHandler> lock_handler_; +}; -TEST_F(ProximityAuthBleSystemTest, - OnScreenDidLock_OnLockScreenEvent_OnScreenDidUnlock) { - SetExpectations(); +TEST_F(ProximityAuthBleSystemTest, LockAndUnlock_LockScreen) { + // Lock the screen. + ON_CALL(lock_handler_, GetScreenType()) + .WillByDefault(Return(ScreenlockBridge::LockHandler::LOCK_SCREEN)); + ScreenlockBridge::Get()->SetLockHandler(&lock_handler_); - ProximityAuthBleSystemTestable proximity_auth_system(screenlock_bridge_); - proximity_auth_system.OnScreenDidLock( - ScreenlockBridge::LockHandler::LOCK_SCREEN); - proximity_auth_system.OnScreenDidUnlock( - ScreenlockBridge::LockHandler::LOCK_SCREEN); + // Unlock the screen. + ScreenlockBridge::Get()->SetLockHandler(nullptr); } -TEST_F(ProximityAuthBleSystemTest, - OnScreenDidLock_OnSigninScreenEvent_OnScreenDidUnlock) { - SetExpectations(); +TEST_F(ProximityAuthBleSystemTest, LockAndUnlock_SigninScreen) { + // Show the sign-in screen. + ON_CALL(lock_handler_, GetScreenType()) + .WillByDefault(Return(ScreenlockBridge::LockHandler::SIGNIN_SCREEN)); + ScreenlockBridge::Get()->SetLockHandler(&lock_handler_); - ProximityAuthBleSystemTestable proximity_auth_system(screenlock_bridge_); - proximity_auth_system.OnScreenDidLock( - ScreenlockBridge::LockHandler::SIGNIN_SCREEN); - proximity_auth_system.OnScreenDidUnlock( - ScreenlockBridge::LockHandler::SIGNIN_SCREEN); + // Sign-in. + ScreenlockBridge::Get()->SetLockHandler(nullptr); } -TEST_F(ProximityAuthBleSystemTest, - OnScreenDidLock_OnOtherScreenEvent_OnScreenDidUnlock) { - SetExpectations(); +TEST_F(ProximityAuthBleSystemTest, LockAndUnlock_OtherScreen) { + // Show the screen. + ON_CALL(lock_handler_, GetScreenType()) + .WillByDefault(Return(ScreenlockBridge::LockHandler::OTHER_SCREEN)); + ScreenlockBridge::Get()->SetLockHandler(&lock_handler_); - ProximityAuthBleSystemTestable proximity_auth_system(screenlock_bridge_); - proximity_auth_system.OnScreenDidLock( - ScreenlockBridge::LockHandler::OTHER_SCREEN); - proximity_auth_system.OnScreenDidUnlock( - ScreenlockBridge::LockHandler::OTHER_SCREEN); + // Hide the screen. + ScreenlockBridge::Get()->SetLockHandler(nullptr); } } // namespace proximity_auth diff --git a/components/proximity_auth/cryptauth/mock_cryptauth_client.cc b/components/proximity_auth/cryptauth/mock_cryptauth_client.cc index 834fd74..05f9ac6 100644 --- a/components/proximity_auth/cryptauth/mock_cryptauth_client.cc +++ b/components/proximity_auth/cryptauth/mock_cryptauth_client.cc @@ -4,7 +4,6 @@ #include "base/callback.h" #include "components/proximity_auth/cryptauth/mock_cryptauth_client.h" -#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" namespace proximity_auth { diff --git a/components/proximity_auth/cryptauth/mock_cryptauth_client.h b/components/proximity_auth/cryptauth/mock_cryptauth_client.h index 27bfd13..59d1926 100644 --- a/components/proximity_auth/cryptauth/mock_cryptauth_client.h +++ b/components/proximity_auth/cryptauth/mock_cryptauth_client.h @@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "components/proximity_auth/cryptauth/cryptauth_client.h" +#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" #include "testing/gmock/include/gmock/gmock.h" namespace proximity_auth { diff --git a/components/proximity_auth/proximity_auth_client.h b/components/proximity_auth/proximity_auth_client.h index 7a26778..eb846cd 100644 --- a/components/proximity_auth/proximity_auth_client.h +++ b/components/proximity_auth/proximity_auth_client.h @@ -18,6 +18,11 @@ class ProximityAuthClient { // Returns the authenticated username. virtual std::string GetAuthenticatedUsername() const = 0; + + // Finalizes an unlock attempt initiated by the user. If |success| is true, + // the screen is unlocked; otherwise, the auth attempt is rejected. An auth + // attempt must be in progress before calling this function. + virtual void FinalizeUnlock(bool success) = 0; }; } // namespace proximity_auth |