proximity_auth_system.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright 2014 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/proximity_auth_system.h"
  5. #include "ash/components/multidevice/logging/logging.h"
  6. #include "ash/components/proximity_auth/proximity_auth_client.h"
  7. #include "ash/components/proximity_auth/remote_device_life_cycle_impl.h"
  8. #include "ash/components/proximity_auth/unlock_manager_impl.h"
  9. #include "ash/constants/ash_features.h"
  10. #include "ash/services/secure_channel/public/cpp/client/secure_channel_client.h"
  11. namespace proximity_auth {
  12. ProximityAuthSystem::ProximityAuthSystem(
  13. ScreenlockType screenlock_type,
  14. ProximityAuthClient* proximity_auth_client,
  15. ash::secure_channel::SecureChannelClient* secure_channel_client)
  16. : secure_channel_client_(secure_channel_client),
  17. unlock_manager_(
  18. std::make_unique<UnlockManagerImpl>(screenlock_type,
  19. proximity_auth_client)) {}
  20. ProximityAuthSystem::ProximityAuthSystem(
  21. ash::secure_channel::SecureChannelClient* secure_channel_client,
  22. std::unique_ptr<UnlockManager> unlock_manager)
  23. : secure_channel_client_(secure_channel_client),
  24. unlock_manager_(std::move(unlock_manager)) {}
  25. ProximityAuthSystem::~ProximityAuthSystem() {
  26. ScreenlockBridge::Get()->RemoveObserver(this);
  27. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  28. }
  29. void ProximityAuthSystem::Start() {
  30. if (started_)
  31. return;
  32. started_ = true;
  33. ScreenlockBridge::Get()->AddObserver(this);
  34. const AccountId& focused_account_id =
  35. ScreenlockBridge::Get()->focused_account_id();
  36. if (focused_account_id.is_valid())
  37. OnFocusedUserChanged(focused_account_id);
  38. }
  39. void ProximityAuthSystem::Stop() {
  40. if (!started_)
  41. return;
  42. started_ = false;
  43. ScreenlockBridge::Get()->RemoveObserver(this);
  44. OnFocusedUserChanged(EmptyAccountId());
  45. }
  46. void ProximityAuthSystem::SetRemoteDevicesForUser(
  47. const AccountId& account_id,
  48. const ash::multidevice::RemoteDeviceRefList& remote_devices,
  49. absl::optional<ash::multidevice::RemoteDeviceRef> local_device) {
  50. PA_LOG(VERBOSE) << "Setting devices for user " << account_id.Serialize()
  51. << ". Remote device count: " << remote_devices.size()
  52. << ", Local device: ["
  53. << (local_device.has_value() ? "present" : "absent") << "].";
  54. remote_devices_map_[account_id] = remote_devices;
  55. if (local_device) {
  56. local_device_map_.emplace(account_id, *local_device);
  57. } else {
  58. local_device_map_.erase(account_id);
  59. }
  60. if (started_) {
  61. const AccountId& focused_account_id =
  62. ScreenlockBridge::Get()->focused_account_id();
  63. if (focused_account_id.is_valid())
  64. OnFocusedUserChanged(focused_account_id);
  65. }
  66. }
  67. ash::multidevice::RemoteDeviceRefList
  68. ProximityAuthSystem::GetRemoteDevicesForUser(
  69. const AccountId& account_id) const {
  70. if (remote_devices_map_.find(account_id) == remote_devices_map_.end())
  71. return ash::multidevice::RemoteDeviceRefList();
  72. return remote_devices_map_.at(account_id);
  73. }
  74. void ProximityAuthSystem::OnAuthAttempted() {
  75. unlock_manager_->OnAuthAttempted(mojom::AuthType::USER_CLICK);
  76. }
  77. void ProximityAuthSystem::OnSuspend() {
  78. PA_LOG(INFO) << "Preparing for device suspension.";
  79. DCHECK(!suspended_);
  80. suspended_ = true;
  81. OnSuspendOrScreenOffChange();
  82. }
  83. void ProximityAuthSystem::OnSuspendDone() {
  84. PA_LOG(INFO) << "Device resumed from suspension.";
  85. DCHECK(suspended_);
  86. suspended_ = false;
  87. OnSuspendOrScreenOffChange();
  88. }
  89. void ProximityAuthSystem::OnScreenOff() {
  90. if (!base::FeatureList::IsEnabled(
  91. ash::features::kSmartLockBluetoothScreenOffFix)) {
  92. return;
  93. }
  94. PA_LOG(INFO) << "Screen is off.";
  95. DCHECK(!screen_off_);
  96. screen_off_ = true;
  97. OnSuspendOrScreenOffChange();
  98. }
  99. void ProximityAuthSystem::OnScreenOffDone() {
  100. if (!base::FeatureList::IsEnabled(
  101. ash::features::kSmartLockBluetoothScreenOffFix)) {
  102. return;
  103. }
  104. // It's possible to end up here when the screen is dimmed and the screen_off_
  105. // boolean was not true, in which case we can return early.
  106. if (!screen_off_)
  107. return;
  108. PA_LOG(INFO) << "Screen is on.";
  109. screen_off_ = false;
  110. OnSuspendOrScreenOffChange();
  111. }
  112. void ProximityAuthSystem::CancelConnectionAttempt() {
  113. unlock_manager_->CancelConnectionAttempt();
  114. }
  115. std::unique_ptr<RemoteDeviceLifeCycle>
  116. ProximityAuthSystem::CreateRemoteDeviceLifeCycle(
  117. ash::multidevice::RemoteDeviceRef remote_device,
  118. absl::optional<ash::multidevice::RemoteDeviceRef> local_device) {
  119. return std::make_unique<RemoteDeviceLifeCycleImpl>(
  120. remote_device, local_device, secure_channel_client_);
  121. }
  122. void ProximityAuthSystem::OnScreenDidLock(
  123. ScreenlockBridge::LockHandler::ScreenType screen_type) {
  124. const AccountId& focused_account_id =
  125. ScreenlockBridge::Get()->focused_account_id();
  126. if (focused_account_id.is_valid())
  127. OnFocusedUserChanged(focused_account_id);
  128. }
  129. void ProximityAuthSystem::OnScreenDidUnlock(
  130. ScreenlockBridge::LockHandler::ScreenType screen_type) {
  131. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  132. remote_device_life_cycle_.reset();
  133. }
  134. void ProximityAuthSystem::OnFocusedUserChanged(const AccountId& account_id) {
  135. // Update the current RemoteDeviceLifeCycle to the focused user.
  136. if (remote_device_life_cycle_) {
  137. if (remote_device_life_cycle_->GetRemoteDevice().user_email() !=
  138. account_id.GetUserEmail()) {
  139. PA_LOG(INFO) << "Focused user changed, destroying life cycle for "
  140. << account_id.Serialize() << ".";
  141. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  142. remote_device_life_cycle_.reset();
  143. } else {
  144. PA_LOG(INFO) << "Refocused on a user who is already focused.";
  145. return;
  146. }
  147. }
  148. if (remote_devices_map_.find(account_id) == remote_devices_map_.end() ||
  149. remote_devices_map_[account_id].size() == 0) {
  150. PA_LOG(INFO) << "User " << account_id.Serialize()
  151. << " does not have a Smart Lock host device.";
  152. return;
  153. }
  154. if (local_device_map_.find(account_id) == local_device_map_.end()) {
  155. PA_LOG(INFO) << "User " << account_id.Serialize()
  156. << " does not have a local device.";
  157. return;
  158. }
  159. // TODO(tengs): We currently assume each user has only one RemoteDevice, so we
  160. // can simply take the first item in the list.
  161. ash::multidevice::RemoteDeviceRef remote_device =
  162. remote_devices_map_[account_id][0];
  163. absl::optional<ash::multidevice::RemoteDeviceRef> local_device;
  164. local_device = local_device_map_.at(account_id);
  165. if (!suspended_ && !screen_off_) {
  166. PA_LOG(INFO) << "Creating RemoteDeviceLifeCycle for focused user: "
  167. << account_id.Serialize();
  168. remote_device_life_cycle_ =
  169. CreateRemoteDeviceLifeCycle(remote_device, local_device);
  170. // UnlockManager listens for Bluetooth power change events, and is therefore
  171. // responsible for starting RemoteDeviceLifeCycle when Bluetooth becomes
  172. // powered.
  173. unlock_manager_->SetRemoteDeviceLifeCycle(remote_device_life_cycle_.get());
  174. }
  175. }
  176. std::string ProximityAuthSystem::GetLastRemoteStatusUnlockForLogging() {
  177. if (unlock_manager_) {
  178. return unlock_manager_->GetLastRemoteStatusUnlockForLogging();
  179. }
  180. return std::string();
  181. }
  182. void ProximityAuthSystem::OnSuspendOrScreenOffChange() {
  183. if (suspended_ || screen_off_) {
  184. unlock_manager_->SetRemoteDeviceLifeCycle(nullptr);
  185. remote_device_life_cycle_.reset();
  186. return;
  187. }
  188. if (!ScreenlockBridge::Get()->IsLocked()) {
  189. PA_LOG(INFO) << "System resumed, but no lock screen.";
  190. } else if (!started_) {
  191. PA_LOG(INFO) << "System resumed, but ProximityAuthSystem is stopped.";
  192. } else {
  193. OnFocusedUserChanged(ScreenlockBridge::Get()->focused_account_id());
  194. }
  195. }
  196. } // namespace proximity_auth