Index: chromeos/components/tether/connect_tethering_operation.cc |
diff --git a/chromeos/components/tether/connect_tethering_operation.cc b/chromeos/components/tether/connect_tethering_operation.cc |
index b7723b7130872c4aaf97c130e509f9f26371fe6c..f63f105bce9c7b7b327e67ed388d3019bd61bec3 100644 |
--- a/chromeos/components/tether/connect_tethering_operation.cc |
+++ b/chromeos/components/tether/connect_tethering_operation.cc |
@@ -52,8 +52,11 @@ ConnectTetheringOperation::ConnectTetheringOperation( |
: MessageTransferOperation( |
std::vector<cryptauth::RemoteDevice>{device_to_connect}, |
connection_manager), |
+ remote_device_(device_to_connect), |
host_scan_device_prioritizer_(host_scan_device_prioritizer), |
- has_authenticated_(false) {} |
+ error_code_to_return_( |
+ ConnectTetheringResponse_ResponseCode:: |
+ ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR) {} |
ConnectTetheringOperation::~ConnectTetheringOperation() {} |
@@ -68,8 +71,6 @@ void ConnectTetheringOperation::RemoveObserver(Observer* observer) { |
void ConnectTetheringOperation::OnDeviceAuthenticated( |
const cryptauth::RemoteDevice& remote_device) { |
DCHECK(remote_devices().size() == 1u && remote_devices()[0] == remote_device); |
- has_authenticated_ = true; |
- |
SendMessageToDevice(remote_device, base::MakeUnique<MessageWrapper>( |
ConnectTetheringRequest())); |
} |
@@ -83,6 +84,11 @@ void ConnectTetheringOperation::OnMessageReceived( |
return; |
} |
+ if (!(remote_device == remote_device_)) { |
+ // If the message came from another device, ignore it. |
+ return; |
+ } |
+ |
ConnectTetheringResponse* response = |
static_cast<ConnectTetheringResponse*>(message_wrapper->GetProto().get()); |
if (response->response_code() == |
@@ -98,22 +104,19 @@ void ConnectTetheringOperation::OnMessageReceived( |
host_scan_device_prioritizer_->RecordSuccessfulConnectTetheringResponse( |
remote_device); |
- NotifyObserversOfSuccessfulResponse(response->ssid(), |
- response->password()); |
+ ssid_to_return_ = response->ssid(); |
+ password_to_return_ = response->password(); |
} else { |
PA_LOG(ERROR) << "Received ConnectTetheringResponse from device with ID " |
<< remote_device.GetTruncatedDeviceIdForLogs() << " and " |
<< "response_code == SUCCESS, but the response did not " |
<< "contain a Wi-Fi SSID and/or password."; |
- NotifyObserversOfConnectionFailure( |
- ConnectTetheringResponse_ResponseCode:: |
- ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR); |
} |
} else { |
PA_LOG(INFO) << "Received ConnectTetheringResponse from device with ID " |
<< remote_device.GetTruncatedDeviceIdForLogs() << " and " |
<< "response_code == " << response->response_code() << "."; |
- NotifyObserversOfConnectionFailure(response->response_code()); |
+ error_code_to_return_ = response->response_code(); |
} |
// Now that a response has been received, the device can be unregistered. |
@@ -121,13 +124,18 @@ void ConnectTetheringOperation::OnMessageReceived( |
} |
void ConnectTetheringOperation::OnOperationFinished() { |
- if (!has_authenticated_) { |
- // If the operation finished but the device never authenticated, there was |
- // some sort of problem connecting to the device. In this case, notify |
- // observers of a failure. |
- NotifyObserversOfConnectionFailure( |
- ConnectTetheringResponse_ResponseCode:: |
- ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR); |
+ // Notify observers of the results of this operation in OnOperationFinished() |
+ // instead of in OnMessageReceived() because observers may delete this |
+ // ConnectTetheringOperation instance. If this happens, the UnregisterDevice() |
+ // call in OnMessageReceived() will cause a crash. |
+ |
+ if (!ssid_to_return_.empty()) { |
+ NotifyObserversOfSuccessfulResponse(ssid_to_return_, password_to_return_); |
+ } else { |
+ // At this point, either the operation finished with a failed response or |
+ // no connection succeeded at all. In these cases, notify observers of a |
+ // failure. |
+ NotifyObserversOfConnectionFailure(error_code_to_return_); |
} |
} |
@@ -139,14 +147,15 @@ void ConnectTetheringOperation::NotifyObserversOfSuccessfulResponse( |
const std::string& ssid, |
const std::string& password) { |
for (auto& observer : observer_list_) { |
- observer.OnSuccessfulConnectTetheringResponse(ssid, password); |
+ observer.OnSuccessfulConnectTetheringResponse(remote_device_, ssid, |
+ password); |
} |
} |
void ConnectTetheringOperation::NotifyObserversOfConnectionFailure( |
ConnectTetheringResponse_ResponseCode error_code) { |
for (auto& observer : observer_list_) { |
- observer.OnConnectTetheringFailure(error_code); |
+ observer.OnConnectTetheringFailure(remote_device_, error_code); |
} |
} |