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/tether_disconnector.h" | 5 #include "chromeos/components/tether/tether_disconnector_impl.h" |
6 | 6 |
7 #include "base/values.h" | 7 #include "base/values.h" |
8 #include "chromeos/components/tether/active_host.h" | 8 #include "chromeos/components/tether/active_host.h" |
9 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" | 9 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" |
10 #include "chromeos/components/tether/network_configuration_remover.h" | 10 #include "chromeos/components/tether/network_configuration_remover.h" |
| 11 #include "chromeos/components/tether/pref_names.h" |
11 #include "chromeos/components/tether/tether_connector.h" | 12 #include "chromeos/components/tether/tether_connector.h" |
12 #include "chromeos/components/tether/tether_host_fetcher.h" | 13 #include "chromeos/components/tether/tether_host_fetcher.h" |
13 #include "chromeos/network/network_connection_handler.h" | 14 #include "chromeos/network/network_connection_handler.h" |
14 #include "chromeos/network/network_state.h" | 15 #include "chromeos/network/network_state.h" |
15 #include "chromeos/network/network_state_handler.h" | 16 #include "chromeos/network/network_state_handler.h" |
| 17 #include "components/prefs/pref_registry_simple.h" |
| 18 #include "components/prefs/pref_service.h" |
16 #include "components/proximity_auth/logging/logging.h" | 19 #include "components/proximity_auth/logging/logging.h" |
17 | 20 |
18 namespace chromeos { | 21 namespace chromeos { |
19 | 22 |
20 namespace tether { | 23 namespace tether { |
21 | 24 |
22 TetherDisconnector::TetherDisconnector( | 25 namespace { |
| 26 |
| 27 void OnDisconnectError(const std::string& error_name) { |
| 28 PA_LOG(WARNING) << "Error disconnecting from Tether network during shutdown; " |
| 29 << "Error name: " << error_name; |
| 30 } |
| 31 |
| 32 } // namespace |
| 33 |
| 34 // static |
| 35 void TetherDisconnectorImpl::RegisterPrefs(PrefRegistrySimple* registry) { |
| 36 registry->RegisterStringPref(prefs::kDisconnectingWifiNetworkGuid, ""); |
| 37 } |
| 38 |
| 39 TetherDisconnectorImpl::TetherDisconnectorImpl( |
23 NetworkConnectionHandler* network_connection_handler, | 40 NetworkConnectionHandler* network_connection_handler, |
24 NetworkStateHandler* network_state_handler, | 41 NetworkStateHandler* network_state_handler, |
25 ActiveHost* active_host, | 42 ActiveHost* active_host, |
26 BleConnectionManager* ble_connection_manager, | 43 BleConnectionManager* ble_connection_manager, |
27 NetworkConfigurationRemover* network_configuration_remover, | 44 NetworkConfigurationRemover* network_configuration_remover, |
28 TetherConnector* tether_connector, | 45 TetherConnector* tether_connector, |
29 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map, | 46 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map, |
30 TetherHostFetcher* tether_host_fetcher) | 47 TetherHostFetcher* tether_host_fetcher, |
| 48 PrefService* pref_service) |
31 : network_connection_handler_(network_connection_handler), | 49 : network_connection_handler_(network_connection_handler), |
32 network_state_handler_(network_state_handler), | 50 network_state_handler_(network_state_handler), |
33 active_host_(active_host), | 51 active_host_(active_host), |
34 ble_connection_manager_(ble_connection_manager), | 52 ble_connection_manager_(ble_connection_manager), |
35 network_configuration_remover_(network_configuration_remover), | 53 network_configuration_remover_(network_configuration_remover), |
36 tether_connector_(tether_connector), | 54 tether_connector_(tether_connector), |
37 device_id_tether_network_guid_map_(device_id_tether_network_guid_map), | 55 device_id_tether_network_guid_map_(device_id_tether_network_guid_map), |
38 tether_host_fetcher_(tether_host_fetcher), | 56 tether_host_fetcher_(tether_host_fetcher), |
39 weak_ptr_factory_(this) {} | 57 pref_service_(pref_service), |
| 58 weak_ptr_factory_(this) { |
| 59 std::string disconnecting_wifi_guid_from_previous_session = |
| 60 pref_service_->GetString(prefs::kDisconnectingWifiNetworkGuid); |
| 61 if (!disconnecting_wifi_guid_from_previous_session.empty()) { |
| 62 // If a previous disconnection attempt was aborted before it could be fully |
| 63 // completed, clean up the leftover network configuration. |
| 64 network_configuration_remover_->RemoveNetworkConfiguration( |
| 65 disconnecting_wifi_guid_from_previous_session); |
| 66 pref_service_->ClearPref(prefs::kDisconnectingWifiNetworkGuid); |
| 67 } |
| 68 } |
40 | 69 |
41 TetherDisconnector::~TetherDisconnector() { | 70 TetherDisconnectorImpl::~TetherDisconnectorImpl() { |
42 if (disconnect_tethering_operation_) | 71 if (disconnect_tethering_operation_) |
43 disconnect_tethering_operation_->RemoveObserver(this); | 72 disconnect_tethering_operation_->RemoveObserver(this); |
| 73 |
| 74 std::string active_tether_guid = active_host_->GetTetherNetworkGuid(); |
| 75 if (!active_tether_guid.empty()) { |
| 76 PA_LOG(INFO) << "There was an active Tether connection during Tether " |
| 77 << "shutdown. Initiating disconnection from network with GUID " |
| 78 << "\"" << active_tether_guid << "\""; |
| 79 DisconnectFromNetwork(active_tether_guid, base::Bind(&base::DoNothing), |
| 80 base::Bind(&OnDisconnectError)); |
| 81 } |
44 } | 82 } |
45 | 83 |
46 void TetherDisconnector::DisconnectFromNetwork( | 84 void TetherDisconnectorImpl::DisconnectFromNetwork( |
47 const std::string& tether_network_guid, | 85 const std::string& tether_network_guid, |
48 const base::Closure& success_callback, | 86 const base::Closure& success_callback, |
49 const network_handler::StringResultCallback& error_callback) { | 87 const network_handler::StringResultCallback& error_callback) { |
50 DCHECK(!tether_network_guid.empty()); | 88 DCHECK(!tether_network_guid.empty()); |
51 | 89 |
52 ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus(); | 90 ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus(); |
53 std::string active_tether_network_guid = active_host_->GetTetherNetworkGuid(); | 91 std::string active_tether_network_guid = active_host_->GetTetherNetworkGuid(); |
54 std::string active_wifi_network_guid = active_host_->GetWifiNetworkGuid(); | 92 std::string active_wifi_network_guid = active_host_->GetWifiNetworkGuid(); |
55 | 93 |
56 if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) { | 94 if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) { |
(...skipping 28 matching lines...) Expand all Loading... |
85 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | 123 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); |
86 return; | 124 return; |
87 } | 125 } |
88 | 126 |
89 DCHECK(!active_wifi_network_guid.empty()); | 127 DCHECK(!active_wifi_network_guid.empty()); |
90 DCHECK(!disconnect_tethering_operation_); | 128 DCHECK(!disconnect_tethering_operation_); |
91 DisconnectActiveWifiConnection(tether_network_guid, active_wifi_network_guid, | 129 DisconnectActiveWifiConnection(tether_network_guid, active_wifi_network_guid, |
92 success_callback, error_callback); | 130 success_callback, error_callback); |
93 } | 131 } |
94 | 132 |
95 void TetherDisconnector::DisconnectActiveWifiConnection( | 133 void TetherDisconnectorImpl::DisconnectActiveWifiConnection( |
96 const std::string& tether_network_guid, | 134 const std::string& tether_network_guid, |
97 const std::string& wifi_network_guid, | 135 const std::string& wifi_network_guid, |
98 const base::Closure& success_callback, | 136 const base::Closure& success_callback, |
99 const network_handler::StringResultCallback& error_callback) { | 137 const network_handler::StringResultCallback& error_callback) { |
100 // First, disconnect the active host so that the user gets visual indication | 138 // First, disconnect the active host so that the user gets visual indication |
101 // that the disconnection is in progress as quickly as possible. | 139 // that the disconnection is in progress as quickly as possible. |
102 // TODO(hansberry): This will result in the Tether network becoming | 140 // TODO(hansberry): This will result in the Tether network becoming |
103 // disconnected, but the Wi-Fi network will still be connected until the | 141 // disconnected, but the Wi-Fi network will still be connected until the |
104 // DisconnectNetwork() call below completes. This will result in a jarring UI | 142 // DisconnectNetwork() call below completes. This will result in a jarring UI |
105 // transition which needs to be fixed. | 143 // transition which needs to be fixed. |
106 active_host_->SetActiveHostDisconnected(); | 144 active_host_->SetActiveHostDisconnected(); |
107 | 145 |
| 146 // Before starting disconnection, log the disconnecting Wi-Fi GUID to prefs. |
| 147 // Under normal circumstances, the GUID will be cleared as part of |
| 148 // CleanUpAfterWifiDisconnection(). However, when the user logs out, |
| 149 // this TetherDisconnectorImpl instance will be deleted before one of the |
| 150 // callbacks passed below to DisconnectNetwork() can be called, and the |
| 151 // GUID will remain in prefs until the next time the user logs in, at which |
| 152 // time the associated network configuration can be removed. |
| 153 pref_service_->Set(prefs::kDisconnectingWifiNetworkGuid, |
| 154 base::Value(wifi_network_guid)); |
| 155 |
108 const NetworkState* wifi_network_state = | 156 const NetworkState* wifi_network_state = |
109 network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid); | 157 network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid); |
110 if (wifi_network_state) { | 158 if (wifi_network_state) { |
111 network_connection_handler_->DisconnectNetwork( | 159 network_connection_handler_->DisconnectNetwork( |
112 wifi_network_state->path(), | 160 wifi_network_state->path(), |
113 base::Bind(&TetherDisconnector::OnSuccessfulWifiDisconnect, | 161 base::Bind(&TetherDisconnectorImpl::OnSuccessfulWifiDisconnect, |
114 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, | 162 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, |
115 success_callback, error_callback), | 163 success_callback, error_callback), |
116 base::Bind(&TetherDisconnector::OnFailedWifiDisconnect, | 164 base::Bind(&TetherDisconnectorImpl::OnFailedWifiDisconnect, |
117 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, | 165 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, |
118 success_callback, error_callback)); | 166 success_callback, error_callback)); |
119 } else { | 167 } else { |
120 PA_LOG(ERROR) << "Wi-Fi NetworkState for GUID " << wifi_network_guid << " " | 168 PA_LOG(ERROR) << "Wi-Fi NetworkState for GUID " << wifi_network_guid << " " |
121 << "was not registered. Cannot disconnect."; | 169 << "was not registered. Cannot disconnect."; |
122 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | 170 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); |
123 } | 171 } |
124 | 172 |
125 // In addition to disconnecting from the Wi-Fi network, this device must also | 173 // In addition to disconnecting from the Wi-Fi network, this device must also |
126 // send a DisconnectTetheringRequest to the tether host so that it can shut | 174 // send a DisconnectTetheringRequest to the tether host so that it can shut |
127 // down its Wi-Fi hotspot if it is no longer in use. | 175 // down its Wi-Fi hotspot if it is no longer in use. |
128 const std::string device_id = | 176 const std::string device_id = |
129 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid( | 177 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid( |
130 tether_network_guid); | 178 tether_network_guid); |
131 tether_host_fetcher_->FetchTetherHost( | 179 tether_host_fetcher_->FetchTetherHost( |
132 device_id, base::Bind(&TetherDisconnector::OnTetherHostFetched, | 180 device_id, base::Bind(&TetherDisconnectorImpl::OnTetherHostFetched, |
133 weak_ptr_factory_.GetWeakPtr(), device_id)); | 181 weak_ptr_factory_.GetWeakPtr(), device_id)); |
134 } | 182 } |
135 | 183 |
136 void TetherDisconnector::OnOperationFinished(const std::string& device_id, | 184 void TetherDisconnectorImpl::OnOperationFinished(const std::string& device_id, |
137 bool success) { | 185 bool success) { |
138 if (success) { | 186 if (success) { |
139 PA_LOG(INFO) << "Successfully sent DisconnectTetheringRequest to device " | 187 PA_LOG(INFO) << "Successfully sent DisconnectTetheringRequest to device " |
140 << "with ID " | 188 << "with ID " |
141 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id); | 189 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id); |
142 } else { | 190 } else { |
143 PA_LOG(ERROR) << "Failed to send DisconnectTetheringRequest to device " | 191 PA_LOG(ERROR) << "Failed to send DisconnectTetheringRequest to device " |
144 << "with ID " | 192 << "with ID " |
145 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( | 193 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( |
146 device_id); | 194 device_id); |
147 } | 195 } |
148 | 196 |
149 // Regardless of success/failure, unregister as a listener and delete the | 197 // Regardless of success/failure, unregister as a listener and delete the |
150 // operation. | 198 // operation. |
151 disconnect_tethering_operation_->RemoveObserver(this); | 199 disconnect_tethering_operation_->RemoveObserver(this); |
152 disconnect_tethering_operation_.reset(); | 200 disconnect_tethering_operation_.reset(); |
153 } | 201 } |
154 | 202 |
155 void TetherDisconnector::OnSuccessfulWifiDisconnect( | 203 void TetherDisconnectorImpl::OnSuccessfulWifiDisconnect( |
156 const std::string& wifi_network_guid, | 204 const std::string& wifi_network_guid, |
157 const base::Closure& success_callback, | 205 const base::Closure& success_callback, |
158 const network_handler::StringResultCallback& error_callback) { | 206 const network_handler::StringResultCallback& error_callback) { |
159 PA_LOG(INFO) << "Successfully disconnected from Wi-Fi network with GUID " | 207 PA_LOG(INFO) << "Successfully disconnected from Wi-Fi network with GUID " |
160 << wifi_network_guid << "."; | 208 << wifi_network_guid << "."; |
161 CleanUpAfterWifiDisconnection(true /* success */, wifi_network_guid, | 209 CleanUpAfterWifiDisconnection(true /* success */, wifi_network_guid, |
162 success_callback, error_callback); | 210 success_callback, error_callback); |
163 } | 211 } |
164 | 212 |
165 void TetherDisconnector::OnFailedWifiDisconnect( | 213 void TetherDisconnectorImpl::OnFailedWifiDisconnect( |
166 const std::string& wifi_network_guid, | 214 const std::string& wifi_network_guid, |
167 const base::Closure& success_callback, | 215 const base::Closure& success_callback, |
168 const network_handler::StringResultCallback& error_callback, | 216 const network_handler::StringResultCallback& error_callback, |
169 const std::string& error_name, | 217 const std::string& error_name, |
170 std::unique_ptr<base::DictionaryValue> error_data) { | 218 std::unique_ptr<base::DictionaryValue> error_data) { |
171 PA_LOG(ERROR) << "Failed to disconnect from Wi-Fi network with GUID " | 219 PA_LOG(ERROR) << "Failed to disconnect from Wi-Fi network with GUID " |
172 << wifi_network_guid << ". Error name: " << error_name; | 220 << wifi_network_guid << ". Error name: " << error_name; |
173 CleanUpAfterWifiDisconnection(false /* success */, wifi_network_guid, | 221 CleanUpAfterWifiDisconnection(false /* success */, wifi_network_guid, |
174 success_callback, error_callback); | 222 success_callback, error_callback); |
175 } | 223 } |
176 | 224 |
177 void TetherDisconnector::CleanUpAfterWifiDisconnection( | 225 void TetherDisconnectorImpl::CleanUpAfterWifiDisconnection( |
178 bool success, | 226 bool success, |
179 const std::string& wifi_network_guid, | 227 const std::string& wifi_network_guid, |
180 const base::Closure& success_callback, | 228 const base::Closure& success_callback, |
181 const network_handler::StringResultCallback& error_callback) { | 229 const network_handler::StringResultCallback& error_callback) { |
| 230 network_configuration_remover_->RemoveNetworkConfiguration(wifi_network_guid); |
| 231 pref_service_->ClearPref(prefs::kDisconnectingWifiNetworkGuid); |
| 232 |
182 if (success) | 233 if (success) |
183 success_callback.Run(); | 234 success_callback.Run(); |
184 else | 235 else |
185 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | 236 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); |
186 | |
187 network_configuration_remover_->RemoveNetworkConfiguration(wifi_network_guid); | |
188 } | 237 } |
189 | 238 |
190 void TetherDisconnector::OnTetherHostFetched( | 239 void TetherDisconnectorImpl::OnTetherHostFetched( |
191 const std::string& device_id, | 240 const std::string& device_id, |
192 std::unique_ptr<cryptauth::RemoteDevice> tether_host) { | 241 std::unique_ptr<cryptauth::RemoteDevice> tether_host) { |
193 if (!tether_host) { | 242 if (!tether_host) { |
194 PA_LOG(ERROR) << "Could not fetch device with ID " | 243 PA_LOG(ERROR) << "Could not fetch device with ID " |
195 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | 244 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
196 << ". Unable to send DisconnectTetheringRequest."; | 245 << ". Unable to send DisconnectTetheringRequest."; |
197 return; | 246 return; |
198 } | 247 } |
199 | 248 |
200 disconnect_tethering_operation_ = | 249 disconnect_tethering_operation_ = |
201 DisconnectTetheringOperation::Factory::NewInstance( | 250 DisconnectTetheringOperation::Factory::NewInstance( |
202 *tether_host, ble_connection_manager_); | 251 *tether_host, ble_connection_manager_); |
203 | 252 |
204 // Start the operation; OnOperationFinished() will be called when finished. | 253 // Start the operation; OnOperationFinished() will be called when finished. |
205 disconnect_tethering_operation_->AddObserver(this); | 254 disconnect_tethering_operation_->AddObserver(this); |
206 disconnect_tethering_operation_->Initialize(); | 255 disconnect_tethering_operation_->Initialize(); |
207 } | 256 } |
208 | 257 |
209 } // namespace tether | 258 } // namespace tether |
210 | 259 |
211 } // namespace chromeos | 260 } // namespace chromeos |
OLD | NEW |