unlock_manager_impl.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. #ifndef ASH_COMPONENTS_PROXIMITY_AUTH_UNLOCK_MANAGER_IMPL_H_
  5. #define ASH_COMPONENTS_PROXIMITY_AUTH_UNLOCK_MANAGER_IMPL_H_
  6. #include "ash/components/proximity_auth/messenger_observer.h"
  7. #include "ash/components/proximity_auth/proximity_auth_system.h"
  8. #include "ash/components/proximity_auth/proximity_monitor_observer.h"
  9. #include "ash/components/proximity_auth/remote_device_life_cycle.h"
  10. #include "ash/components/proximity_auth/remote_status_update.h"
  11. #include "ash/components/proximity_auth/screenlock_bridge.h"
  12. #include "ash/components/proximity_auth/smart_lock_metrics_recorder.h"
  13. #include "ash/components/proximity_auth/unlock_manager.h"
  14. #include "ash/public/cpp/smartlock_state.h"
  15. #include "ash/services/secure_channel/public/mojom/secure_channel.mojom.h"
  16. #include "base/memory/ref_counted.h"
  17. #include "base/memory/weak_ptr.h"
  18. #include "base/time/time.h"
  19. #include "build/build_config.h"
  20. #include "chromeos/dbus/power/power_manager_client.h"
  21. #include "device/bluetooth/bluetooth_adapter.h"
  22. namespace base {
  23. class OneShotTimer;
  24. } // namespace base
  25. namespace proximity_auth {
  26. class Messenger;
  27. class ProximityAuthClient;
  28. class ProximityMonitor;
  29. // The unlock manager is responsible for controlling the lock screen UI based on
  30. // the authentication status of the registered remote devices.
  31. class UnlockManagerImpl : public UnlockManager,
  32. public MessengerObserver,
  33. public ProximityMonitorObserver,
  34. public chromeos::PowerManagerClient::Observer,
  35. public device::BluetoothAdapter::Observer,
  36. public RemoteDeviceLifeCycle::Observer {
  37. public:
  38. // The |proximity_auth_client| is not owned and should outlive the constructed
  39. // unlock manager.
  40. UnlockManagerImpl(ProximityAuthSystem::ScreenlockType screenlock_type,
  41. ProximityAuthClient* proximity_auth_client);
  42. UnlockManagerImpl(const UnlockManagerImpl&) = delete;
  43. UnlockManagerImpl& operator=(const UnlockManagerImpl&) = delete;
  44. ~UnlockManagerImpl() override;
  45. // UnlockManager:
  46. bool IsUnlockAllowed() override;
  47. void SetRemoteDeviceLifeCycle(RemoteDeviceLifeCycle* life_cycle) override;
  48. void OnAuthAttempted(mojom::AuthType auth_type) override;
  49. void CancelConnectionAttempt() override;
  50. std::string GetLastRemoteStatusUnlockForLogging() override;
  51. protected:
  52. // Creates a ProximityMonitor instance for the given |connection|.
  53. // Exposed for testing.
  54. virtual std::unique_ptr<ProximityMonitor> CreateProximityMonitor(
  55. RemoteDeviceLifeCycle* life_cycle);
  56. private:
  57. friend class ProximityAuthUnlockManagerImplTest;
  58. // The possible lock screen states for the remote device.
  59. enum class RemoteScreenlockState {
  60. UNKNOWN,
  61. UNLOCKED,
  62. DISABLED,
  63. LOCKED,
  64. PRIMARY_USER_ABSENT,
  65. };
  66. // This enum is tied directly to a UMA enum defined in
  67. // //tools/metrics/histograms/enums.xml, and should always reflect it (do not
  68. // change one without changing the other). Entries should be never modified
  69. // or deleted. Only additions possible.
  70. enum class GetRemoteStatusResultFailureReason {
  71. kCanceledBluetoothDisabled = 0,
  72. kDeprecatedTimedOutCouldNotEstablishAuthenticatedChannel = 1,
  73. kTimedOutDidNotReceiveRemoteStatusUpdate = 2,
  74. kDeprecatedUserEnteredPasswordWhileBluetoothDisabled = 3,
  75. kCanceledUserEnteredPassword = 4,
  76. kAuthenticatedChannelDropped = 5,
  77. kMaxValue = kAuthenticatedChannelDropped
  78. };
  79. // MessengerObserver:
  80. void OnUnlockEventSent(bool success) override;
  81. void OnRemoteStatusUpdate(const RemoteStatusUpdate& status_update) override;
  82. void OnDecryptResponse(const std::string& decrypted_bytes) override;
  83. void OnUnlockResponse(bool success) override;
  84. void OnDisconnected() override;
  85. // ProximityMonitorObserver:
  86. void OnProximityStateChanged() override;
  87. // Called when the screenlock state changes.
  88. void OnScreenLockedOrUnlocked(bool is_locked);
  89. // Called when the Bluetooth adapter is initialized.
  90. void OnBluetoothAdapterInitialized(
  91. scoped_refptr<device::BluetoothAdapter> adapter);
  92. // device::BluetoothAdapter::Observer:
  93. void AdapterPresentChanged(device::BluetoothAdapter* adapter,
  94. bool present) override;
  95. void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
  96. bool powered) override;
  97. // chromeos::PowerManagerClient::Observer:
  98. void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
  99. void SuspendDone(base::TimeDelta sleep_duration) override;
  100. // RemoteDeviceLifeCycle::Observer:
  101. void OnLifeCycleStateChanged(RemoteDeviceLifeCycle::State old_state,
  102. RemoteDeviceLifeCycle::State new_state) override;
  103. // Returns true if the BluetoothAdapter is present and powered.
  104. bool IsBluetoothPresentAndPowered() const;
  105. // TODO(crbug.com/986896): Waiting a certain time, after resume, before
  106. // trusting the presence and power values returned by BluetoothAdapter is
  107. // necessary because the BluetoothAdapter returns incorrect values directly
  108. // after resume, and does not return correct values until about 1-2 seconds
  109. // later. Remove this function once the bug is resolved.
  110. //
  111. // This function returns true if the BluetoothAdapter is still resuming from
  112. // suspension, indicating that its returned presence and power values cannot
  113. // yet be trusted.
  114. bool IsBluetoothAdapterRecoveringFromSuspend() const;
  115. // Called once BluetoothAdapter has recovered after resuming from suspend,
  116. // meaning its presence and power values can be trusted again. This method
  117. // checks if Bluetooth is enabled; if it is not, it cancels the initial scan.
  118. void OnBluetoothAdapterPresentAndPoweredChanged();
  119. // If the RemoteDeviceLifeCycle is available, ensure it is started (but only
  120. // if Bluetooth is available).
  121. void AttemptToStartRemoteDeviceLifecycle();
  122. // Called when auth is attempted to send the sign-in challenge to the remote
  123. // device for decryption.
  124. void SendSignInChallenge();
  125. // Once the connection metadata is received from a ClientChannel, its channel
  126. // binding data can be used to finish a sign-in request.
  127. void OnGetConnectionMetadata(ash::secure_channel::mojom::ConnectionMetadataPtr
  128. connection_metadata_ptr);
  129. // Called with the sign-in |challenge| so we can send it to the remote device
  130. // for decryption.
  131. void OnGotSignInChallenge(const std::string& challenge);
  132. // Returns the current state for the Smart Lock UI.
  133. ash::SmartLockState GetSmartLockState();
  134. // Updates the lock screen based on the manager's current state.
  135. void UpdateLockScreen();
  136. // Activates or deactivates the proximity monitor, as appropriate given the
  137. // current state of |this| unlock manager.
  138. void UpdateProximityMonitorState();
  139. // Sets if the "initial scan" is in progress. This state factors into what is
  140. // shown to the user. See |is_performing_initial_scan_| for more.
  141. void SetIsPerformingInitialScan(bool is_performing_initial_scan);
  142. // Accepts or rejects the current auth attempt according to |error|. Accepts
  143. // if and only if |error| is empty. If the auth attempt is accepted, unlocks
  144. // the screen.
  145. void FinalizeAuthAttempt(
  146. const absl::optional<
  147. SmartLockMetricsRecorder::SmartLockAuthResultFailureReason>& error);
  148. // Failed to create a connection to the host during the "initial scan". See
  149. // |is_performing_initial_scan_| for more.
  150. void OnInitialScanTimeout();
  151. // Returns the screen lock state corresponding to the given remote |status|
  152. // update.
  153. RemoteScreenlockState GetScreenlockStateFromRemoteUpdate(
  154. RemoteStatusUpdate update);
  155. // Returns the Messenger instance associated with |life_cycle_|. This function
  156. // will return nullptr if |life_cycle_| is not set or the remote device is not
  157. // yet authenticated.
  158. Messenger* GetMessenger();
  159. // Records UMA performance metrics for the first remote status (regardless of
  160. // whether it's unlockable) being received.
  161. void RecordFirstRemoteStatusReceived(bool unlockable);
  162. // Records a UMA metric for the first status shown to the user as well
  163. // as performance metrics for how long it takes to show that first status
  164. // (regardless of whether it's unlockable/green).
  165. void RecordFirstStatusShownToUser(ash::SmartLockState new_state);
  166. // Clears the timers for beginning a scan and fetching remote status.
  167. void ResetPerformanceMetricsTimestamps();
  168. void SetBluetoothSuspensionRecoveryTimerForTesting(
  169. std::unique_ptr<base::OneShotTimer> timer);
  170. // For recording metrics.
  171. void RecordGetRemoteStatusResultSuccess(
  172. ProximityAuthSystem::ScreenlockType screenlock_type,
  173. bool success = true);
  174. void RecordGetRemoteStatusResultFailure(
  175. ProximityAuthSystem::ScreenlockType screenlock_type,
  176. GetRemoteStatusResultFailureReason failure_reason);
  177. std::string GetRemoteStatusResultFailureReasonToString(
  178. GetRemoteStatusResultFailureReason reason);
  179. // Whether |this| manager is being used for sign-in or session unlock.
  180. const ProximityAuthSystem::ScreenlockType screenlock_type_;
  181. // Used to call into the embedder. Expected to outlive |this| instance.
  182. ProximityAuthClient* proximity_auth_client_;
  183. // Starts running after resuming from suspension, and fires once enough time
  184. // has elapsed such that the BluetoothAdapter's presence and power values can
  185. // be trusted again. To be removed once https://crbug.com/986896 is fixed.
  186. std::unique_ptr<base::OneShotTimer> bluetooth_suspension_recovery_timer_;
  187. // The Bluetooth adapter. Null if there is no adapter present on the local
  188. // device.
  189. scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
  190. // Tracks whether the remote device is currently in close enough proximity to
  191. // the local device to allow unlocking.
  192. std::unique_ptr<ProximityMonitor> proximity_monitor_;
  193. // Whether the user is present at the remote device. Unset if no remote status
  194. // update has yet been received.
  195. std::unique_ptr<RemoteScreenlockState> remote_screenlock_state_;
  196. // The sign-in secret received from the remote device by decrypting the
  197. // sign-in challenge.
  198. std::unique_ptr<std::string> sign_in_secret_;
  199. // Controls the proximity auth flow logic for a remote device. Not owned, and
  200. // expcted to outlive |this| instance.
  201. RemoteDeviceLifeCycle* life_cycle_ = nullptr;
  202. // True if the manager is currently processing a user-initiated authentication
  203. // attempt, which is initiated when the user pod is clicked.
  204. bool is_attempting_auth_ = false;
  205. // If true, either the lock screen was just shown (after resuming from
  206. // suspend, or directly locking the screen), or the focused user pod was
  207. // switched. It becomes false if the phone is found, something goes wrong
  208. // while searching for the phone, or the initial scan times out (at which
  209. // point the user visually sees an indication that the phone cannot be found).
  210. // Though this field becomes false after this timeout, Smart Lock continues
  211. // to scan for the phone until the user unlocks the screen.
  212. bool is_performing_initial_scan_ = false;
  213. // True if a secure connection is currently active with the host.
  214. bool is_bluetooth_connection_to_phone_active_ = false;
  215. // TODO(crbug.com/986896): For a short time window after resuming from
  216. // suspension, BluetoothAdapter returns incorrect presence and power values.
  217. // This field acts as a cache in case we need to check those values during
  218. // that time window when the device resumes. Remove this field once the bug
  219. // is fixed.
  220. bool was_bluetooth_present_and_powered_before_last_suspend_ = false;
  221. // True only if the remote device has responded with a remote status, either
  222. // "unlockable" or otherwise.
  223. bool has_received_first_remote_status_ = false;
  224. // True only if the user has been shown a Smart Lock status and tooltip,
  225. // either "unlockable" (green) or otherwise (yellow).
  226. bool has_user_been_shown_first_status_ = false;
  227. // The state of the current screen lock UI.
  228. ash::SmartLockState smartlock_state_ = ash::SmartLockState::kInactive;
  229. // The timestamp of when the lock or login screen is shown to the user. Begins
  230. // when the screen is locked, the system is rebooted, the clamshell lid is
  231. // opened, or another user pod is switched to on the login screen.
  232. base::Time show_lock_screen_time_;
  233. // The timestamp of when UnlockManager begins to perform the initial scan for
  234. // the requested remote device of the provided RemoteDeviceLifeCycle. Usually
  235. // begins right after |show_lock_screen_time_|, unless Bluetooth is disabled.
  236. // If Bluetooth is re-enabled, it also begins.
  237. base::Time initial_scan_start_time_;
  238. // The timestamp of when UnlockManager successfully establishes a secure
  239. // connection to the requested remote device of the provided
  240. // RemoteDeviceLifeCycle, and begins to try to fetch its "remote status".
  241. base::Time attempt_get_remote_status_start_time_;
  242. // Stores the last value emitted to the
  243. // SmartLock.GetRemoteStatus.Unlock(.Failure) metrics. Should be |nullopt|
  244. // until the first time GetRemoteStatus succeeds or fails.
  245. absl::optional<bool> get_remote_status_unlock_success_;
  246. absl::optional<GetRemoteStatusResultFailureReason>
  247. get_remote_status_unlock_failure_reason_;
  248. // Used to track if the "initial scan" has timed out. See
  249. // |is_performing_initial_scan_| for more.
  250. base::WeakPtrFactory<UnlockManagerImpl>
  251. initial_scan_timeout_weak_ptr_factory_{this};
  252. // Used to reject auth attempts after a timeout. An in-progress auth attempt
  253. // blocks the sign-in screen UI, so it's important to prevent the auth attempt
  254. // from blocking the UI in case a step in the code path hangs.
  255. base::WeakPtrFactory<UnlockManagerImpl> reject_auth_attempt_weak_ptr_factory_{
  256. this};
  257. // Used to vend all other weak pointers.
  258. base::WeakPtrFactory<UnlockManagerImpl> weak_ptr_factory_{this};
  259. };
  260. } // namespace proximity_auth
  261. #endif // ASH_COMPONENTS_PROXIMITY_AUTH_UNLOCK_MANAGER_IMPL_H_