| Index: chromeos/components/tether/message_transfer_operation.cc
|
| diff --git a/chromeos/components/tether/message_transfer_operation.cc b/chromeos/components/tether/message_transfer_operation.cc
|
| index d9d75cf72b1cd63fb5bbed455a8df36514d5d853..ab0167621c42d043f11ac888149a63271a68cae7 100644
|
| --- a/chromeos/components/tether/message_transfer_operation.cc
|
| +++ b/chromeos/components/tether/message_transfer_operation.cc
|
| @@ -7,6 +7,7 @@
|
| #include <set>
|
|
|
| #include "chromeos/components/tether/message_wrapper.h"
|
| +#include "chromeos/components/tether/timer_factory.h"
|
| #include "components/proximity_auth/logging/logging.h"
|
|
|
| namespace chromeos {
|
| @@ -35,12 +36,17 @@ std::vector<cryptauth::RemoteDevice> RemoveDuplicatesFromVector(
|
| // static
|
| uint32_t MessageTransferOperation::kMaxConnectionAttemptsPerDevice = 3;
|
|
|
| +// static
|
| +uint32_t MessageTransferOperation::kDefaultResponseTimeoutSeconds = 10;
|
| +
|
| MessageTransferOperation::MessageTransferOperation(
|
| const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
|
| BleConnectionManager* connection_manager)
|
| : remote_devices_(RemoveDuplicatesFromVector(devices_to_connect)),
|
| connection_manager_(connection_manager),
|
| - initialized_(false) {}
|
| + timer_factory_(base::MakeUnique<TimerFactory>()),
|
| + initialized_(false),
|
| + weak_ptr_factory_(this) {}
|
|
|
| MessageTransferOperation::~MessageTransferOperation() {
|
| connection_manager_->RemoveObserver(this);
|
| @@ -63,6 +69,9 @@ void MessageTransferOperation::Initialize() {
|
| cryptauth::SecureChannel::Status status;
|
| if (connection_manager_->GetStatusForDevice(remote_device, &status) &&
|
| status == cryptauth::SecureChannel::Status::AUTHENTICATED) {
|
| + if (ShouldWaitForResponse())
|
| + StartResponseTimerForDevice(remote_device);
|
| +
|
| OnDeviceAuthenticated(remote_device);
|
| }
|
| }
|
| @@ -81,6 +90,9 @@ void MessageTransferOperation::OnSecureChannelStatusChanged(
|
| }
|
|
|
| if (new_status == cryptauth::SecureChannel::Status::AUTHENTICATED) {
|
| + if (ShouldWaitForResponse())
|
| + StartResponseTimerForDevice(remote_device);
|
| +
|
| OnDeviceAuthenticated(remote_device);
|
| } else if (old_status == cryptauth::SecureChannel::Status::AUTHENTICATING) {
|
| // If authentication fails, account details (e.g., BeaconSeeds) are not
|
| @@ -139,6 +151,9 @@ void MessageTransferOperation::UnregisterDevice(
|
| remote_devices_.erase(std::remove(remote_devices_.begin(),
|
| remote_devices_.end(), remote_device),
|
| remote_devices_.end());
|
| + if (ShouldWaitForResponse())
|
| + StopResponseTimerForDeviceIfRunning(remote_device);
|
| +
|
| connection_manager_->UnregisterRemoteDevice(remote_device,
|
| GetMessageTypeForConnection());
|
|
|
| @@ -154,6 +169,56 @@ void MessageTransferOperation::SendMessageToDevice(
|
| message_wrapper->ToRawMessage());
|
| }
|
|
|
| +bool MessageTransferOperation::ShouldWaitForResponse() {
|
| + return true;
|
| +}
|
| +
|
| +uint32_t MessageTransferOperation::GetResponseTimeoutSeconds() {
|
| + return MessageTransferOperation::kDefaultResponseTimeoutSeconds;
|
| +}
|
| +
|
| +void MessageTransferOperation::SetTimerFactoryForTest(
|
| + std::unique_ptr<TimerFactory> timer_factory_for_test) {
|
| + timer_factory_ = std::move(timer_factory_for_test);
|
| +}
|
| +
|
| +void MessageTransferOperation::StartResponseTimerForDevice(
|
| + const cryptauth::RemoteDevice& remote_device) {
|
| + DCHECK(ShouldWaitForResponse());
|
| +
|
| + PA_LOG(INFO) << "Starting timer to wait for response to message type "
|
| + << GetMessageTypeForConnection() << " from device with ID "
|
| + << remote_device.GetTruncatedDeviceIdForLogs() << ".";
|
| +
|
| + remote_device_to_timer_map_.emplace(remote_device,
|
| + timer_factory_->CreateOneShotTimer());
|
| + remote_device_to_timer_map_[remote_device]->Start(
|
| + FROM_HERE, base::TimeDelta::FromSeconds(GetResponseTimeoutSeconds()),
|
| + base::Bind(&MessageTransferOperation::OnResponseTimeout,
|
| + weak_ptr_factory_.GetWeakPtr(), remote_device));
|
| +}
|
| +
|
| +void MessageTransferOperation::StopResponseTimerForDeviceIfRunning(
|
| + const cryptauth::RemoteDevice& remote_device) {
|
| + DCHECK(ShouldWaitForResponse());
|
| +
|
| + if (!remote_device_to_timer_map_[remote_device])
|
| + return;
|
| +
|
| + remote_device_to_timer_map_[remote_device]->Stop();
|
| + remote_device_to_timer_map_.erase(remote_device);
|
| +}
|
| +
|
| +void MessageTransferOperation::OnResponseTimeout(
|
| + const cryptauth::RemoteDevice& remote_device) {
|
| + PA_LOG(WARNING) << "Timed out while waiting for response to message type "
|
| + << GetMessageTypeForConnection() << " from device with ID "
|
| + << remote_device.GetTruncatedDeviceIdForLogs() << ".";
|
| +
|
| + remote_device_to_timer_map_.erase(remote_device);
|
| + UnregisterDevice(remote_device);
|
| +}
|
| +
|
| } // namespace tether
|
|
|
| } // namespace chromeos
|
|
|