Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/components/tether/message_transfer_operation.h" | 5 #include "chromeos/components/tether/message_transfer_operation.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "chromeos/components/tether/message_wrapper.h" | 9 #include "chromeos/components/tether/message_wrapper.h" |
| 10 #include "chromeos/components/tether/timer_factory.h" | |
| 10 #include "components/proximity_auth/logging/logging.h" | 11 #include "components/proximity_auth/logging/logging.h" |
| 11 | 12 |
| 12 namespace chromeos { | 13 namespace chromeos { |
| 13 | 14 |
| 14 namespace tether { | 15 namespace tether { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 std::vector<cryptauth::RemoteDevice> RemoveDuplicatesFromVector( | 19 std::vector<cryptauth::RemoteDevice> RemoveDuplicatesFromVector( |
| 19 const std::vector<cryptauth::RemoteDevice>& remote_devices) { | 20 const std::vector<cryptauth::RemoteDevice>& remote_devices) { |
| 20 std::vector<cryptauth::RemoteDevice> updated_remote_devices; | 21 std::vector<cryptauth::RemoteDevice> updated_remote_devices; |
| 21 std::set<cryptauth::RemoteDevice> remote_devices_set; | 22 std::set<cryptauth::RemoteDevice> remote_devices_set; |
| 22 for (const auto& remote_device : remote_devices) { | 23 for (const auto& remote_device : remote_devices) { |
| 23 // Only add the device to the output vector if it has not already been put | 24 // Only add the device to the output vector if it has not already been put |
| 24 // into the set. | 25 // into the set. |
| 25 if (remote_devices_set.find(remote_device) == remote_devices_set.end()) { | 26 if (remote_devices_set.find(remote_device) == remote_devices_set.end()) { |
| 26 remote_devices_set.insert(remote_device); | 27 remote_devices_set.insert(remote_device); |
| 27 updated_remote_devices.push_back(remote_device); | 28 updated_remote_devices.push_back(remote_device); |
| 28 } | 29 } |
| 29 } | 30 } |
| 30 return updated_remote_devices; | 31 return updated_remote_devices; |
| 31 } | 32 } |
| 32 | 33 |
| 33 } // namespace | 34 } // namespace |
| 34 | 35 |
| 35 // static | 36 // static |
| 36 uint32_t MessageTransferOperation::kMaxConnectionAttemptsPerDevice = 3; | 37 uint32_t MessageTransferOperation::kMaxConnectionAttemptsPerDevice = 3; |
| 37 | 38 |
| 39 // static | |
| 40 uint32_t MessageTransferOperation::kResponseTimeoutSeconds = 10; | |
| 41 | |
| 38 MessageTransferOperation::MessageTransferOperation( | 42 MessageTransferOperation::MessageTransferOperation( |
| 39 const std::vector<cryptauth::RemoteDevice>& devices_to_connect, | 43 const std::vector<cryptauth::RemoteDevice>& devices_to_connect, |
| 40 BleConnectionManager* connection_manager) | 44 BleConnectionManager* connection_manager) |
| 41 : remote_devices_(RemoveDuplicatesFromVector(devices_to_connect)), | 45 : remote_devices_(RemoveDuplicatesFromVector(devices_to_connect)), |
| 42 connection_manager_(connection_manager), | 46 connection_manager_(connection_manager), |
| 43 initialized_(false) {} | 47 timer_factory_(base::MakeUnique<TimerFactory>()), |
| 48 initialized_(false), | |
| 49 wait_for_response_(true), | |
| 50 response_timeout_seconds_(kResponseTimeoutSeconds), | |
| 51 weak_ptr_factory_(this) {} | |
| 44 | 52 |
| 45 MessageTransferOperation::~MessageTransferOperation() { | 53 MessageTransferOperation::~MessageTransferOperation() { |
| 46 connection_manager_->RemoveObserver(this); | 54 connection_manager_->RemoveObserver(this); |
| 47 } | 55 } |
| 48 | 56 |
| 49 void MessageTransferOperation::Initialize() { | 57 void MessageTransferOperation::Initialize() { |
| 50 if (initialized_) { | 58 if (initialized_) { |
| 51 return; | 59 return; |
| 52 } | 60 } |
| 53 initialized_ = true; | 61 initialized_ = true; |
| 54 | 62 |
| 55 connection_manager_->AddObserver(this); | 63 connection_manager_->AddObserver(this); |
| 56 OnOperationStarted(); | 64 OnOperationStarted(); |
| 57 | 65 |
| 58 MessageType message_type_for_connection = GetMessageTypeForConnection(); | 66 MessageType message_type_for_connection = GetMessageTypeForConnection(); |
| 59 for (const auto& remote_device : remote_devices_) { | 67 for (const auto& remote_device : remote_devices_) { |
| 60 connection_manager_->RegisterRemoteDevice(remote_device, | 68 connection_manager_->RegisterRemoteDevice(remote_device, |
| 61 message_type_for_connection); | 69 message_type_for_connection); |
| 62 | 70 |
| 63 cryptauth::SecureChannel::Status status; | 71 cryptauth::SecureChannel::Status status; |
| 64 if (connection_manager_->GetStatusForDevice(remote_device, &status) && | 72 if (connection_manager_->GetStatusForDevice(remote_device, &status) && |
| 65 status == cryptauth::SecureChannel::Status::AUTHENTICATED) { | 73 status == cryptauth::SecureChannel::Status::AUTHENTICATED) { |
| 74 StartResponseTimerForDevice(remote_device); | |
| 66 OnDeviceAuthenticated(remote_device); | 75 OnDeviceAuthenticated(remote_device); |
| 67 } | 76 } |
| 68 } | 77 } |
| 69 } | 78 } |
| 70 | 79 |
| 71 void MessageTransferOperation::OnSecureChannelStatusChanged( | 80 void MessageTransferOperation::OnSecureChannelStatusChanged( |
| 72 const cryptauth::RemoteDevice& remote_device, | 81 const cryptauth::RemoteDevice& remote_device, |
| 73 const cryptauth::SecureChannel::Status& old_status, | 82 const cryptauth::SecureChannel::Status& old_status, |
| 74 const cryptauth::SecureChannel::Status& new_status) { | 83 const cryptauth::SecureChannel::Status& new_status) { |
| 75 if (std::find(remote_devices_.begin(), remote_devices_.end(), | 84 if (std::find(remote_devices_.begin(), remote_devices_.end(), |
| 76 remote_device) == remote_devices_.end()) { | 85 remote_device) == remote_devices_.end()) { |
| 77 // If the device whose status has changed does not correspond to any of the | 86 // If the device whose status has changed does not correspond to any of the |
| 78 // devices passed to this MessageTransferOperation instance, ignore the | 87 // devices passed to this MessageTransferOperation instance, ignore the |
| 79 // status change. | 88 // status change. |
| 80 return; | 89 return; |
| 81 } | 90 } |
| 82 | 91 |
| 83 if (new_status == cryptauth::SecureChannel::Status::AUTHENTICATED) { | 92 if (new_status == cryptauth::SecureChannel::Status::AUTHENTICATED) { |
| 93 StartResponseTimerForDevice(remote_device); | |
| 84 OnDeviceAuthenticated(remote_device); | 94 OnDeviceAuthenticated(remote_device); |
| 85 } else if (old_status == cryptauth::SecureChannel::Status::AUTHENTICATING) { | 95 } else if (old_status == cryptauth::SecureChannel::Status::AUTHENTICATING) { |
| 86 // If authentication fails, account details (e.g., BeaconSeeds) are not | 96 // If authentication fails, account details (e.g., BeaconSeeds) are not |
| 87 // synced, and there is no way to continue. Unregister the device and give | 97 // synced, and there is no way to continue. Unregister the device and give |
| 88 // up. | 98 // up. |
| 89 UnregisterDevice(remote_device); | 99 UnregisterDevice(remote_device); |
| 90 } else if (new_status == cryptauth::SecureChannel::Status::DISCONNECTED) { | 100 } else if (new_status == cryptauth::SecureChannel::Status::DISCONNECTED) { |
| 91 uint32_t num_attempts_so_far; | 101 uint32_t num_attempts_so_far; |
| 92 if (remote_device_to_num_attempts_map_.find(remote_device) == | 102 if (remote_device_to_num_attempts_map_.find(remote_device) == |
| 93 remote_device_to_num_attempts_map_.end()) { | 103 remote_device_to_num_attempts_map_.end()) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 OnMessageReceived(std::move(message_wrapper), remote_device); | 142 OnMessageReceived(std::move(message_wrapper), remote_device); |
| 133 } | 143 } |
| 134 } | 144 } |
| 135 | 145 |
| 136 void MessageTransferOperation::UnregisterDevice( | 146 void MessageTransferOperation::UnregisterDevice( |
| 137 const cryptauth::RemoteDevice& remote_device) { | 147 const cryptauth::RemoteDevice& remote_device) { |
| 138 remote_device_to_num_attempts_map_.erase(remote_device); | 148 remote_device_to_num_attempts_map_.erase(remote_device); |
| 139 remote_devices_.erase(std::remove(remote_devices_.begin(), | 149 remote_devices_.erase(std::remove(remote_devices_.begin(), |
| 140 remote_devices_.end(), remote_device), | 150 remote_devices_.end(), remote_device), |
| 141 remote_devices_.end()); | 151 remote_devices_.end()); |
| 152 StopResponseTimerForDevice(remote_device); | |
| 142 connection_manager_->UnregisterRemoteDevice(remote_device, | 153 connection_manager_->UnregisterRemoteDevice(remote_device, |
| 143 GetMessageTypeForConnection()); | 154 GetMessageTypeForConnection()); |
| 144 | 155 |
| 145 if (remote_devices_.empty()) { | 156 if (remote_devices_.empty()) { |
| 146 OnOperationFinished(); | 157 OnOperationFinished(); |
| 147 } | 158 } |
| 148 } | 159 } |
| 149 | 160 |
| 150 void MessageTransferOperation::SendMessageToDevice( | 161 void MessageTransferOperation::SendMessageToDevice( |
| 151 const cryptauth::RemoteDevice& remote_device, | 162 const cryptauth::RemoteDevice& remote_device, |
| 152 std::unique_ptr<MessageWrapper> message_wrapper) { | 163 std::unique_ptr<MessageWrapper> message_wrapper) { |
| 153 connection_manager_->SendMessage(remote_device, | 164 connection_manager_->SendMessage(remote_device, |
| 154 message_wrapper->ToRawMessage()); | 165 message_wrapper->ToRawMessage()); |
| 155 } | 166 } |
| 156 | 167 |
| 168 void MessageTransferOperation::SetTimerFactoryForTest( | |
| 169 std::unique_ptr<TimerFactory> timer_factory_for_test) { | |
| 170 timer_factory_ = std::move(timer_factory_for_test); | |
| 171 } | |
| 172 | |
| 173 void MessageTransferOperation::StartResponseTimerForDevice( | |
|
khorimoto
2017/05/31 17:26:35
nit: Do you think a log is appropriate in this fun
Ryan Hansberry
2017/05/31 21:19:03
Doesn't hurt; added.
| |
| 174 const cryptauth::RemoteDevice& remote_device) { | |
| 175 if (!wait_for_response_) | |
|
khorimoto
2017/05/31 17:26:35
Only call this function when we should wait for a
Ryan Hansberry
2017/05/31 21:19:03
Good point, done.
| |
| 176 return; | |
| 177 | |
| 178 remote_device_to_timer_map_.emplace(remote_device, | |
| 179 timer_factory_->CreateOneShotTimer()); | |
| 180 remote_device_to_timer_map_[remote_device]->Start( | |
| 181 FROM_HERE, base::TimeDelta::FromSeconds(response_timeout_seconds_), | |
| 182 base::Bind(&MessageTransferOperation::OnResponseTimeout, | |
| 183 weak_ptr_factory_.GetWeakPtr(), remote_device)); | |
| 184 } | |
| 185 | |
| 186 void MessageTransferOperation::StopResponseTimerForDevice( | |
| 187 const cryptauth::RemoteDevice& remote_device) { | |
| 188 if (!wait_for_response_ || !remote_device_to_timer_map_[remote_device]) | |
|
khorimoto
2017/05/31 17:26:35
Instead of returning early if(!remote_device_to_ti
Ryan Hansberry
2017/05/31 21:19:03
That can't work, because this method is called fro
Kyle Horimoto
2017/05/31 21:55:33
Instead, can you change your code to make sure the
Ryan Hansberry
2017/06/01 00:31:58
What is the difference between checking if the map
Kyle Horimoto
2017/06/01 18:18:58
Yep, I just wanted to make the method more clearly
Ryan Hansberry
2017/06/01 18:44:09
Done.
| |
| 189 return; | |
| 190 | |
| 191 remote_device_to_timer_map_[remote_device]->Stop(); | |
| 192 remote_device_to_timer_map_.erase(remote_device); | |
| 193 } | |
| 194 | |
| 195 void MessageTransferOperation::OnResponseTimeout( | |
| 196 const cryptauth::RemoteDevice& remote_device) { | |
| 197 PA_LOG(WARNING) << "Timed out while waiting for response from device with id " | |
|
khorimoto
2017/05/31 17:26:35
nit: Capitalize ID.
khorimoto
2017/05/31 17:26:35
In your log, also include the message type that wa
Ryan Hansberry
2017/05/31 21:19:03
Done.
| |
| 198 << remote_device.GetTruncatedDeviceIdForLogs() << "."; | |
| 199 | |
| 200 remote_device_to_timer_map_.erase(remote_device); | |
| 201 UnregisterDevice(remote_device); | |
| 202 } | |
| 203 | |
| 157 } // namespace tether | 204 } // namespace tether |
| 158 | 205 |
| 159 } // namespace chromeos | 206 } // namespace chromeos |
| OLD | NEW |