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 |