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::kDefaultResponseTimeoutSeconds = 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 weak_ptr_factory_(this) {} |
44 | 50 |
45 MessageTransferOperation::~MessageTransferOperation() { | 51 MessageTransferOperation::~MessageTransferOperation() { |
46 connection_manager_->RemoveObserver(this); | 52 connection_manager_->RemoveObserver(this); |
47 } | 53 } |
48 | 54 |
49 void MessageTransferOperation::Initialize() { | 55 void MessageTransferOperation::Initialize() { |
50 if (initialized_) { | 56 if (initialized_) { |
51 return; | 57 return; |
52 } | 58 } |
53 initialized_ = true; | 59 initialized_ = true; |
54 | 60 |
55 connection_manager_->AddObserver(this); | 61 connection_manager_->AddObserver(this); |
56 OnOperationStarted(); | 62 OnOperationStarted(); |
57 | 63 |
58 MessageType message_type_for_connection = GetMessageTypeForConnection(); | 64 MessageType message_type_for_connection = GetMessageTypeForConnection(); |
59 for (const auto& remote_device : remote_devices_) { | 65 for (const auto& remote_device : remote_devices_) { |
60 connection_manager_->RegisterRemoteDevice(remote_device, | 66 connection_manager_->RegisterRemoteDevice(remote_device, |
61 message_type_for_connection); | 67 message_type_for_connection); |
62 | 68 |
63 cryptauth::SecureChannel::Status status; | 69 cryptauth::SecureChannel::Status status; |
64 if (connection_manager_->GetStatusForDevice(remote_device, &status) && | 70 if (connection_manager_->GetStatusForDevice(remote_device, &status) && |
65 status == cryptauth::SecureChannel::Status::AUTHENTICATED) { | 71 status == cryptauth::SecureChannel::Status::AUTHENTICATED) { |
| 72 if (ShouldWaitForResponse()) |
| 73 StartResponseTimerForDevice(remote_device); |
| 74 |
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 if (ShouldWaitForResponse()) |
| 94 StartResponseTimerForDevice(remote_device); |
| 95 |
84 OnDeviceAuthenticated(remote_device); | 96 OnDeviceAuthenticated(remote_device); |
85 } else if (old_status == cryptauth::SecureChannel::Status::AUTHENTICATING) { | 97 } else if (old_status == cryptauth::SecureChannel::Status::AUTHENTICATING) { |
86 // If authentication fails, account details (e.g., BeaconSeeds) are not | 98 // If authentication fails, account details (e.g., BeaconSeeds) are not |
87 // synced, and there is no way to continue. Unregister the device and give | 99 // synced, and there is no way to continue. Unregister the device and give |
88 // up. | 100 // up. |
89 UnregisterDevice(remote_device); | 101 UnregisterDevice(remote_device); |
90 } else if (new_status == cryptauth::SecureChannel::Status::DISCONNECTED) { | 102 } else if (new_status == cryptauth::SecureChannel::Status::DISCONNECTED) { |
91 uint32_t num_attempts_so_far; | 103 uint32_t num_attempts_so_far; |
92 if (remote_device_to_num_attempts_map_.find(remote_device) == | 104 if (remote_device_to_num_attempts_map_.find(remote_device) == |
93 remote_device_to_num_attempts_map_.end()) { | 105 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); | 144 OnMessageReceived(std::move(message_wrapper), remote_device); |
133 } | 145 } |
134 } | 146 } |
135 | 147 |
136 void MessageTransferOperation::UnregisterDevice( | 148 void MessageTransferOperation::UnregisterDevice( |
137 const cryptauth::RemoteDevice& remote_device) { | 149 const cryptauth::RemoteDevice& remote_device) { |
138 remote_device_to_num_attempts_map_.erase(remote_device); | 150 remote_device_to_num_attempts_map_.erase(remote_device); |
139 remote_devices_.erase(std::remove(remote_devices_.begin(), | 151 remote_devices_.erase(std::remove(remote_devices_.begin(), |
140 remote_devices_.end(), remote_device), | 152 remote_devices_.end(), remote_device), |
141 remote_devices_.end()); | 153 remote_devices_.end()); |
| 154 if (ShouldWaitForResponse()) |
| 155 StopResponseTimerForDeviceIfRunning(remote_device); |
| 156 |
142 connection_manager_->UnregisterRemoteDevice(remote_device, | 157 connection_manager_->UnregisterRemoteDevice(remote_device, |
143 GetMessageTypeForConnection()); | 158 GetMessageTypeForConnection()); |
144 | 159 |
145 if (remote_devices_.empty()) { | 160 if (remote_devices_.empty()) { |
146 OnOperationFinished(); | 161 OnOperationFinished(); |
147 } | 162 } |
148 } | 163 } |
149 | 164 |
150 void MessageTransferOperation::SendMessageToDevice( | 165 void MessageTransferOperation::SendMessageToDevice( |
151 const cryptauth::RemoteDevice& remote_device, | 166 const cryptauth::RemoteDevice& remote_device, |
152 std::unique_ptr<MessageWrapper> message_wrapper) { | 167 std::unique_ptr<MessageWrapper> message_wrapper) { |
153 connection_manager_->SendMessage(remote_device, | 168 connection_manager_->SendMessage(remote_device, |
154 message_wrapper->ToRawMessage()); | 169 message_wrapper->ToRawMessage()); |
155 } | 170 } |
156 | 171 |
| 172 bool MessageTransferOperation::ShouldWaitForResponse() { |
| 173 return true; |
| 174 } |
| 175 |
| 176 uint32_t MessageTransferOperation::GetResponseTimeoutSeconds() { |
| 177 return MessageTransferOperation::kDefaultResponseTimeoutSeconds; |
| 178 } |
| 179 |
| 180 void MessageTransferOperation::SetTimerFactoryForTest( |
| 181 std::unique_ptr<TimerFactory> timer_factory_for_test) { |
| 182 timer_factory_ = std::move(timer_factory_for_test); |
| 183 } |
| 184 |
| 185 void MessageTransferOperation::StartResponseTimerForDevice( |
| 186 const cryptauth::RemoteDevice& remote_device) { |
| 187 DCHECK(ShouldWaitForResponse()); |
| 188 |
| 189 PA_LOG(INFO) << "Starting timer to wait for response to message type " |
| 190 << GetMessageTypeForConnection() << " from device with ID " |
| 191 << remote_device.GetTruncatedDeviceIdForLogs() << "."; |
| 192 |
| 193 remote_device_to_timer_map_.emplace(remote_device, |
| 194 timer_factory_->CreateOneShotTimer()); |
| 195 remote_device_to_timer_map_[remote_device]->Start( |
| 196 FROM_HERE, base::TimeDelta::FromSeconds(GetResponseTimeoutSeconds()), |
| 197 base::Bind(&MessageTransferOperation::OnResponseTimeout, |
| 198 weak_ptr_factory_.GetWeakPtr(), remote_device)); |
| 199 } |
| 200 |
| 201 void MessageTransferOperation::StopResponseTimerForDeviceIfRunning( |
| 202 const cryptauth::RemoteDevice& remote_device) { |
| 203 DCHECK(ShouldWaitForResponse()); |
| 204 |
| 205 if (!remote_device_to_timer_map_[remote_device]) |
| 206 return; |
| 207 |
| 208 remote_device_to_timer_map_[remote_device]->Stop(); |
| 209 remote_device_to_timer_map_.erase(remote_device); |
| 210 } |
| 211 |
| 212 void MessageTransferOperation::OnResponseTimeout( |
| 213 const cryptauth::RemoteDevice& remote_device) { |
| 214 PA_LOG(WARNING) << "Timed out while waiting for response to message type " |
| 215 << GetMessageTypeForConnection() << " from device with ID " |
| 216 << remote_device.GetTruncatedDeviceIdForLogs() << "."; |
| 217 |
| 218 remote_device_to_timer_map_.erase(remote_device); |
| 219 UnregisterDevice(remote_device); |
| 220 } |
| 221 |
157 } // namespace tether | 222 } // namespace tether |
158 | 223 |
159 } // namespace chromeos | 224 } // namespace chromeos |
OLD | NEW |