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.h" |
6 | 6 |
7 #include "base/values.h" | 7 #include "chromeos/components/tether/pref_names.h" |
8 #include "chromeos/components/tether/active_host.h" | 8 #include "components/prefs/pref_registry_simple.h" |
9 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" | |
10 #include "chromeos/components/tether/network_configuration_remover.h" | |
11 #include "chromeos/components/tether/tether_connector.h" | |
12 #include "chromeos/components/tether/tether_host_fetcher.h" | |
13 #include "chromeos/network/network_connection_handler.h" | |
14 #include "chromeos/network/network_state.h" | |
15 #include "chromeos/network/network_state_handler.h" | |
16 #include "components/proximity_auth/logging/logging.h" | |
17 | 9 |
18 namespace chromeos { | 10 namespace chromeos { |
19 | 11 |
20 namespace tether { | 12 namespace tether { |
21 | 13 |
22 TetherDisconnector::TetherDisconnector( | 14 // static |
23 NetworkConnectionHandler* network_connection_handler, | 15 void TetherDisconnector::RegisterPrefs(PrefRegistrySimple* registry) { |
Ryan Hansberry
2017/07/11 22:23:56
You need to call this from Initializer.
Kyle Horimoto
2017/07/12 01:42:59
That's already done.
Ryan Hansberry
2017/07/12 17:10:10
Oops, also did not see that on first glance.
| |
24 NetworkStateHandler* network_state_handler, | 16 registry->RegisterStringPref(prefs::kDisconnectingWifiNetworkGuid, ""); |
25 ActiveHost* active_host, | |
26 BleConnectionManager* ble_connection_manager, | |
27 NetworkConfigurationRemover* network_configuration_remover, | |
28 TetherConnector* tether_connector, | |
29 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map, | |
30 TetherHostFetcher* tether_host_fetcher) | |
31 : network_connection_handler_(network_connection_handler), | |
32 network_state_handler_(network_state_handler), | |
33 active_host_(active_host), | |
34 ble_connection_manager_(ble_connection_manager), | |
35 network_configuration_remover_(network_configuration_remover), | |
36 tether_connector_(tether_connector), | |
37 device_id_tether_network_guid_map_(device_id_tether_network_guid_map), | |
38 tether_host_fetcher_(tether_host_fetcher), | |
39 weak_ptr_factory_(this) {} | |
40 | |
41 TetherDisconnector::~TetherDisconnector() { | |
42 if (disconnect_tethering_operation_) | |
43 disconnect_tethering_operation_->RemoveObserver(this); | |
44 } | |
45 | |
46 void TetherDisconnector::DisconnectFromNetwork( | |
47 const std::string& tether_network_guid, | |
48 const base::Closure& success_callback, | |
49 const network_handler::StringResultCallback& error_callback) { | |
50 DCHECK(!tether_network_guid.empty()); | |
51 | |
52 ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus(); | |
53 std::string active_tether_network_guid = active_host_->GetTetherNetworkGuid(); | |
54 std::string active_wifi_network_guid = active_host_->GetWifiNetworkGuid(); | |
55 | |
56 if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) { | |
57 PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID " | |
58 << tether_network_guid << ", but no device is connected."; | |
59 error_callback.Run(NetworkConnectionHandler::kErrorNotConnected); | |
60 return; | |
61 } | |
62 | |
63 if (tether_network_guid != active_tether_network_guid) { | |
64 PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID " | |
65 << tether_network_guid << ", but that device is not the " | |
66 << "active host."; | |
67 error_callback.Run(NetworkConnectionHandler::kErrorNotConnected); | |
68 return; | |
69 } | |
70 | |
71 if (status == ActiveHost::ActiveHostStatus::CONNECTING) { | |
72 // Note: CancelConnectionAttempt() internally sets the active host to be | |
73 // disconnected. | |
74 if (tether_connector_->CancelConnectionAttempt(tether_network_guid)) { | |
75 PA_LOG(INFO) << "Disconnect requested for Tether network with GUID " | |
76 << tether_network_guid << ", which had not yet connected. " | |
77 << "Canceled in-progress connection attempt."; | |
78 success_callback.Run(); | |
79 return; | |
80 } | |
81 | |
82 PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID " | |
83 << tether_network_guid << " (not yet connected), but " | |
84 << "canceling connection attempt failed."; | |
85 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | |
86 return; | |
87 } | |
88 | |
89 DCHECK(!active_wifi_network_guid.empty()); | |
90 DCHECK(!disconnect_tethering_operation_); | |
91 DisconnectActiveWifiConnection(tether_network_guid, active_wifi_network_guid, | |
92 success_callback, error_callback); | |
93 } | |
94 | |
95 void TetherDisconnector::DisconnectActiveWifiConnection( | |
96 const std::string& tether_network_guid, | |
97 const std::string& wifi_network_guid, | |
98 const base::Closure& success_callback, | |
99 const network_handler::StringResultCallback& error_callback) { | |
100 // First, disconnect the active host so that the user gets visual indication | |
101 // that the disconnection is in progress as quickly as possible. | |
102 // TODO(hansberry): This will result in the Tether network becoming | |
103 // disconnected, but the Wi-Fi network will still be connected until the | |
104 // DisconnectNetwork() call below completes. This will result in a jarring UI | |
105 // transition which needs to be fixed. | |
106 active_host_->SetActiveHostDisconnected(); | |
107 | |
108 const NetworkState* wifi_network_state = | |
109 network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid); | |
110 if (wifi_network_state) { | |
111 network_connection_handler_->DisconnectNetwork( | |
112 wifi_network_state->path(), | |
113 base::Bind(&TetherDisconnector::OnSuccessfulWifiDisconnect, | |
114 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, | |
115 success_callback, error_callback), | |
116 base::Bind(&TetherDisconnector::OnFailedWifiDisconnect, | |
117 weak_ptr_factory_.GetWeakPtr(), wifi_network_guid, | |
118 success_callback, error_callback)); | |
119 } else { | |
120 PA_LOG(ERROR) << "Wi-Fi NetworkState for GUID " << wifi_network_guid << " " | |
121 << "was not registered. Cannot disconnect."; | |
122 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | |
123 } | |
124 | |
125 // 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 | |
127 // down its Wi-Fi hotspot if it is no longer in use. | |
128 const std::string device_id = | |
129 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid( | |
130 tether_network_guid); | |
131 tether_host_fetcher_->FetchTetherHost( | |
132 device_id, base::Bind(&TetherDisconnector::OnTetherHostFetched, | |
133 weak_ptr_factory_.GetWeakPtr(), device_id)); | |
134 } | |
135 | |
136 void TetherDisconnector::OnOperationFinished(const std::string& device_id, | |
137 bool success) { | |
138 if (success) { | |
139 PA_LOG(INFO) << "Successfully sent DisconnectTetheringRequest to device " | |
140 << "with ID " | |
141 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id); | |
142 } else { | |
143 PA_LOG(ERROR) << "Failed to send DisconnectTetheringRequest to device " | |
144 << "with ID " | |
145 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( | |
146 device_id); | |
147 } | |
148 | |
149 // Regardless of success/failure, unregister as a listener and delete the | |
150 // operation. | |
151 disconnect_tethering_operation_->RemoveObserver(this); | |
152 disconnect_tethering_operation_.reset(); | |
153 } | |
154 | |
155 void TetherDisconnector::OnSuccessfulWifiDisconnect( | |
156 const std::string& wifi_network_guid, | |
157 const base::Closure& success_callback, | |
158 const network_handler::StringResultCallback& error_callback) { | |
159 PA_LOG(INFO) << "Successfully disconnected from Wi-Fi network with GUID " | |
160 << wifi_network_guid << "."; | |
161 CleanUpAfterWifiDisconnection(true /* success */, wifi_network_guid, | |
162 success_callback, error_callback); | |
163 } | |
164 | |
165 void TetherDisconnector::OnFailedWifiDisconnect( | |
166 const std::string& wifi_network_guid, | |
167 const base::Closure& success_callback, | |
168 const network_handler::StringResultCallback& error_callback, | |
169 const std::string& error_name, | |
170 std::unique_ptr<base::DictionaryValue> error_data) { | |
171 PA_LOG(ERROR) << "Failed to disconnect from Wi-Fi network with GUID " | |
172 << wifi_network_guid << ". Error name: " << error_name; | |
173 CleanUpAfterWifiDisconnection(false /* success */, wifi_network_guid, | |
174 success_callback, error_callback); | |
175 } | |
176 | |
177 void TetherDisconnector::CleanUpAfterWifiDisconnection( | |
178 bool success, | |
179 const std::string& wifi_network_guid, | |
180 const base::Closure& success_callback, | |
181 const network_handler::StringResultCallback& error_callback) { | |
182 if (success) | |
183 success_callback.Run(); | |
184 else | |
185 error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed); | |
186 | |
187 network_configuration_remover_->RemoveNetworkConfiguration(wifi_network_guid); | |
188 } | |
189 | |
190 void TetherDisconnector::OnTetherHostFetched( | |
191 const std::string& device_id, | |
192 std::unique_ptr<cryptauth::RemoteDevice> tether_host) { | |
193 if (!tether_host) { | |
194 PA_LOG(ERROR) << "Could not fetch device with ID " | |
195 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) | |
196 << ". Unable to send DisconnectTetheringRequest."; | |
197 return; | |
198 } | |
199 | |
200 disconnect_tethering_operation_ = | |
201 DisconnectTetheringOperation::Factory::NewInstance( | |
202 *tether_host, ble_connection_manager_); | |
203 | |
204 // Start the operation; OnOperationFinished() will be called when finished. | |
205 disconnect_tethering_operation_->AddObserver(this); | |
206 disconnect_tethering_operation_->Initialize(); | |
207 } | 17 } |
208 | 18 |
209 } // namespace tether | 19 } // namespace tether |
210 | 20 |
211 } // namespace chromeos | 21 } // namespace chromeos |
OLD | NEW |