Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: chrome/browser/extensions/api/networking_private/networking_private_api.cc

Issue 378103002: Add NetworkingPrivateDelegate class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix stupid mac complaints Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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/extensions/api/networking_private/networking_private_ap i.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "chrome/browser/extensions/api/networking_private/networking_private_de legate.h"
11 #include "chrome/common/extensions/api/networking_private.h"
12 #include "components/onc/onc_constants.h"
13 #include "extensions/browser/extension_function_registry.h"
14
15 namespace {
16
17 const int kDefaultNetworkListLimit = 1000;
18
19 extensions::NetworkingPrivateDelegate* GetDelegate(
20 content::BrowserContext* browser_context) {
21 return extensions::NetworkingPrivateDelegate::GetForBrowserContext(
22 browser_context);
23 }
24
25 } // namespace
26
27 namespace private_api = extensions::api::networking_private;
28
29 namespace extensions {
30
31 namespace networking_private {
32
33 // static
34 const char kErrorInvalidNetworkGuid[] = "Error.InvalidNetworkGuid";
35 const char kErrorNetworkUnavailable[] = "Error.NetworkUnavailable";
36 const char kErrorEncryptionError[] = "Error.EncryptionError";
37 const char kErrorNotReady[] = "Error.NotReady";
38 const char kErrorNotSupported[] = "Error.NotSupported";
39
40 } // namespace networking_private
41
42 ////////////////////////////////////////////////////////////////////////////////
43 // NetworkingPrivateGetPropertiesFunction
44
45 NetworkingPrivateGetPropertiesFunction::
46 ~NetworkingPrivateGetPropertiesFunction() {
47 }
48
49 bool NetworkingPrivateGetPropertiesFunction::RunAsync() {
50 scoped_ptr<private_api::GetProperties::Params> params =
51 private_api::GetProperties::Params::Create(*args_);
52 EXTENSION_FUNCTION_VALIDATE(params);
53
54 GetDelegate(browser_context())->GetProperties(
55 params->network_guid,
56 base::Bind(&NetworkingPrivateGetPropertiesFunction::Success, this),
57 base::Bind(&NetworkingPrivateGetPropertiesFunction::Failure, this));
58 return true;
59 }
60
61 void NetworkingPrivateGetPropertiesFunction::Success(
62 scoped_ptr<base::DictionaryValue> result) {
63 SetResult(result.release());
64 SendResponse(true);
65 }
66
67 void NetworkingPrivateGetPropertiesFunction::Failure(const std::string& error) {
68 error_ = error;
69 SendResponse(false);
70 }
71
72 ////////////////////////////////////////////////////////////////////////////////
73 // NetworkingPrivateGetManagedPropertiesFunction
74
75 NetworkingPrivateGetManagedPropertiesFunction::
76 ~NetworkingPrivateGetManagedPropertiesFunction() {
77 }
78
79 bool NetworkingPrivateGetManagedPropertiesFunction::RunAsync() {
80 scoped_ptr<private_api::GetManagedProperties::Params> params =
81 private_api::GetManagedProperties::Params::Create(*args_);
82 EXTENSION_FUNCTION_VALIDATE(params);
83
84 GetDelegate(browser_context())->GetManagedProperties(
85 params->network_guid,
86 base::Bind(&NetworkingPrivateGetManagedPropertiesFunction::Success, this),
87 base::Bind(&NetworkingPrivateGetManagedPropertiesFunction::Failure,
88 this));
89 return true;
90 }
91
92 void NetworkingPrivateGetManagedPropertiesFunction::Success(
93 scoped_ptr<base::DictionaryValue> result) {
94 SetResult(result.release());
95 SendResponse(true);
96 }
97
98 void NetworkingPrivateGetManagedPropertiesFunction::Failure(
99 const std::string& error) {
100 error_ = error;
101 SendResponse(false);
102 }
103
104 ////////////////////////////////////////////////////////////////////////////////
105 // NetworkingPrivateGetStateFunction
106
107 NetworkingPrivateGetStateFunction::~NetworkingPrivateGetStateFunction() {
108 }
109
110 bool NetworkingPrivateGetStateFunction::RunAsync() {
111 scoped_ptr<private_api::GetState::Params> params =
112 private_api::GetState::Params::Create(*args_);
113 EXTENSION_FUNCTION_VALIDATE(params);
114
115 GetDelegate(browser_context())->GetState(
116 params->network_guid,
117 base::Bind(&NetworkingPrivateGetStateFunction::Success, this),
118 base::Bind(&NetworkingPrivateGetStateFunction::Failure, this));
119 return true;
120 }
121
122 void NetworkingPrivateGetStateFunction::Success(
123 scoped_ptr<base::DictionaryValue> result) {
124 SetResult(result.release());
125 SendResponse(true);
126 }
127
128 void NetworkingPrivateGetStateFunction::Failure(const std::string& error) {
129 error_ = error;
130 SendResponse(false);
131 }
132
133 ////////////////////////////////////////////////////////////////////////////////
134 // NetworkingPrivateSetPropertiesFunction
135
136 NetworkingPrivateSetPropertiesFunction::
137 ~NetworkingPrivateSetPropertiesFunction() {
138 }
139
140 bool NetworkingPrivateSetPropertiesFunction::RunAsync() {
141 scoped_ptr<private_api::SetProperties::Params> params =
142 private_api::SetProperties::Params::Create(*args_);
143 EXTENSION_FUNCTION_VALIDATE(params);
144
145 scoped_ptr<base::DictionaryValue> properties_dict(
146 params->properties.ToValue());
147
148 GetDelegate(browser_context())->SetProperties(
149 params->network_guid,
150 properties_dict.Pass(),
151 base::Bind(&NetworkingPrivateSetPropertiesFunction::Success, this),
152 base::Bind(&NetworkingPrivateSetPropertiesFunction::Failure, this));
153 return true;
154 }
155
156 void NetworkingPrivateSetPropertiesFunction::Success() {
157 SendResponse(true);
158 }
159
160 void NetworkingPrivateSetPropertiesFunction::Failure(const std::string& error) {
161 error_ = error;
162 SendResponse(false);
163 }
164
165 ////////////////////////////////////////////////////////////////////////////////
166 // NetworkingPrivateCreateNetworkFunction
167
168 NetworkingPrivateCreateNetworkFunction::
169 ~NetworkingPrivateCreateNetworkFunction() {
170 }
171
172 bool NetworkingPrivateCreateNetworkFunction::RunAsync() {
173 scoped_ptr<private_api::CreateNetwork::Params> params =
174 private_api::CreateNetwork::Params::Create(*args_);
175 EXTENSION_FUNCTION_VALIDATE(params);
176
177 scoped_ptr<base::DictionaryValue> properties_dict(
178 params->properties.ToValue());
179
180 GetDelegate(browser_context())->CreateNetwork(
181 params->shared,
182 properties_dict.Pass(),
183 base::Bind(&NetworkingPrivateCreateNetworkFunction::Success, this),
184 base::Bind(&NetworkingPrivateCreateNetworkFunction::Failure, this));
185 return true;
186 }
187
188 void NetworkingPrivateCreateNetworkFunction::Success(const std::string& guid) {
189 results_ = private_api::CreateNetwork::Results::Create(guid);
190 SendResponse(true);
191 }
192
193 void NetworkingPrivateCreateNetworkFunction::Failure(const std::string& error) {
194 error_ = error;
195 SendResponse(false);
196 }
197
198 ////////////////////////////////////////////////////////////////////////////////
199 // NetworkingPrivateGetNetworksFunction
200
201 NetworkingPrivateGetNetworksFunction::~NetworkingPrivateGetNetworksFunction() {
202 }
203
204 bool NetworkingPrivateGetNetworksFunction::RunAsync() {
205 scoped_ptr<private_api::GetNetworks::Params> params =
206 private_api::GetNetworks::Params::Create(*args_);
207 EXTENSION_FUNCTION_VALIDATE(params);
208
209 std::string network_type = private_api::ToString(params->filter.network_type);
210 const bool configured_only =
211 params->filter.configured ? *params->filter.configured : false;
212 const bool visible_only =
213 params->filter.visible ? *params->filter.visible : false;
214 const int limit =
215 params->filter.limit ? *params->filter.limit : kDefaultNetworkListLimit;
216
217 GetDelegate(browser_context())->GetNetworks(
218 network_type,
219 configured_only,
220 visible_only,
221 limit,
222 base::Bind(&NetworkingPrivateGetNetworksFunction::Success, this),
223 base::Bind(&NetworkingPrivateGetNetworksFunction::Failure, this));
224 return true;
225 }
226
227 void NetworkingPrivateGetNetworksFunction::Success(
228 scoped_ptr<base::ListValue> network_list) {
229 SetResult(network_list.release());
230 SendResponse(true);
231 }
232
233 void NetworkingPrivateGetNetworksFunction::Failure(const std::string& error) {
234 error_ = error;
235 SendResponse(false);
236 }
237
238 ////////////////////////////////////////////////////////////////////////////////
239 // NetworkingPrivateGetVisibleNetworksFunction
240
241 NetworkingPrivateGetVisibleNetworksFunction::
242 ~NetworkingPrivateGetVisibleNetworksFunction() {
243 }
244
245 bool NetworkingPrivateGetVisibleNetworksFunction::RunAsync() {
246 scoped_ptr<private_api::GetVisibleNetworks::Params> params =
247 private_api::GetVisibleNetworks::Params::Create(*args_);
248 EXTENSION_FUNCTION_VALIDATE(params);
249
250 std::string network_type = private_api::ToString(params->network_type);
251 const bool configured_only = false;
252 const bool visible_only = true;
253
254 GetDelegate(browser_context())->GetNetworks(
255 network_type,
256 configured_only,
257 visible_only,
258 kDefaultNetworkListLimit,
259 base::Bind(&NetworkingPrivateGetVisibleNetworksFunction::Success, this),
260 base::Bind(&NetworkingPrivateGetVisibleNetworksFunction::Failure, this));
261 return true;
262 }
263
264 void NetworkingPrivateGetVisibleNetworksFunction::Success(
265 scoped_ptr<base::ListValue> network_properties_list) {
266 SetResult(network_properties_list.release());
267 SendResponse(true);
268 }
269
270 void NetworkingPrivateGetVisibleNetworksFunction::Failure(
271 const std::string& error) {
272 error_ = error;
273 SendResponse(false);
274 }
275
276 ////////////////////////////////////////////////////////////////////////////////
277 // NetworkingPrivateGetEnabledNetworkTypesFunction
278
279 NetworkingPrivateGetEnabledNetworkTypesFunction::
280 ~NetworkingPrivateGetEnabledNetworkTypesFunction() {
281 }
282
283 bool NetworkingPrivateGetEnabledNetworkTypesFunction::RunSync() {
284 scoped_ptr<base::ListValue> enabled_networks_onc_types(
285 GetDelegate(browser_context())->GetEnabledNetworkTypes());
286 if (!enabled_networks_onc_types) {
287 error_ = networking_private::kErrorNotSupported;
288 return false;
289 }
290 scoped_ptr<base::ListValue> enabled_networks_list;
291 for (base::ListValue::iterator iter = enabled_networks_onc_types->begin();
292 iter != enabled_networks_onc_types->end(); ++iter) {
293 std::string type;
294 if (!(*iter)->GetAsString(&type))
295 NOTREACHED();
296 if (type == ::onc::network_type::kEthernet) {
297 enabled_networks_list->AppendString(api::networking_private::ToString(
298 api::networking_private::NETWORK_TYPE_ETHERNET));
299 } else if (type == ::onc::network_type::kWiFi) {
300 enabled_networks_list->AppendString(api::networking_private::ToString(
301 api::networking_private::NETWORK_TYPE_WIFI));
302 } else if (type == ::onc::network_type::kWimax) {
303 enabled_networks_list->AppendString(api::networking_private::ToString(
304 api::networking_private::NETWORK_TYPE_WIMAX));
305 } else if (type == ::onc::network_type::kCellular) {
306 enabled_networks_list->AppendString(api::networking_private::ToString(
307 api::networking_private::NETWORK_TYPE_CELLULAR));
308 } else {
309 LOG(ERROR) << "networkingPrivate: Unexpected type: " << type;
310 }
311 }
312 SetResult(enabled_networks_list.release());
313 return true;
314 }
315
316 ////////////////////////////////////////////////////////////////////////////////
317 // NetworkingPrivateEnableNetworkTypeFunction
318
319 NetworkingPrivateEnableNetworkTypeFunction::
320 ~NetworkingPrivateEnableNetworkTypeFunction() {
321 }
322
323 bool NetworkingPrivateEnableNetworkTypeFunction::RunSync() {
324 scoped_ptr<private_api::EnableNetworkType::Params> params =
325 private_api::EnableNetworkType::Params::Create(*args_);
326 EXTENSION_FUNCTION_VALIDATE(params);
327
328 return GetDelegate(browser_context())->EnableNetworkType(
329 private_api::ToString(params->network_type));
330 }
331
332 ////////////////////////////////////////////////////////////////////////////////
333 // NetworkingPrivateDisableNetworkTypeFunction
334
335 NetworkingPrivateDisableNetworkTypeFunction::
336 ~NetworkingPrivateDisableNetworkTypeFunction() {
337 }
338
339 bool NetworkingPrivateDisableNetworkTypeFunction::RunSync() {
340 scoped_ptr<private_api::DisableNetworkType::Params> params =
341 private_api::DisableNetworkType::Params::Create(*args_);
342
343 return GetDelegate(browser_context())->DisableNetworkType(
344 private_api::ToString(params->network_type));
345 }
346
347 ////////////////////////////////////////////////////////////////////////////////
348 // NetworkingPrivateRequestNetworkScanFunction
349
350 NetworkingPrivateRequestNetworkScanFunction::
351 ~NetworkingPrivateRequestNetworkScanFunction() {
352 }
353
354 bool NetworkingPrivateRequestNetworkScanFunction::RunSync() {
355 return GetDelegate(browser_context())->RequestScan();
356 }
357
358 ////////////////////////////////////////////////////////////////////////////////
359 // NetworkingPrivateStartConnectFunction
360
361 NetworkingPrivateStartConnectFunction::
362 ~NetworkingPrivateStartConnectFunction() {
363 }
364
365 bool NetworkingPrivateStartConnectFunction::RunAsync() {
366 scoped_ptr<private_api::StartConnect::Params> params =
367 private_api::StartConnect::Params::Create(*args_);
368 EXTENSION_FUNCTION_VALIDATE(params);
369
370 GetDelegate(browser_context())->StartConnect(
371 params->network_guid,
372 base::Bind(&NetworkingPrivateStartConnectFunction::Success, this),
373 base::Bind(&NetworkingPrivateStartConnectFunction::Failure, this));
374 return true;
375 }
376
377 void NetworkingPrivateStartConnectFunction::Success() {
378 SendResponse(true);
379 }
380
381 void NetworkingPrivateStartConnectFunction::Failure(const std::string& error) {
382 error_ = error;
383 SendResponse(false);
384 }
385
386 ////////////////////////////////////////////////////////////////////////////////
387 // NetworkingPrivateStartDisconnectFunction
388
389 NetworkingPrivateStartDisconnectFunction::
390 ~NetworkingPrivateStartDisconnectFunction() {
391 }
392
393 bool NetworkingPrivateStartDisconnectFunction::RunAsync() {
394 scoped_ptr<private_api::StartDisconnect::Params> params =
395 private_api::StartDisconnect::Params::Create(*args_);
396 EXTENSION_FUNCTION_VALIDATE(params);
397
398 GetDelegate(browser_context())->StartDisconnect(
399 params->network_guid,
400 base::Bind(&NetworkingPrivateStartDisconnectFunction::Success, this),
401 base::Bind(&NetworkingPrivateStartDisconnectFunction::Failure, this));
402 return true;
403 }
404
405 void NetworkingPrivateStartDisconnectFunction::Success() {
406 SendResponse(true);
407 }
408
409 void NetworkingPrivateStartDisconnectFunction::Failure(
410 const std::string& error) {
411 error_ = error;
412 SendResponse(false);
413 }
414
415 ////////////////////////////////////////////////////////////////////////////////
416 // NetworkingPrivateVerifyDestinationFunction
417
418 NetworkingPrivateVerifyDestinationFunction::
419 ~NetworkingPrivateVerifyDestinationFunction() {
420 }
421
422 bool NetworkingPrivateVerifyDestinationFunction::RunAsync() {
423 scoped_ptr<private_api::VerifyDestination::Params> params =
424 private_api::VerifyDestination::Params::Create(*args_);
425 EXTENSION_FUNCTION_VALIDATE(params);
426
427 GetDelegate(browser_context())->VerifyDestination(
428 params->properties,
429 base::Bind(&NetworkingPrivateVerifyDestinationFunction::Success, this),
430 base::Bind(&NetworkingPrivateVerifyDestinationFunction::Failure, this));
431 return true;
432 }
433
434 void NetworkingPrivateVerifyDestinationFunction::Success(bool result) {
435 results_ = private_api::VerifyDestination::Results::Create(result);
436 SendResponse(true);
437 }
438
439 void NetworkingPrivateVerifyDestinationFunction::Failure(
440 const std::string& error) {
441 error_ = error;
442 SendResponse(false);
443 }
444
445 ////////////////////////////////////////////////////////////////////////////////
446 // NetworkingPrivateVerifyAndEncryptCredentialsFunction
447
448 NetworkingPrivateVerifyAndEncryptCredentialsFunction::
449 ~NetworkingPrivateVerifyAndEncryptCredentialsFunction() {
450 }
451
452 bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunAsync() {
453 scoped_ptr<private_api::VerifyAndEncryptCredentials::Params> params =
454 private_api::VerifyAndEncryptCredentials::Params::Create(*args_);
455 EXTENSION_FUNCTION_VALIDATE(params);
456
457 GetDelegate(browser_context())->VerifyAndEncryptCredentials(
458 params->network_guid,
459 params->properties,
460 base::Bind(&NetworkingPrivateVerifyAndEncryptCredentialsFunction::Success,
461 this),
462 base::Bind(&NetworkingPrivateVerifyAndEncryptCredentialsFunction::Failure,
463 this));
464 return true;
465 }
466
467 void NetworkingPrivateVerifyAndEncryptCredentialsFunction::Success(
468 const std::string& result) {
469 results_ = private_api::VerifyAndEncryptCredentials::Results::Create(result);
470 SendResponse(true);
471 }
472
473 void NetworkingPrivateVerifyAndEncryptCredentialsFunction::Failure(
474 const std::string& error) {
475 error_ = error;
476 SendResponse(false);
477 }
478
479 ////////////////////////////////////////////////////////////////////////////////
480 // NetworkingPrivateVerifyAndEncryptDataFunction
481
482 NetworkingPrivateVerifyAndEncryptDataFunction::
483 ~NetworkingPrivateVerifyAndEncryptDataFunction() {
484 }
485
486 bool NetworkingPrivateVerifyAndEncryptDataFunction::RunAsync() {
487 scoped_ptr<private_api::VerifyAndEncryptData::Params> params =
488 private_api::VerifyAndEncryptData::Params::Create(*args_);
489 EXTENSION_FUNCTION_VALIDATE(params);
490
491 GetDelegate(browser_context())->VerifyAndEncryptData(
492 params->properties,
493 params->data,
494 base::Bind(&NetworkingPrivateVerifyAndEncryptDataFunction::Success, this),
495 base::Bind(&NetworkingPrivateVerifyAndEncryptDataFunction::Failure,
496 this));
497 return true;
498 }
499
500 void NetworkingPrivateVerifyAndEncryptDataFunction::Success(
501 const std::string& result) {
502 results_ = private_api::VerifyAndEncryptData::Results::Create(result);
503 SendResponse(true);
504 }
505
506 void NetworkingPrivateVerifyAndEncryptDataFunction::Failure(
507 const std::string& error) {
508 error_ = error;
509 SendResponse(false);
510 }
511
512 ////////////////////////////////////////////////////////////////////////////////
513 // NetworkingPrivateSetWifiTDLSEnabledStateFunction
514
515 NetworkingPrivateSetWifiTDLSEnabledStateFunction::
516 ~NetworkingPrivateSetWifiTDLSEnabledStateFunction() {
517 }
518
519 bool NetworkingPrivateSetWifiTDLSEnabledStateFunction::RunAsync() {
520 scoped_ptr<private_api::SetWifiTDLSEnabledState::Params> params =
521 private_api::SetWifiTDLSEnabledState::Params::Create(*args_);
522 EXTENSION_FUNCTION_VALIDATE(params);
523
524 GetDelegate(browser_context())->SetWifiTDLSEnabledState(
525 params->ip_or_mac_address,
526 params->enabled,
527 base::Bind(&NetworkingPrivateSetWifiTDLSEnabledStateFunction::Success,
528 this),
529 base::Bind(&NetworkingPrivateSetWifiTDLSEnabledStateFunction::Failure,
530 this));
531
532 return true;
533 }
534
535 void NetworkingPrivateSetWifiTDLSEnabledStateFunction::Success(
536 const std::string& result) {
537 results_ = private_api::SetWifiTDLSEnabledState::Results::Create(result);
538 SendResponse(true);
539 }
540
541 void NetworkingPrivateSetWifiTDLSEnabledStateFunction::Failure(
542 const std::string& error) {
543 error_ = error;
544 SendResponse(false);
545 }
546
547 ////////////////////////////////////////////////////////////////////////////////
548 // NetworkingPrivateGetWifiTDLSStatusFunction
549
550 NetworkingPrivateGetWifiTDLSStatusFunction::
551 ~NetworkingPrivateGetWifiTDLSStatusFunction() {
552 }
553
554 bool NetworkingPrivateGetWifiTDLSStatusFunction::RunAsync() {
555 scoped_ptr<private_api::GetWifiTDLSStatus::Params> params =
556 private_api::GetWifiTDLSStatus::Params::Create(*args_);
557 EXTENSION_FUNCTION_VALIDATE(params);
558
559 GetDelegate(browser_context())->GetWifiTDLSStatus(
560 params->ip_or_mac_address,
561 base::Bind(&NetworkingPrivateGetWifiTDLSStatusFunction::Success, this),
562 base::Bind(&NetworkingPrivateGetWifiTDLSStatusFunction::Failure, this));
563
564 return true;
565 }
566
567 void NetworkingPrivateGetWifiTDLSStatusFunction::Success(
568 const std::string& result) {
569 results_ = private_api::GetWifiTDLSStatus::Results::Create(result);
570 SendResponse(true);
571 }
572
573 void NetworkingPrivateGetWifiTDLSStatusFunction::Failure(
574 const std::string& error) {
575 error_ = error;
576 SendResponse(false);
577 }
578
579 ////////////////////////////////////////////////////////////////////////////////
580 // NetworkingPrivateGetCaptivePortalStatusFunction
581
582 NetworkingPrivateGetCaptivePortalStatusFunction::
583 ~NetworkingPrivateGetCaptivePortalStatusFunction() {
584 }
585
586 bool NetworkingPrivateGetCaptivePortalStatusFunction::RunAsync() {
587 scoped_ptr<private_api::GetCaptivePortalStatus::Params> params =
588 private_api::GetCaptivePortalStatus::Params::Create(*args_);
589 EXTENSION_FUNCTION_VALIDATE(params);
590
591 GetDelegate(browser_context())->GetCaptivePortalStatus(
592 params->network_guid,
593 base::Bind(&NetworkingPrivateGetCaptivePortalStatusFunction::Success,
594 this),
595 base::Bind(&NetworkingPrivateGetCaptivePortalStatusFunction::Failure,
596 this));
597 return true;
598 }
599
600 void NetworkingPrivateGetCaptivePortalStatusFunction::Success(
601 const std::string& result) {
602 results_ = private_api::GetCaptivePortalStatus::Results::Create(
603 private_api::ParseCaptivePortalStatus(result));
604 SendResponse(true);
605 }
606
607 void NetworkingPrivateGetCaptivePortalStatusFunction::Failure(
608 const std::string& error) {
609 error_ = error;
610 SendResponse(false);
611 }
612
613 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698