Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chromeos/components/tether/tether_connector.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "chromeos/components/tether/active_host.h" | |
| 9 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" | |
| 10 #include "chromeos/components/tether/tether_host_fetcher.h" | |
| 11 #include "chromeos/components/tether/wifi_hotspot_connector.h" | |
| 12 #include "chromeos/network/network_handler.h" | |
| 13 #include "chromeos/network/network_state_handler.h" | |
| 14 #include "components/proximity_auth/logging/logging.h" | |
| 15 | |
| 16 namespace chromeos { | |
| 17 | |
| 18 namespace tether { | |
| 19 | |
| 20 TetherConnector::TetherConnector( | |
| 21 WifiHotspotConnector* wifi_hotspot_connector, | |
| 22 ActiveHost* active_host, | |
| 23 TetherHostFetcher* tether_host_fetcher, | |
| 24 BleConnectionManager* connection_manager, | |
| 25 HostScanDevicePrioritizer* host_scan_device_prioritizer, | |
| 26 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map) | |
| 27 : TetherConnector(NetworkConnect::Get(), | |
| 28 NetworkHandler::Get()->network_state_handler(), | |
| 29 wifi_hotspot_connector, | |
| 30 active_host, | |
| 31 tether_host_fetcher, | |
| 32 connection_manager, | |
| 33 host_scan_device_prioritizer, | |
| 34 device_id_tether_network_guid_map) {} | |
| 35 | |
| 36 TetherConnector::TetherConnector( | |
| 37 NetworkConnect* network_connect, | |
| 38 NetworkStateHandler* network_state_handler, | |
| 39 WifiHotspotConnector* wifi_hotspot_connector, | |
| 40 ActiveHost* active_host, | |
| 41 TetherHostFetcher* tether_host_fetcher, | |
| 42 BleConnectionManager* connection_manager, | |
| 43 HostScanDevicePrioritizer* host_scan_device_prioritizer, | |
| 44 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map) | |
| 45 : network_connect_(network_connect), | |
| 46 network_state_handler_(network_state_handler), | |
| 47 wifi_hotspot_connector_(wifi_hotspot_connector), | |
| 48 active_host_(active_host), | |
| 49 tether_host_fetcher_(tether_host_fetcher), | |
| 50 connection_manager_(connection_manager), | |
| 51 host_scan_device_prioritizer_(host_scan_device_prioritizer), | |
| 52 device_id_tether_network_guid_map_(device_id_tether_network_guid_map), | |
| 53 weak_ptr_factory_(this) { | |
| 54 network_connect_->SetTetherDelegate(this); | |
| 55 } | |
| 56 | |
| 57 TetherConnector::~TetherConnector() { | |
| 58 network_connect_->SetTetherDelegate(nullptr); | |
| 59 if (connect_tethering_operation_) { | |
| 60 connect_tethering_operation_->RemoveObserver(this); | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 void TetherConnector::ConnectToNetwork(const std::string& guid) { | |
| 65 PA_LOG(INFO) << "Attempting to connect to network with GUID " << guid << "."; | |
| 66 | |
| 67 std::string device_id = | |
| 68 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(guid); | |
| 69 | |
| 70 if (device_id_pending_connection_ == device_id) { | |
| 71 PA_LOG(INFO) << "Connection attempt requested for network with GUID " | |
| 72 << guid << ", but a connection attempt is already in " | |
| 73 << "progress. Continuing with the existing attempt."; | |
| 74 return; | |
| 75 } | |
| 76 | |
| 77 if (connect_tethering_operation_) { | |
| 78 DCHECK(!device_id_pending_connection_.empty()); | |
| 79 | |
| 80 PA_LOG(INFO) << "A connection attempt was already in progress to device " | |
| 81 << "with ID " << device_id_pending_connection_ << ". " | |
| 82 << "Canceling that connection attempt before continuing."; | |
| 83 | |
| 84 // If a connection to a *different* device is pending, stop the connection | |
| 85 // attempt. | |
| 86 connect_tethering_operation_->RemoveObserver(this); | |
| 87 connect_tethering_operation_.reset(); | |
| 88 } | |
| 89 | |
| 90 device_id_pending_connection_ = device_id; | |
| 91 | |
| 92 tether_host_fetcher_->FetchTetherHost( | |
| 93 device_id_pending_connection_, | |
| 94 base::Bind(&TetherConnector::OnTetherHostToConnectFetched, | |
| 95 weak_ptr_factory_.GetWeakPtr(), | |
| 96 device_id_pending_connection_)); | |
| 97 } | |
| 98 | |
| 99 void TetherConnector::OnSuccessfulConnectTetheringResponse( | |
| 100 const cryptauth::RemoteDevice& remote_device, | |
| 101 const std::string& ssid, | |
| 102 const std::string& password) { | |
| 103 if (device_id_pending_connection_ != remote_device.GetDeviceId()) { | |
| 104 // If the success was part of a previous attempt for a different device, | |
| 105 // ignore it. | |
| 106 PA_LOG(INFO) << "Received successful ConnectTetheringResponse from " | |
| 107 << "device with ID " | |
| 108 << remote_device.GetTruncatedDeviceIdForLogs() | |
| 109 << ", but a connection to another device was started while " | |
| 110 << "the response was being received."; | |
| 111 return; | |
| 112 } | |
| 113 | |
| 114 PA_LOG(INFO) << "Received successful ConnectTetheringResponse from device " | |
| 115 << "with ID " << remote_device.GetTruncatedDeviceIdForLogs() | |
| 116 << ". SSID: \"" << ssid << "\", Password: \"" << password | |
| 117 << "\""; | |
| 118 | |
| 119 // Make a copy of the device ID to pass below before destroying | |
| 120 // |connect_tethering_operation_|. | |
| 121 std::string remote_device_id = remote_device.GetDeviceId(); | |
| 122 | |
| 123 connect_tethering_operation_->RemoveObserver(this); | |
| 124 connect_tethering_operation_.reset(); | |
|
Ryan Hansberry
2017/04/06 02:17:44
You are deleting connect_tethering_operation_ here
Kyle Horimoto
2017/04/06 17:10:53
Done.
| |
| 125 | |
| 126 wifi_hotspot_connector_->ConnectToWifiHotspot( | |
| 127 ssid, password, | |
| 128 base::Bind(&TetherConnector::OnWifiConnection, | |
| 129 weak_ptr_factory_.GetWeakPtr(), remote_device_id)); | |
| 130 } | |
| 131 | |
| 132 void TetherConnector::OnConnectTetheringFailure( | |
| 133 const cryptauth::RemoteDevice& remote_device, | |
| 134 ConnectTetheringResponse_ResponseCode error_code) { | |
| 135 if (device_id_pending_connection_ != remote_device.GetDeviceId()) { | |
| 136 // If the failure was part of a previous attempt for a different device, | |
| 137 // ignore it. | |
| 138 PA_LOG(INFO) << "Received failed ConnectTetheringResponse from device with " | |
| 139 << "ID " << remote_device.GetTruncatedDeviceIdForLogs() | |
| 140 << ", but a connection to another device has already started."; | |
| 141 return; | |
| 142 } | |
| 143 | |
| 144 PA_LOG(WARNING) << "Connection to device with ID " | |
| 145 << remote_device.GetTruncatedDeviceIdForLogs() | |
| 146 << " could not connect. Error code: " << error_code; | |
| 147 | |
| 148 connect_tethering_operation_->RemoveObserver(this); | |
| 149 connect_tethering_operation_.reset(); | |
| 150 SetDisconnected(); | |
| 151 } | |
| 152 | |
| 153 void TetherConnector::OnTetherHostToConnectFetched( | |
| 154 const std::string& device_id, | |
| 155 std::unique_ptr<cryptauth::RemoteDevice> tether_host_to_connect) { | |
| 156 if (!tether_host_to_connect) { | |
| 157 PA_LOG(ERROR) << "Could not fetch tether host with device ID " | |
| 158 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
| 159 << ". Cannot connect."; | |
| 160 return; | |
| 161 } | |
| 162 | |
| 163 if (device_id_pending_connection_ != tether_host_to_connect->GetDeviceId()) { | |
| 164 PA_LOG(INFO) << "Device to connect to has changed while device with ID " | |
| 165 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
| 166 << " was being fetched."; | |
| 167 return; | |
| 168 } | |
| 169 | |
| 170 active_host_->SetActiveHostConnecting( | |
| 171 device_id_pending_connection_, | |
| 172 device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( | |
| 173 device_id_pending_connection_)); | |
| 174 | |
| 175 connect_tethering_operation_ = | |
| 176 ConnectTetheringOperation::Factory::NewInstance( | |
| 177 *tether_host_to_connect, connection_manager_, | |
| 178 host_scan_device_prioritizer_); | |
| 179 connect_tethering_operation_->AddObserver(this); | |
| 180 connect_tethering_operation_->Initialize(); | |
| 181 } | |
| 182 | |
| 183 void TetherConnector::SetDisconnected() { | |
| 184 device_id_pending_connection_ = ""; | |
| 185 active_host_->SetActiveHostDisconnected(); | |
| 186 } | |
| 187 | |
| 188 void TetherConnector::SetConnected(const std::string& device_id, | |
| 189 const std::string& wifi_network_guid) { | |
| 190 device_id_pending_connection_ = ""; | |
| 191 active_host_->SetActiveHostConnected( | |
| 192 device_id, | |
| 193 device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( | |
| 194 device_id), | |
| 195 wifi_network_guid); | |
| 196 } | |
| 197 | |
| 198 void TetherConnector::OnWifiConnection(const std::string& device_id, | |
| 199 const std::string& wifi_network_guid) { | |
| 200 if (device_id != device_id_pending_connection_) { | |
| 201 // If the device ID does not match the ID of the device pending connection, | |
| 202 // this is a stale attempt. | |
| 203 PA_LOG(ERROR) << "Cannot connect to device with ID " | |
| 204 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
| 205 << " because another connection attempt has been started to " | |
| 206 << "a different device."; | |
| 207 | |
| 208 // TODO(khorimoto): Disconnect from the network. | |
| 209 return; | |
| 210 } | |
| 211 | |
| 212 if (wifi_network_guid.empty()) { | |
| 213 // If the Wi-Fi network ID is empty, then the connection did not succeed. | |
| 214 PA_LOG(ERROR) << "Failed to connect to the hotspot belonging to the device " | |
| 215 << "with ID " | |
| 216 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
| 217 << "."; | |
| 218 | |
| 219 SetDisconnected(); | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 bool successful_association = | |
| 224 network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork( | |
| 225 device_id, wifi_network_guid); | |
| 226 if (successful_association) { | |
| 227 PA_LOG(INFO) << "Successfully connected to host device with ID " | |
| 228 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
| 229 << ". Tether network ID: \"" << device_id | |
| 230 << "\", Wi-Fi network ID: \"" << wifi_network_guid << "\""; | |
| 231 } else { | |
| 232 PA_LOG(WARNING) << "Successfully connected to host device with ID " | |
| 233 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( | |
| 234 device_id) | |
| 235 << ", but failed to associate tether network with ID \"" | |
| 236 << device_id << "\" to Wi-Fi network with ID \"" | |
| 237 << wifi_network_guid << "\"."; | |
| 238 } | |
| 239 | |
| 240 SetConnected(device_id, wifi_network_guid); | |
| 241 } | |
| 242 | |
| 243 } // namespace tether | |
| 244 | |
| 245 } // namespace chromeos | |
| OLD | NEW |