OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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 "chrome/browser/chromeos/extensions/networking_private_api.h" | |
6 | |
7 #include "base/bind_helpers.h" | |
8 #include "chrome/browser/chromeos/extensions/networking_private_api_factory.h" | |
9 #include "chrome/browser/extensions/extension_function_registry.h" | |
10 #include "chromeos/dbus/dbus_thread_manager.h" | |
11 #include "chromeos/dbus/shill_manager_client.h" | |
12 #include "chromeos/dbus/shill_service_client.h" | |
13 #include "chromeos/network/onc/onc_constants.h" | |
14 #include "chromeos/network/onc/onc_signature.h" | |
15 #include "chromeos/network/onc/onc_translation_tables.h" | |
16 #include "chromeos/network/onc/onc_translator.h" | |
17 #include "dbus/object_path.h" | |
18 #include "third_party/cros_system_api/dbus/service_constants.h" | |
19 | |
20 namespace chromeos { | |
21 | |
22 namespace { | |
23 | |
24 // This creates a new ONC dictionary that only contains the information we're | |
25 // interested in passing on to JavaScript. | |
26 base::DictionaryValue* CreateFilteredResult( | |
27 const base::DictionaryValue& properties) { | |
28 scoped_ptr<base::DictionaryValue> onc_properties( | |
29 onc::TranslateShillServiceToONCPart( | |
30 properties, | |
31 &onc::kNetworkConfigurationSignature)); | |
32 | |
33 // Now we filter it so we only include properties that we care about for this | |
34 // interface. | |
35 const char* desired_fields[] = { | |
pneubeck (no reviews)
2013/01/18 13:22:36
may add static
but could even be
static const ch
Greg Spencer (Chromium)
2013/01/18 19:53:56
Done.
| |
36 onc::network_type::kWiFi, | |
37 onc::kName, | |
38 onc::kGUID, | |
39 onc::kType, | |
40 onc::kStatus, | |
41 }; | |
42 | |
43 scoped_ptr<base::DictionaryValue> filtered_result(new base::DictionaryValue); | |
44 for (size_t i = 0; i < arraysize(desired_fields); ++i) { | |
45 base::Value* value; | |
46 if (onc_properties->Get(desired_fields[i], &value)) | |
47 filtered_result->Set(desired_fields[i], value->DeepCopy()); | |
48 } | |
49 return filtered_result.release(); | |
50 } | |
51 | |
52 } // namespace | |
53 | |
54 | |
55 //////////////////////////////////////////////////////////////////////////////// | |
56 // NetworkingGetPropertiesFunction | |
57 | |
58 NetworkingGetPropertiesFunction::~NetworkingGetPropertiesFunction() { | |
59 } | |
60 | |
61 bool NetworkingGetPropertiesFunction::RunImpl() { | |
62 std::string service_path; | |
63 if (!args_->GetString(0, &service_path)) | |
64 return false; | |
65 | |
66 DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( | |
67 dbus::ObjectPath(service_path), base::Bind( | |
68 &NetworkingGetPropertiesFunction::ResultCallback, this)); | |
69 return true; | |
70 } | |
71 | |
72 void NetworkingGetPropertiesFunction::ResultCallback( | |
73 DBusMethodCallStatus call_status, | |
74 const base::DictionaryValue& result) { | |
75 scoped_ptr<base::DictionaryValue> filtered_result( | |
76 CreateFilteredResult(result)); | |
77 | |
78 SetResult(filtered_result.release()); | |
79 SendResponse(true); | |
80 } | |
81 | |
82 //////////////////////////////////////////////////////////////////////////////// | |
83 // NetworkingGetVisibleNetworksFunction::ResultList | |
84 | |
85 NetworkingGetVisibleNetworksFunction::ResultList::ResultList(int count) | |
86 : list_(new base::ListValue), count_(count) { | |
87 } | |
88 | |
89 NetworkingGetVisibleNetworksFunction::ResultList::~ResultList() { | |
90 } | |
91 | |
92 void NetworkingGetVisibleNetworksFunction::ResultList::Append( | |
93 base::Value* value) { | |
94 list_->Append(value); | |
95 } | |
96 | |
97 //////////////////////////////////////////////////////////////////////////////// | |
98 // NetworkingGetVisibleNetworksFunction::ScopedDecrementer | |
99 | |
100 NetworkingGetVisibleNetworksFunction::ScopedDecrementer::ScopedDecrementer( | |
101 NetworkingGetVisibleNetworksFunction* parent, | |
102 scoped_refptr<NetworkingGetVisibleNetworksFunction::ResultList> result_list) | |
103 : parent_(parent), | |
104 result_list_(result_list) { | |
105 } | |
106 | |
107 NetworkingGetVisibleNetworksFunction::ScopedDecrementer::~ScopedDecrementer() { | |
108 --result_list_->count_; | |
109 if (result_list_->count() == 0) { | |
110 parent_->SetResult(result_list_->release()); | |
111 parent_->SendResponse(true); | |
112 } | |
113 } | |
114 | |
115 //////////////////////////////////////////////////////////////////////////////// | |
116 // NetworkingGetVisibleNetworksFunction | |
117 | |
118 NetworkingGetVisibleNetworksFunction::~NetworkingGetVisibleNetworksFunction() { | |
119 } | |
120 | |
121 bool NetworkingGetVisibleNetworksFunction::RunImpl() { | |
122 std::string network_type; | |
123 if (!args_->GetString(0, &network_type)) | |
124 return false; | |
125 | |
126 DBusThreadManager::Get()->GetShillManagerClient()->GetProperties( | |
127 base::Bind( | |
128 &NetworkingGetVisibleNetworksFunction::ManagerPropertiesCallback, | |
129 this, | |
130 network_type)); | |
131 return true; | |
132 } | |
133 | |
134 // For each of the available services, fire off a request for its properties. | |
135 void NetworkingGetVisibleNetworksFunction::ManagerPropertiesCallback( | |
136 const std::string& network_type, | |
137 DBusMethodCallStatus call_status, | |
138 const base::DictionaryValue& result) { | |
139 const base::ListValue* available_services; | |
140 if (!result.GetList(flimflam::kServicesProperty, &available_services)) { | |
141 error_ = "Error.noServices"; | |
142 SendResponse(false); | |
143 return; | |
144 } | |
145 | |
146 scoped_refptr<ResultList> results( | |
147 new ResultList(available_services->GetSize())); | |
148 for (size_t i = 0; i < available_services->GetSize(); ++i) { | |
pneubeck (no reviews)
2013/01/18 13:22:36
As you don't need the index, I'd prefer using List
Greg Spencer (Chromium)
2013/01/18 19:53:56
Done.
| |
149 std::string service_path; | |
150 available_services->GetString(i, &service_path); | |
151 DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( | |
152 dbus::ObjectPath(service_path), | |
153 base::Bind( | |
154 &NetworkingGetVisibleNetworksFunction::ServicePropertiesCallback, | |
155 this, | |
156 service_path, | |
157 network_type, | |
158 results)); | |
159 } | |
160 } | |
161 | |
162 // If this network is of the appropriate type, add it to the results and | |
163 // decrement the count. If the count hits zero, then send the result. | |
164 void NetworkingGetVisibleNetworksFunction::ServicePropertiesCallback( | |
165 const std::string& service_path, | |
166 const std::string& network_type, | |
167 scoped_refptr<ResultList> result_list, | |
168 DBusMethodCallStatus call_status, | |
169 const base::DictionaryValue& result) { | |
170 // We must decrement the count each time we get a callback, regardless of the | |
171 // outcome. | |
172 ScopedDecrementer decrementer(this, result_list); | |
pneubeck (no reviews)
2013/01/18 13:22:36
The only usage now and in the future seems to be t
Greg Spencer (Chromium)
2013/01/18 19:53:56
Yes, I suppose that's simpler. When I wrote the d
| |
173 | |
174 if (call_status != DBUS_METHOD_CALL_SUCCESS) | |
175 return; | |
176 | |
177 std::string shill_type; | |
178 if (!result.GetString(flimflam::kTypeProperty, &shill_type)) | |
179 return; | |
180 | |
181 std::string onc_type; | |
182 if (!TranslateStringToONC(onc::kNetworkTypeTable, shill_type, &onc_type)) | |
183 return; | |
184 | |
185 if (onc_type == network_type || | |
186 network_type == onc::network_type::kAllTypes) { | |
187 // TODO(gspencer): For now the "guid" we send back is going to look | |
188 // remarkably like the service path. Once this code starts using the | |
189 // NetworkStateHandler instead of Shill directly, we should remove this code | |
190 // so that we're sending back the actual GUID. The JavaScript shouldn't | |
191 // care: this ID is opaque to it, and it shouldn't store it anywhere. | |
192 scoped_ptr<base::DictionaryValue> filtered_result( | |
193 CreateFilteredResult(result)); | |
194 filtered_result->SetString(onc::kGUID, service_path); | |
195 result_list->Append(filtered_result.release()); | |
196 } | |
197 } | |
198 | |
199 //////////////////////////////////////////////////////////////////////////////// | |
200 // NetworkingRequestConnectFunction | |
201 | |
202 NetworkingRequestConnectFunction::~NetworkingRequestConnectFunction() { | |
203 } | |
204 | |
205 void NetworkingRequestConnectFunction::ConnectRequestSuccess() { | |
206 SendResponse(true); | |
207 } | |
208 | |
209 void NetworkingRequestConnectFunction::ConnectRequestFailed( | |
210 const std::string& errorName, | |
211 const std::string& errorMessage) { | |
212 error_ = errorName; | |
213 SendResponse(false); | |
214 } | |
215 | |
216 bool NetworkingRequestConnectFunction::RunImpl() { | |
217 std::string guid; | |
218 if (!args_->GetString(0, &guid)) | |
219 return false; | |
220 | |
221 // TODO(gspencer): For now, the "guid" we receive from the JavaScript is going | |
222 // to be the service path. Fix this so it actually looks up the service path | |
223 // from the GUID once we're using the NetworkStateHandler. | |
224 std::string service_path = guid; | |
225 | |
226 DBusThreadManager::Get()->GetShillServiceClient()->Connect( | |
227 dbus::ObjectPath(service_path), | |
228 base::Bind(&NetworkingRequestConnectFunction::ConnectRequestSuccess, | |
229 this), | |
230 base::Bind(&NetworkingRequestConnectFunction::ConnectRequestFailed, | |
231 this)); | |
232 return true; | |
233 } | |
234 | |
235 //////////////////////////////////////////////////////////////////////////////// | |
236 // NetworkingRequestDisconnectFunction | |
237 | |
238 NetworkingRequestDisconnectFunction::~NetworkingRequestDisconnectFunction() { | |
239 } | |
240 | |
241 void NetworkingRequestDisconnectFunction::DisconnectRequestSuccess() { | |
242 SendResponse(true); | |
243 } | |
244 | |
245 void NetworkingRequestDisconnectFunction::DisconnectRequestFailed( | |
246 const std::string& errorName, | |
247 const std::string& errorMessage) { | |
248 error_ = errorName; | |
249 SendResponse(false); | |
250 } | |
251 | |
252 bool NetworkingRequestDisconnectFunction::RunImpl() { | |
253 std::string service_path; | |
254 if (!args_->GetString(0, &service_path)) | |
255 return false; | |
256 | |
257 DBusThreadManager::Get()->GetShillServiceClient()->Connect( | |
258 dbus::ObjectPath(service_path), | |
259 base::Bind(&NetworkingRequestDisconnectFunction::DisconnectRequestSuccess, | |
260 this), | |
261 base::Bind(&NetworkingRequestDisconnectFunction::DisconnectRequestFailed, | |
262 this)); | |
263 return true; | |
264 } | |
265 | |
266 //////////////////////////////////////////////////////////////////////////////// | |
267 // NetworkingPrivateAPI | |
268 | |
269 NetworkingPrivateAPI::NetworkingPrivateAPI(Profile* profile) { | |
270 ExtensionFunctionRegistry* registry = | |
271 ExtensionFunctionRegistry::GetInstance(); | |
272 registry->RegisterFunction<NetworkingGetPropertiesFunction>(); | |
273 registry->RegisterFunction<NetworkingGetVisibleNetworksFunction>(); | |
274 registry->RegisterFunction<NetworkingRequestConnectFunction>(); | |
275 registry->RegisterFunction<NetworkingRequestDisconnectFunction>(); | |
276 } | |
277 | |
278 NetworkingPrivateAPI::~NetworkingPrivateAPI() { | |
279 } | |
280 | |
281 void NetworkingPrivateAPI::Shutdown() { | |
282 } | |
283 | |
284 // static | |
285 NetworkingPrivateAPI* NetworkingPrivateAPI::Get(Profile* profile) { | |
286 return NetworkingPrivateAPIFactory::GetForProfile(profile); | |
287 } | |
288 | |
289 } // namespace chromeos | |
OLD | NEW |