Adding platform specific variables for MediaCanPlayTypeTest
[chromium-blink-merge.git] / chromeos / network / network_device_handler_impl.cc
blob85ff2153a2c6e72d0207923039731629cd9c065f
1 // Copyright 2013 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.
5 #include "chromeos/network/network_device_handler_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/time/time.h"
11 #include "base/values.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "chromeos/dbus/shill_device_client.h"
14 #include "chromeos/dbus/shill_ipconfig_client.h"
15 #include "chromeos/network/device_state.h"
16 #include "chromeos/network/network_event_log.h"
17 #include "chromeos/network/network_handler_callbacks.h"
18 #include "chromeos/network/network_state_handler.h"
19 #include "chromeos/network/shill_property_util.h"
20 #include "dbus/object_path.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
23 namespace chromeos {
25 namespace {
27 std::string GetErrorNameForShillError(const std::string& shill_error_name) {
28 if (shill_error_name == shill::kErrorResultFailure)
29 return NetworkDeviceHandler::kErrorFailure;
30 if (shill_error_name == shill::kErrorResultNotSupported)
31 return NetworkDeviceHandler::kErrorNotSupported;
32 if (shill_error_name == shill::kErrorResultIncorrectPin)
33 return NetworkDeviceHandler::kErrorIncorrectPin;
34 if (shill_error_name == shill::kErrorResultPinBlocked)
35 return NetworkDeviceHandler::kErrorPinBlocked;
36 if (shill_error_name == shill::kErrorResultPinRequired)
37 return NetworkDeviceHandler::kErrorPinRequired;
38 if (shill_error_name == shill::kErrorResultNotFound)
39 return NetworkDeviceHandler::kErrorDeviceMissing;
40 return NetworkDeviceHandler::kErrorUnknown;
43 void InvokeErrorCallback(const std::string& service_path,
44 const network_handler::ErrorCallback& error_callback,
45 const std::string& error_name) {
46 std::string error_msg = "Device Error: " + error_name;
47 NET_LOG_ERROR(error_msg, service_path);
48 network_handler::RunErrorCallback(
49 error_callback, service_path, error_name, error_msg);
52 void HandleShillCallFailure(
53 const std::string& device_path,
54 const network_handler::ErrorCallback& error_callback,
55 const std::string& shill_error_name,
56 const std::string& shill_error_message) {
57 network_handler::ShillErrorCallbackFunction(
58 GetErrorNameForShillError(shill_error_name),
59 device_path,
60 error_callback,
61 shill_error_name,
62 shill_error_message);
65 void IPConfigRefreshCallback(const std::string& ipconfig_path,
66 DBusMethodCallStatus call_status) {
67 if (call_status != DBUS_METHOD_CALL_SUCCESS) {
68 NET_LOG_ERROR(
69 base::StringPrintf("IPConfigs.Refresh Failed: %d", call_status),
70 ipconfig_path);
71 } else {
72 NET_LOG_EVENT("IPConfigs.Refresh Succeeded", ipconfig_path);
76 void RefreshIPConfigsCallback(
77 const base::Closure& callback,
78 const network_handler::ErrorCallback& error_callback,
79 const std::string& device_path,
80 const base::DictionaryValue& properties) {
81 const base::ListValue* ip_configs;
82 if (!properties.GetListWithoutPathExpansion(
83 shill::kIPConfigsProperty, &ip_configs)) {
84 NET_LOG_ERROR("RequestRefreshIPConfigs Failed", device_path);
85 network_handler::ShillErrorCallbackFunction(
86 "RequestRefreshIPConfigs Failed",
87 device_path,
88 error_callback,
89 std::string("Missing ") + shill::kIPConfigsProperty, "");
90 return;
93 for (size_t i = 0; i < ip_configs->GetSize(); i++) {
94 std::string ipconfig_path;
95 if (!ip_configs->GetString(i, &ipconfig_path))
96 continue;
97 DBusThreadManager::Get()->GetShillIPConfigClient()->Refresh(
98 dbus::ObjectPath(ipconfig_path),
99 base::Bind(&IPConfigRefreshCallback, ipconfig_path));
101 // It is safe to invoke |callback| here instead of waiting for the
102 // IPConfig.Refresh callbacks to complete because the Refresh DBus calls will
103 // be executed in order and thus before any further DBus requests that
104 // |callback| may issue.
105 if (!callback.is_null())
106 callback.Run();
109 void ProposeScanCallback(
110 const std::string& device_path,
111 const base::Closure& callback,
112 const network_handler::ErrorCallback& error_callback,
113 DBusMethodCallStatus call_status) {
114 if (call_status != DBUS_METHOD_CALL_SUCCESS) {
115 network_handler::ShillErrorCallbackFunction(
116 "Device.ProposeScan Failed",
117 device_path,
118 error_callback,
119 base::StringPrintf("DBus call failed: %d", call_status), "");
120 return;
122 NET_LOG_EVENT("Device.ProposeScan succeeded.", device_path);
123 if (!callback.is_null())
124 callback.Run();
127 void SetDevicePropertyInternal(
128 const std::string& device_path,
129 const std::string& property_name,
130 const base::Value& value,
131 const base::Closure& callback,
132 const network_handler::ErrorCallback& error_callback) {
133 DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
134 dbus::ObjectPath(device_path),
135 property_name,
136 value,
137 callback,
138 base::Bind(&HandleShillCallFailure, device_path, error_callback));
141 // Struct containing TDLS Operation parameters.
142 struct TDLSOperationParams {
143 TDLSOperationParams() : retry_count(0) {}
144 std::string operation;
145 std::string ip_or_mac_address;
146 int retry_count;
149 // Forward declare for PostDelayedTask.
150 void CallPerformTDLSOperation(
151 const std::string& device_path,
152 const TDLSOperationParams& params,
153 const network_handler::StringResultCallback& callback,
154 const network_handler::ErrorCallback& error_callback);
156 void TDLSSuccessCallback(
157 const std::string& device_path,
158 const TDLSOperationParams& params,
159 const network_handler::StringResultCallback& callback,
160 const network_handler::ErrorCallback& error_callback,
161 const std::string& result) {
162 std::string event_desc = "TDLSSuccessCallback: " + params.operation;
163 if (!result.empty())
164 event_desc += ": " + result;
165 NET_LOG_EVENT(event_desc, device_path);
166 if (params.operation != shill::kTDLSSetupOperation) {
167 if (!callback.is_null())
168 callback.Run(result);
169 return;
172 if (!result.empty())
173 NET_LOG_ERROR("Unexpected TDLS result: " + result, device_path);
175 // Send a delayed Status request after a successful Setup call.
176 TDLSOperationParams status_params;
177 status_params.operation = shill::kTDLSStatusOperation;
178 status_params.ip_or_mac_address = params.ip_or_mac_address;
180 const int64 kRequestStatusDelayMs = 500;
181 base::TimeDelta request_delay;
182 if (!DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface())
183 request_delay = base::TimeDelta::FromMilliseconds(kRequestStatusDelayMs);
185 base::MessageLoopProxy::current()->PostDelayedTask(
186 FROM_HERE,
187 base::Bind(&CallPerformTDLSOperation,
188 device_path, status_params, callback, error_callback),
189 request_delay);
192 void TDLSErrorCallback(
193 const std::string& device_path,
194 const TDLSOperationParams& params,
195 const network_handler::StringResultCallback& callback,
196 const network_handler::ErrorCallback& error_callback,
197 const std::string& dbus_error_name,
198 const std::string& dbus_error_message) {
199 // If a Setup operation receives an InProgress error, retry.
200 const int kMaxRetries = 5;
201 if (params.operation == shill::kTDLSSetupOperation &&
202 dbus_error_name == shill::kErrorResultInProgress &&
203 params.retry_count < kMaxRetries) {
204 TDLSOperationParams retry_params = params;
205 ++retry_params.retry_count;
206 NET_LOG_EVENT(base::StringPrintf("TDLS Retry: %d", params.retry_count),
207 device_path);
208 const int64 kReRequestDelayMs = 1000;
209 base::TimeDelta request_delay;
210 if (!DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface())
211 request_delay = base::TimeDelta::FromMilliseconds(kReRequestDelayMs);
213 base::MessageLoopProxy::current()->PostDelayedTask(
214 FROM_HERE,
215 base::Bind(&CallPerformTDLSOperation,
216 device_path, retry_params, callback, error_callback),
217 request_delay);
218 return;
221 NET_LOG_ERROR("TDLS Error:" + dbus_error_name + ":" + dbus_error_message,
222 device_path);
223 if (error_callback.is_null())
224 return;
226 const std::string error_name =
227 dbus_error_name == shill::kErrorResultInProgress ?
228 NetworkDeviceHandler::kErrorTimeout : NetworkDeviceHandler::kErrorUnknown;
229 const std::string& error_detail = params.ip_or_mac_address;
230 scoped_ptr<base::DictionaryValue> error_data(
231 network_handler::CreateDBusErrorData(
232 device_path, error_name, error_detail,
233 dbus_error_name, dbus_error_message));
234 error_callback.Run(error_name, error_data.Pass());
237 void CallPerformTDLSOperation(
238 const std::string& device_path,
239 const TDLSOperationParams& params,
240 const network_handler::StringResultCallback& callback,
241 const network_handler::ErrorCallback& error_callback) {
242 NET_LOG_EVENT("CallPerformTDLSOperation: " + params.operation, device_path);
243 DBusThreadManager::Get()->GetShillDeviceClient()->PerformTDLSOperation(
244 dbus::ObjectPath(device_path),
245 params.operation,
246 params.ip_or_mac_address,
247 base::Bind(&TDLSSuccessCallback,
248 device_path, params, callback, error_callback),
249 base::Bind(&TDLSErrorCallback,
250 device_path, params, callback, error_callback));
253 } // namespace
255 NetworkDeviceHandlerImpl::~NetworkDeviceHandlerImpl() {
256 network_state_handler_->RemoveObserver(this, FROM_HERE);
259 void NetworkDeviceHandlerImpl::GetDeviceProperties(
260 const std::string& device_path,
261 const network_handler::DictionaryResultCallback& callback,
262 const network_handler::ErrorCallback& error_callback) const {
263 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties(
264 dbus::ObjectPath(device_path),
265 base::Bind(&network_handler::GetPropertiesCallback,
266 callback, error_callback, device_path));
269 void NetworkDeviceHandlerImpl::SetDeviceProperty(
270 const std::string& device_path,
271 const std::string& property_name,
272 const base::Value& value,
273 const base::Closure& callback,
274 const network_handler::ErrorCallback& error_callback) {
275 const char* const property_blacklist[] = {
276 // Must only be changed by policy/owner through.
277 shill::kCellularAllowRoamingProperty
280 for (size_t i = 0; i < arraysize(property_blacklist); ++i) {
281 if (property_name == property_blacklist[i]) {
282 InvokeErrorCallback(
283 device_path,
284 error_callback,
285 "SetDeviceProperty called on blacklisted property " + property_name);
286 return;
290 SetDevicePropertyInternal(
291 device_path, property_name, value, callback, error_callback);
294 void NetworkDeviceHandlerImpl::RequestRefreshIPConfigs(
295 const std::string& device_path,
296 const base::Closure& callback,
297 const network_handler::ErrorCallback& error_callback) {
298 GetDeviceProperties(device_path,
299 base::Bind(&RefreshIPConfigsCallback,
300 callback, error_callback),
301 error_callback);
304 void NetworkDeviceHandlerImpl::ProposeScan(
305 const std::string& device_path,
306 const base::Closure& callback,
307 const network_handler::ErrorCallback& error_callback) {
308 DBusThreadManager::Get()->GetShillDeviceClient()->ProposeScan(
309 dbus::ObjectPath(device_path),
310 base::Bind(&ProposeScanCallback, device_path, callback, error_callback));
313 void NetworkDeviceHandlerImpl::RegisterCellularNetwork(
314 const std::string& device_path,
315 const std::string& network_id,
316 const base::Closure& callback,
317 const network_handler::ErrorCallback& error_callback) {
318 DBusThreadManager::Get()->GetShillDeviceClient()->Register(
319 dbus::ObjectPath(device_path),
320 network_id,
321 callback,
322 base::Bind(&HandleShillCallFailure, device_path, error_callback));
325 void NetworkDeviceHandlerImpl::SetCarrier(
326 const std::string& device_path,
327 const std::string& carrier,
328 const base::Closure& callback,
329 const network_handler::ErrorCallback& error_callback) {
330 DBusThreadManager::Get()->GetShillDeviceClient()->SetCarrier(
331 dbus::ObjectPath(device_path),
332 carrier,
333 callback,
334 base::Bind(&HandleShillCallFailure, device_path, error_callback));
337 void NetworkDeviceHandlerImpl::RequirePin(
338 const std::string& device_path,
339 bool require_pin,
340 const std::string& pin,
341 const base::Closure& callback,
342 const network_handler::ErrorCallback& error_callback) {
343 DBusThreadManager::Get()->GetShillDeviceClient()->RequirePin(
344 dbus::ObjectPath(device_path),
345 pin,
346 require_pin,
347 callback,
348 base::Bind(&HandleShillCallFailure, device_path, error_callback));
351 void NetworkDeviceHandlerImpl::EnterPin(
352 const std::string& device_path,
353 const std::string& pin,
354 const base::Closure& callback,
355 const network_handler::ErrorCallback& error_callback) {
356 DBusThreadManager::Get()->GetShillDeviceClient()->EnterPin(
357 dbus::ObjectPath(device_path),
358 pin,
359 callback,
360 base::Bind(&HandleShillCallFailure, device_path, error_callback));
363 void NetworkDeviceHandlerImpl::UnblockPin(
364 const std::string& device_path,
365 const std::string& puk,
366 const std::string& new_pin,
367 const base::Closure& callback,
368 const network_handler::ErrorCallback& error_callback) {
369 DBusThreadManager::Get()->GetShillDeviceClient()->UnblockPin(
370 dbus::ObjectPath(device_path),
371 puk,
372 new_pin,
373 callback,
374 base::Bind(&HandleShillCallFailure, device_path, error_callback));
377 void NetworkDeviceHandlerImpl::ChangePin(
378 const std::string& device_path,
379 const std::string& old_pin,
380 const std::string& new_pin,
381 const base::Closure& callback,
382 const network_handler::ErrorCallback& error_callback) {
383 DBusThreadManager::Get()->GetShillDeviceClient()->ChangePin(
384 dbus::ObjectPath(device_path),
385 old_pin,
386 new_pin,
387 callback,
388 base::Bind(&HandleShillCallFailure, device_path, error_callback));
391 void NetworkDeviceHandlerImpl::SetCellularAllowRoaming(
392 const bool allow_roaming) {
393 cellular_allow_roaming_ = allow_roaming;
394 ApplyCellularAllowRoamingToShill();
397 void NetworkDeviceHandlerImpl::SetWifiTDLSEnabled(
398 const std::string& ip_or_mac_address,
399 bool enabled,
400 const network_handler::StringResultCallback& callback,
401 const network_handler::ErrorCallback& error_callback) {
402 const DeviceState* device_state =
403 network_state_handler_->GetDeviceStateByType(NetworkTypePattern::WiFi());
404 if (!device_state) {
405 if (error_callback.is_null())
406 return;
407 scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
408 error_data->SetString(network_handler::kErrorName, kErrorDeviceMissing);
409 error_callback.Run(kErrorDeviceMissing, error_data.Pass());
410 return;
412 TDLSOperationParams params;
413 params.operation = enabled ? shill::kTDLSSetupOperation
414 : shill::kTDLSTeardownOperation;
415 params.ip_or_mac_address = ip_or_mac_address;
416 CallPerformTDLSOperation(
417 device_state->path(), params, callback, error_callback);
420 void NetworkDeviceHandlerImpl::GetWifiTDLSStatus(
421 const std::string& ip_or_mac_address,
422 const network_handler::StringResultCallback& callback,
423 const network_handler::ErrorCallback& error_callback) {
424 const DeviceState* device_state =
425 network_state_handler_->GetDeviceStateByType(NetworkTypePattern::WiFi());
426 if (!device_state) {
427 if (error_callback.is_null())
428 return;
429 scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
430 error_data->SetString(network_handler::kErrorName, kErrorDeviceMissing);
431 error_callback.Run(kErrorDeviceMissing, error_data.Pass());
432 return;
434 TDLSOperationParams params;
435 params.operation = shill::kTDLSStatusOperation;
436 params.ip_or_mac_address = ip_or_mac_address;
437 CallPerformTDLSOperation(
438 device_state->path(), params, callback, error_callback);
441 void NetworkDeviceHandlerImpl::DeviceListChanged() {
442 ApplyCellularAllowRoamingToShill();
445 NetworkDeviceHandlerImpl::NetworkDeviceHandlerImpl()
446 : network_state_handler_(NULL),
447 cellular_allow_roaming_(false) {}
449 void NetworkDeviceHandlerImpl::Init(
450 NetworkStateHandler* network_state_handler) {
451 DCHECK(network_state_handler);
452 network_state_handler_ = network_state_handler;
453 network_state_handler_->AddObserver(this, FROM_HERE);
456 void NetworkDeviceHandlerImpl::ApplyCellularAllowRoamingToShill() {
457 NetworkStateHandler::DeviceStateList list;
458 network_state_handler_->GetDeviceListByType(NetworkTypePattern::Cellular(),
459 &list);
460 if (list.empty()) {
461 NET_LOG_DEBUG("No cellular device is available",
462 "Roaming is only supported by cellular devices.");
463 return;
465 for (NetworkStateHandler::DeviceStateList::const_iterator it = list.begin();
466 it != list.end(); ++it) {
467 const DeviceState* device_state = *it;
468 bool current_allow_roaming = device_state->allow_roaming();
470 // If roaming is required by the provider, always try to set to true.
471 bool new_device_value =
472 device_state->provider_requires_roaming() || cellular_allow_roaming_;
474 // Only set the value if the current value is different from
475 // |new_device_value|.
476 if (new_device_value == current_allow_roaming)
477 continue;
479 SetDevicePropertyInternal(device_state->path(),
480 shill::kCellularAllowRoamingProperty,
481 base::FundamentalValue(new_device_value),
482 base::Bind(&base::DoNothing),
483 network_handler::ErrorCallback());
487 } // namespace chromeos