Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chromeos/components/tether/message_transfer_operation.cc

Issue 2915713002: Tether MessageTransferOperation: Only wait for a response from a host for a certain amount of time … (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698