02fbdb959bf6e9130763e8d0be17b9231ba1f76d
[platform/framework/web/crosswalk.git] / src / chromeos / network / network_device_handler_impl.cc
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.
4
5 #include "chromeos/network/network_device_handler_impl.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/values.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "chromeos/dbus/shill_device_client.h"
12 #include "chromeos/dbus/shill_ipconfig_client.h"
13 #include "chromeos/network/device_state.h"
14 #include "chromeos/network/network_event_log.h"
15 #include "chromeos/network/network_handler_callbacks.h"
16 #include "chromeos/network/network_state_handler.h"
17 #include "chromeos/network/shill_property_util.h"
18 #include "dbus/object_path.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
20
21 namespace chromeos {
22
23 namespace {
24
25 // TODO(armansito): Add bindings for these to service_constants.h
26 // (crbug.com/256889)
27 const char kShillErrorFailure[] = "org.chromium.flimflam.Error.Failure";
28 const char kShillErrorNotSupported[] =
29     "org.chromium.flimflam.Error.NotSupported";
30
31 std::string GetErrorNameForShillError(const std::string& shill_error_name) {
32   // TODO(armansito): Use the new SIM error names once the ones below get
33   // deprecated (crbug.com/256855)
34   if (shill_error_name == kShillErrorFailure)
35     return NetworkDeviceHandler::kErrorFailure;
36   if (shill_error_name == kShillErrorNotSupported)
37     return NetworkDeviceHandler::kErrorNotSupported;
38   if (shill_error_name == shill::kErrorIncorrectPinMsg)
39     return NetworkDeviceHandler::kErrorIncorrectPin;
40   if (shill_error_name == shill::kErrorPinBlockedMsg)
41     return NetworkDeviceHandler::kErrorPinBlocked;
42   if (shill_error_name == shill::kErrorPinRequiredMsg)
43     return NetworkDeviceHandler::kErrorPinRequired;
44   return NetworkDeviceHandler::kErrorUnknown;
45 }
46
47 void InvokeErrorCallback(const std::string& service_path,
48                          const network_handler::ErrorCallback& error_callback,
49                          const std::string& error_name) {
50   std::string error_msg = "Device Error: " + error_name;
51   NET_LOG_ERROR(error_msg, service_path);
52   network_handler::RunErrorCallback(
53       error_callback, service_path, error_name, error_msg);
54 }
55
56 void HandleShillCallFailure(
57     const std::string& device_path,
58     const network_handler::ErrorCallback& error_callback,
59     const std::string& shill_error_name,
60     const std::string& shill_error_message) {
61   network_handler::ShillErrorCallbackFunction(
62       GetErrorNameForShillError(shill_error_name),
63       device_path,
64       error_callback,
65       shill_error_name,
66       shill_error_message);
67 }
68
69 void IPConfigRefreshCallback(const std::string& ipconfig_path,
70                              DBusMethodCallStatus call_status) {
71   if (call_status != DBUS_METHOD_CALL_SUCCESS) {
72     NET_LOG_ERROR(
73         base::StringPrintf("IPConfigs.Refresh Failed: %d", call_status),
74         ipconfig_path);
75   } else {
76     NET_LOG_EVENT("IPConfigs.Refresh Succeeded", ipconfig_path);
77   }
78 }
79
80 void RefreshIPConfigsCallback(
81     const base::Closure& callback,
82     const network_handler::ErrorCallback& error_callback,
83     const std::string& device_path,
84     const base::DictionaryValue& properties) {
85   const base::ListValue* ip_configs;
86   if (!properties.GetListWithoutPathExpansion(
87           shill::kIPConfigsProperty, &ip_configs)) {
88     NET_LOG_ERROR("RequestRefreshIPConfigs Failed", device_path);
89     network_handler::ShillErrorCallbackFunction(
90         "RequestRefreshIPConfigs Failed",
91         device_path,
92         error_callback,
93         std::string("Missing ") + shill::kIPConfigsProperty, "");
94     return;
95   }
96
97   for (size_t i = 0; i < ip_configs->GetSize(); i++) {
98     std::string ipconfig_path;
99     if (!ip_configs->GetString(i, &ipconfig_path))
100       continue;
101     DBusThreadManager::Get()->GetShillIPConfigClient()->Refresh(
102         dbus::ObjectPath(ipconfig_path),
103         base::Bind(&IPConfigRefreshCallback, ipconfig_path));
104   }
105   // It is safe to invoke |callback| here instead of waiting for the
106   // IPConfig.Refresh callbacks to complete because the Refresh DBus calls will
107   // be executed in order and thus before any further DBus requests that
108   // |callback| may issue.
109   if (!callback.is_null())
110     callback.Run();
111 }
112
113 void ProposeScanCallback(
114     const std::string& device_path,
115     const base::Closure& callback,
116     const network_handler::ErrorCallback& error_callback,
117     DBusMethodCallStatus call_status) {
118   if (call_status != DBUS_METHOD_CALL_SUCCESS) {
119     network_handler::ShillErrorCallbackFunction(
120         "Device.ProposeScan Failed",
121         device_path,
122         error_callback,
123         base::StringPrintf("DBus call failed: %d", call_status), "");
124     return;
125   }
126   NET_LOG_EVENT("Device.ProposeScan succeeded.", device_path);
127   if (!callback.is_null())
128     callback.Run();
129 }
130
131 void SetDevicePropertyInternal(
132     const std::string& device_path,
133     const std::string& property_name,
134     const base::Value& value,
135     const base::Closure& callback,
136     const network_handler::ErrorCallback& error_callback) {
137   DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
138       dbus::ObjectPath(device_path),
139       property_name,
140       value,
141       callback,
142       base::Bind(&HandleShillCallFailure, device_path, error_callback));
143 }
144
145 }  // namespace
146
147 NetworkDeviceHandlerImpl::~NetworkDeviceHandlerImpl() {
148   network_state_handler_->RemoveObserver(this, FROM_HERE);
149 }
150
151 void NetworkDeviceHandlerImpl::GetDeviceProperties(
152     const std::string& device_path,
153     const network_handler::DictionaryResultCallback& callback,
154     const network_handler::ErrorCallback& error_callback) const {
155   DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties(
156       dbus::ObjectPath(device_path),
157       base::Bind(&network_handler::GetPropertiesCallback,
158                  callback, error_callback, device_path));
159 }
160
161 void NetworkDeviceHandlerImpl::SetDeviceProperty(
162     const std::string& device_path,
163     const std::string& property_name,
164     const base::Value& value,
165     const base::Closure& callback,
166     const network_handler::ErrorCallback& error_callback) {
167   const char* const property_blacklist[] = {
168       // Must only be changed by policy/owner through.
169       shill::kCellularAllowRoamingProperty
170   };
171
172   for (size_t i = 0; i < arraysize(property_blacklist); ++i) {
173     if (property_name == property_blacklist[i]) {
174       InvokeErrorCallback(
175           device_path,
176           error_callback,
177           "SetDeviceProperty called on blacklisted property " + property_name);
178       return;
179     }
180   }
181
182   SetDevicePropertyInternal(
183       device_path, property_name, value, callback, error_callback);
184 }
185
186 void NetworkDeviceHandlerImpl::RequestRefreshIPConfigs(
187     const std::string& device_path,
188     const base::Closure& callback,
189     const network_handler::ErrorCallback& error_callback) {
190   GetDeviceProperties(device_path,
191                       base::Bind(&RefreshIPConfigsCallback,
192                                  callback, error_callback),
193                       error_callback);
194 }
195
196 void NetworkDeviceHandlerImpl::ProposeScan(
197     const std::string& device_path,
198     const base::Closure& callback,
199     const network_handler::ErrorCallback& error_callback) {
200   DBusThreadManager::Get()->GetShillDeviceClient()->ProposeScan(
201       dbus::ObjectPath(device_path),
202       base::Bind(&ProposeScanCallback, device_path, callback, error_callback));
203 }
204
205 void NetworkDeviceHandlerImpl::RegisterCellularNetwork(
206     const std::string& device_path,
207     const std::string& network_id,
208     const base::Closure& callback,
209     const network_handler::ErrorCallback& error_callback) {
210   DBusThreadManager::Get()->GetShillDeviceClient()->Register(
211       dbus::ObjectPath(device_path),
212       network_id,
213       callback,
214       base::Bind(&HandleShillCallFailure, device_path, error_callback));
215 }
216
217 void NetworkDeviceHandlerImpl::SetCarrier(
218     const std::string& device_path,
219     const std::string& carrier,
220     const base::Closure& callback,
221     const network_handler::ErrorCallback& error_callback) {
222   DBusThreadManager::Get()->GetShillDeviceClient()->SetCarrier(
223       dbus::ObjectPath(device_path),
224       carrier,
225       callback,
226       base::Bind(&HandleShillCallFailure, device_path, error_callback));
227 }
228
229 void NetworkDeviceHandlerImpl::RequirePin(
230     const std::string& device_path,
231     bool require_pin,
232     const std::string& pin,
233     const base::Closure& callback,
234     const network_handler::ErrorCallback& error_callback) {
235   DBusThreadManager::Get()->GetShillDeviceClient()->RequirePin(
236       dbus::ObjectPath(device_path),
237       pin,
238       require_pin,
239       callback,
240       base::Bind(&HandleShillCallFailure, device_path, error_callback));
241 }
242
243 void NetworkDeviceHandlerImpl::EnterPin(
244     const std::string& device_path,
245     const std::string& pin,
246     const base::Closure& callback,
247     const network_handler::ErrorCallback& error_callback) {
248   DBusThreadManager::Get()->GetShillDeviceClient()->EnterPin(
249       dbus::ObjectPath(device_path),
250       pin,
251       callback,
252       base::Bind(&HandleShillCallFailure, device_path, error_callback));
253 }
254
255 void NetworkDeviceHandlerImpl::UnblockPin(
256     const std::string& device_path,
257     const std::string& puk,
258     const std::string& new_pin,
259     const base::Closure& callback,
260     const network_handler::ErrorCallback& error_callback) {
261   DBusThreadManager::Get()->GetShillDeviceClient()->UnblockPin(
262       dbus::ObjectPath(device_path),
263       puk,
264       new_pin,
265       callback,
266       base::Bind(&HandleShillCallFailure, device_path, error_callback));
267 }
268
269 void NetworkDeviceHandlerImpl::ChangePin(
270     const std::string& device_path,
271     const std::string& old_pin,
272     const std::string& new_pin,
273     const base::Closure& callback,
274     const network_handler::ErrorCallback& error_callback) {
275   DBusThreadManager::Get()->GetShillDeviceClient()->ChangePin(
276       dbus::ObjectPath(device_path),
277       old_pin,
278       new_pin,
279       callback,
280       base::Bind(&HandleShillCallFailure, device_path, error_callback));
281 }
282
283 void NetworkDeviceHandlerImpl::SetCellularAllowRoaming(
284     const bool allow_roaming) {
285   cellular_allow_roaming_ = allow_roaming;
286   ApplyCellularAllowRoamingToShill();
287 }
288
289 void NetworkDeviceHandlerImpl::DeviceListChanged() {
290   ApplyCellularAllowRoamingToShill();
291 }
292
293 NetworkDeviceHandlerImpl::NetworkDeviceHandlerImpl()
294     : network_state_handler_(NULL),
295       cellular_allow_roaming_(false) {}
296
297 void NetworkDeviceHandlerImpl::Init(
298     NetworkStateHandler* network_state_handler) {
299   DCHECK(network_state_handler);
300   network_state_handler_ = network_state_handler;
301   network_state_handler_->AddObserver(this, FROM_HERE);
302 }
303
304 void NetworkDeviceHandlerImpl::ApplyCellularAllowRoamingToShill() {
305   NetworkStateHandler::DeviceStateList list;
306   network_state_handler_->GetDeviceListByType(NetworkTypePattern::Cellular(),
307                                               &list);
308   if (list.empty()) {
309     NET_LOG_DEBUG("No cellular device is available",
310                   "Roaming is only supported by cellular devices.");
311     return;
312   }
313   for (NetworkStateHandler::DeviceStateList::const_iterator it = list.begin();
314       it != list.end(); ++it) {
315     const DeviceState* device_state = *it;
316     bool current_device_value;
317     if (!device_state->properties().GetBooleanWithoutPathExpansion(
318              shill::kCellularAllowRoamingProperty, &current_device_value)) {
319       NET_LOG_ERROR(
320           "Could not get \"allow roaming\" property from cellular "
321           "device.",
322           device_state->path());
323       continue;
324     }
325
326     // If roaming is required by the provider, always try to set to true.
327     bool new_device_value =
328         device_state->provider_requires_roaming() || cellular_allow_roaming_;
329
330     // Only set the value if the current value is different from
331     // |new_device_value|.
332     if (new_device_value == current_device_value)
333       continue;
334
335     SetDevicePropertyInternal(device_state->path(),
336                               shill::kCellularAllowRoamingProperty,
337                               base::FundamentalValue(new_device_value),
338                               base::Bind(&base::DoNothing),
339                               network_handler::ErrorCallback());
340   }
341 }
342
343 }  // namespace chromeos