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

Side by Side Diff: chrome/common/extensions/api/sockets/sockets_handler.cc

Issue 51433002: Enable permission warnings from ManifestHandlers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing. Created 7 years, 1 month 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "chrome/common/extensions/api/sockets/sockets_handler.h" 5 #include "chrome/common/extensions/api/sockets/sockets_handler.h"
6 6
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "chrome/common/extensions/api/manifest_types.h" 10 #include "chrome/common/extensions/api/manifest_types.h"
11 #include "chrome/common/extensions/extension.h" 11 #include "chrome/common/extensions/extension.h"
12 #include "chrome/common/extensions/extension_messages.h"
12 #include "chrome/common/extensions/permissions/permissions_data.h" 13 #include "chrome/common/extensions/permissions/permissions_data.h"
13 #include "chrome/common/extensions/permissions/socket_permission_data.h" 14 #include "chrome/common/extensions/permissions/socket_permission_data.h"
14 #include "extensions/common/error_utils.h" 15 #include "extensions/common/error_utils.h"
15 #include "extensions/common/manifest_constants.h" 16 #include "extensions/common/manifest_constants.h"
16 #include "extensions/common/permissions/api_permission_set.h" 17 #include "extensions/common/permissions/api_permission_set.h"
18 #include "grit/generated_resources.h"
19 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_message_utils.h"
21 #include "ui/base/l10n/l10n_util.h"
17 22
18 namespace extensions { 23 namespace extensions {
19 24
20 namespace sockets_errors { 25 namespace sockets_errors {
21 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'"; 26 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'";
22 } 27 }
23 28
24 namespace keys = extensions::manifest_keys; 29 namespace keys = extensions::manifest_keys;
25 namespace errors = sockets_errors; 30 namespace errors = sockets_errors;
26 using api::manifest_types::Sockets; 31 using api::manifest_types::Sockets;
32 using content::SocketPermissionRequest;
33
34 // TODO(rpaquay): Unit test for all this class (Diff, Union, etc).
35 class SocketsManifestPermission : public ManifestPermission {
Yoyo Zhou 2013/11/09 01:15:30 Do you anticipate something like SetDisjunctionPer
rpaquay 2013/11/11 18:37:35 I would say probably at some point. I don't know o
Yoyo Zhou 2013/11/12 02:39:29 Okay.
36 public:
37 SocketsManifestPermission() {
38 }
39
40 explicit SocketsManifestPermission(scoped_ptr<SocketsManifestData> data)
41 : data_(data.Pass()) {
42 }
43
44 virtual std::string name() const OVERRIDE {
45 return keys::kSockets;
46 }
47
48 virtual std::string id() const OVERRIDE {
49 return name();
50 }
51
52 // Returns true if this permission has any PermissionMessages.
53 virtual bool HasMessages() const OVERRIDE {
54 if (!data_)
55 return false;
56
57 return data_->HasMessages();
58 }
59
60 // Returns the localized permission messages of this permission.
61 virtual PermissionMessages GetMessages() const OVERRIDE {
62 if (!data_)
63 return PermissionMessages();
64 return data_->GetPermissionMessages();
65 }
66
67 // Parses the ManifestPermission from |value|. Returns false if error happens.
68 virtual bool FromValue(const base::Value* value) OVERRIDE {
69 // TODO(rpaquay): Null check?
70 if (!value)
71 return false;
72
73 std::vector<InstallWarning> warnings;
74 string16 error;
75 scoped_ptr<SocketsManifestData> data(
76 SocketsManifestData::FromValue(*value, &warnings, &error));
77
78 if (!data)
79 return false;
80
81 data_ = data.Pass();
82 return true;
83 }
84
85 // Stores this into a new created |value|.
86 virtual scoped_ptr<base::Value> ToValue() const OVERRIDE {
87 if (!data_) {
88 // TODO(rpaquay) : Is it ok to return NULL?
89 return scoped_ptr<base::Value>(base::Value::CreateNullValue());
90 }
91
92 Sockets sockets;
93 if (data_->is_udp()) {
94 sockets.udp.reset(new Sockets::Udp());
95 sockets.udp->bind = AddEntry(SocketPermissionRequest::UDP_BIND).Pass();
96 sockets.udp->send = AddEntry(SocketPermissionRequest::UDP_SEND_TO).Pass();
97 sockets.udp->multicast_membership =
98 AddEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP).Pass();
99 }
100 if (data_->is_tcp()) {
101 sockets.tcp.reset(new Sockets::Tcp());
102 sockets.tcp->connect = AddEntry(
103 SocketPermissionRequest::TCP_CONNECT).Pass();
104 }
105 if (data_->is_tcp_server()) {
106 sockets.tcp_server.reset(new Sockets::TcpServer());
107 sockets.tcp_server->listen = AddEntry(
108 SocketPermissionRequest::TCP_LISTEN).Pass();
109 }
110
111 return sockets.ToValue().Pass();
112 }
113
114 // Clones this.
115 virtual ManifestPermission* Clone() const OVERRIDE {
116 if (!data_)
117 return new SocketsManifestPermission();
118
119 scoped_ptr<SocketsManifestData> clone_data(data_->Clone());
120 return new SocketsManifestPermission(clone_data.Pass());
121 }
122
123 // Returns a new API permission which equals this - |rhs|.
124 virtual ManifestPermission* Diff(const ManifestPermission* rhs)
125 const OVERRIDE {
126 const SocketsManifestPermission* other =
127 static_cast<const SocketsManifestPermission*>(rhs);
128
129 if (!data_)
130 return new SocketsManifestPermission();
131
132 if (!other->data_)
133 return Clone();
134
135 scoped_ptr<SocketsManifestData> data(data_->Diff(other->data_.get()));
136 return new SocketsManifestPermission(data.Pass());
137 }
138
139 // Returns a new API permission which equals the union of this and |rhs|.
140 virtual ManifestPermission* Union(const ManifestPermission* rhs)
141 const OVERRIDE {
142 const SocketsManifestPermission* other =
143 static_cast<const SocketsManifestPermission*>(rhs);
144
145 if (!data_)
146 return other->Clone();
147
148 if (!other->data_)
149 return Clone();
150
151 scoped_ptr<SocketsManifestData> data(data_->Union(other->data_.get()));
152 return new SocketsManifestPermission(data.Pass());
153 }
154
155 // Returns a new API permission which equals the intersect of this and |rhs|.
156 virtual ManifestPermission* Intersect(const ManifestPermission* rhs)
157 const OVERRIDE {
158 const SocketsManifestPermission* other =
159 static_cast<const SocketsManifestPermission*>(rhs);
160
161 if (!data_)
162 return new SocketsManifestPermission();
163
164 if (!other->data_)
165 return new SocketsManifestPermission();
166
167 scoped_ptr<SocketsManifestData> data(data_->Intersect(other->data_.get()));
168 return new SocketsManifestPermission(data.Pass());
169 }
170
171 // Returns true if |rhs| is a subset of this.
172 virtual bool Contains(const ManifestPermission* rhs) const OVERRIDE {
173 const SocketsManifestPermission* other =
174 static_cast<const SocketsManifestPermission*>(rhs);
175
176 if (!data_)
177 return !other->data_;
178
179 if (!other->data_)
180 return true;
181
182 return data_->Contains(other->data_.get());
183 }
184
185 // Returns true if |rhs| is equal to this.
186 virtual bool Equal(const ManifestPermission* rhs) const OVERRIDE {
187 const SocketsManifestPermission* other =
188 static_cast<const SocketsManifestPermission*>(rhs);
189
190 if (!data_)
191 return !other->data_;
192
193 if (!other->data_)
194 return false;
195
196 return data_->Equal(other->data_.get());
197 }
198
199 // IPC functions
200 // Writes this into the given IPC message |m|.
201 virtual void Write(IPC::Message* m) const OVERRIDE {
202 bool has_data = !!data_;
203 IPC::WriteParam(m, has_data);
204 if (has_data) {
205 data_->Write(m);
206 }
207 }
208
209 // Reads from the given IPC message |m|.
210 virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE {
211 data_.reset();
212
213 bool has_data;
214 bool result = IPC::ReadParam(m, iter, &has_data);
215 if (!result)
216 return result;
217
218 if (!has_data)
219 return true;
220
221 data_.reset(new SocketsManifestData());
222 return data_->Read(m, iter);
223 }
224
225 // Logs this permission.
226 virtual void Log(std::string* log) const OVERRIDE {
227 if (data_)
228 data_->Log(log);
229 }
230
231 private:
232 scoped_ptr<std::string> AddEntry(
233 content::SocketPermissionRequest::OperationType operation_type) const {
234 scoped_ptr<std::string> result;
235 for (SocketsManifestData::SocketPermissionEntrySet::const_iterator it =
236 data_->entries().begin(); it != data_->entries().end() ; ++it) {
237 if (it->pattern().type == operation_type) {
238 result.reset(new std::string(it->GetHostPatternAsString()));
239 break;
240 }
241 }
242 return result.Pass();
243 }
244
245 scoped_ptr<SocketsManifestData> data_;
Yoyo Zhou 2013/11/09 01:15:30 This looks like unusual ownership. ManifestDatas a
rpaquay 2013/11/11 18:37:35 The "initial" value is a clone of the extension ma
Yoyo Zhou 2013/11/13 02:57:07 (SocketPermissionData already exists, but it seems
rpaquay 2013/11/13 21:28:55 This makes sense. Patchset #6 swaps ownership betw
246 };
27 247
28 SocketsHandler::SocketsHandler() {} 248 SocketsHandler::SocketsHandler() {}
29 249
30 SocketsHandler::~SocketsHandler() {} 250 SocketsHandler::~SocketsHandler() {}
31 251
32 bool SocketsHandler::Parse(Extension* extension, string16* error) { 252 bool SocketsHandler::Parse(Extension* extension, string16* error) {
33 const base::Value* sockets = NULL; 253 const base::Value* sockets = NULL;
34 CHECK(extension->manifest()->Get(keys::kSockets, &sockets)); 254 CHECK(extension->manifest()->Get(keys::kSockets, &sockets));
35 std::vector<InstallWarning> install_warnings; 255 std::vector<InstallWarning> install_warnings;
36 scoped_ptr<SocketsManifestData> data = 256 scoped_ptr<SocketsManifestData> data =
37 SocketsManifestData::FromValue(*sockets, 257 SocketsManifestData::FromValue(*sockets,
38 &install_warnings, 258 &install_warnings,
39 error); 259 error);
40 if (!data) 260 if (!data)
41 return false; 261 return false;
42 262
43 extension->AddInstallWarnings(install_warnings); 263 extension->AddInstallWarnings(install_warnings);
44 extension->SetManifestData(keys::kSockets, data.release()); 264 extension->SetManifestData(keys::kSockets, data.release());
45 return true; 265 return true;
46 } 266 }
47 267
268 ManifestPermission* SocketsHandler::CreatePermission() {
269 return new SocketsManifestPermission();
270 }
271
272 ManifestPermission* SocketsHandler::CreateInitialRequiredPermission(
273 const Extension* extension) {
274 SocketsManifestData* data = SocketsManifestData::Get(extension);
275 if (data) {
276 return new SocketsManifestPermission(
277 scoped_ptr<SocketsManifestData>(data->Clone()).Pass());
278 }
279 return new SocketsManifestPermission();
280 }
281
48 const std::vector<std::string> SocketsHandler::Keys() const { 282 const std::vector<std::string> SocketsHandler::Keys() const {
49 return SingleKey(manifest_keys::kSockets); 283 return SingleKey(manifest_keys::kSockets);
50 } 284 }
51 285
52 SocketsManifestData::SocketsManifestData() {} 286 SocketsManifestData::SocketsManifestData() : kinds_(kNone) {}
53 SocketsManifestData::~SocketsManifestData() {} 287 SocketsManifestData::~SocketsManifestData() {}
54 288
55 // static 289 // static
56 SocketsManifestData* SocketsManifestData::Get(const Extension* extension) { 290 SocketsManifestData* SocketsManifestData::Get(const Extension* extension) {
57 return static_cast<SocketsManifestData*>( 291 return static_cast<SocketsManifestData*>(
58 extension->GetManifestData(keys::kSockets)); 292 extension->GetManifestData(keys::kSockets));
59 } 293 }
60 294
61 // static 295 // static
62 bool SocketsManifestData::CheckRequest( 296 bool SocketsManifestData::CheckRequest(
63 const Extension* extension, 297 const Extension* extension,
64 const content::SocketPermissionRequest& request) { 298 const content::SocketPermissionRequest& request) {
65 SocketsManifestData* data = SocketsManifestData::Get(extension); 299 SocketsManifestData* data = SocketsManifestData::Get(extension);
66 if (data == NULL) 300 if (!data)
67 return false; 301 return false;
68 302
69 return data->CheckRequestImpl(extension, request); 303 return data->CheckRequestImpl(extension, request);
70 } 304 }
71 305
72 // static 306 // static
73 scoped_ptr<SocketsManifestData> SocketsManifestData::FromValue( 307 scoped_ptr<SocketsManifestData> SocketsManifestData::FromValue(
74 const base::Value& value, 308 const base::Value& value,
75 std::vector<InstallWarning>* install_warnings, 309 std::vector<InstallWarning>* install_warnings,
76 string16* error) { 310 string16* error) {
77 scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error); 311 scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error);
78 if (!sockets) 312 if (!sockets)
79 return scoped_ptr<SocketsManifestData>(); 313 return scoped_ptr<SocketsManifestData>();
80 314
81 scoped_ptr<SocketsManifestData> result(new SocketsManifestData()); 315 scoped_ptr<SocketsManifestData> result(new SocketsManifestData());
82 if (sockets->udp) { 316 if (sockets->udp) {
317 result->kinds_ |= kUdpPermission;
83 if (!ParseHostPattern(result.get(), 318 if (!ParseHostPattern(result.get(),
84 content::SocketPermissionRequest::UDP_BIND, 319 content::SocketPermissionRequest::UDP_BIND,
85 sockets->udp->bind, 320 sockets->udp->bind,
86 error)) { 321 error)) {
87 return scoped_ptr<SocketsManifestData>(); 322 return scoped_ptr<SocketsManifestData>();
88 } 323 }
89 if (!ParseHostPattern(result.get(), 324 if (!ParseHostPattern(result.get(),
90 content::SocketPermissionRequest::UDP_SEND_TO, 325 content::SocketPermissionRequest::UDP_SEND_TO,
91 sockets->udp->send, 326 sockets->udp->send,
92 error)) { 327 error)) {
93 return scoped_ptr<SocketsManifestData>(); 328 return scoped_ptr<SocketsManifestData>();
94 } 329 }
95 if (!ParseHostPattern(result.get(), 330 if (!ParseHostPattern(result.get(),
96 content::SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, 331 content::SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
97 sockets->udp->multicast_membership, 332 sockets->udp->multicast_membership,
98 error)) { 333 error)) {
99 return scoped_ptr<SocketsManifestData>(); 334 return scoped_ptr<SocketsManifestData>();
100 } 335 }
101 } 336 }
102 if (sockets->tcp) { 337 if (sockets->tcp) {
338 result->kinds_ |= kTcpPermission;
103 if (!ParseHostPattern(result.get(), 339 if (!ParseHostPattern(result.get(),
104 content::SocketPermissionRequest::TCP_CONNECT, 340 content::SocketPermissionRequest::TCP_CONNECT,
105 sockets->tcp->connect, 341 sockets->tcp->connect,
106 error)) { 342 error)) {
107 return scoped_ptr<SocketsManifestData>(); 343 return scoped_ptr<SocketsManifestData>();
108 } 344 }
109 } 345 }
110 if (sockets->tcp_server) { 346 if (sockets->tcp_server) {
347 result->kinds_ |= kTcpServerPermission;
111 if (!ParseHostPattern(result.get(), 348 if (!ParseHostPattern(result.get(),
112 content::SocketPermissionRequest::TCP_LISTEN, 349 content::SocketPermissionRequest::TCP_LISTEN,
113 sockets->tcp_server->listen, 350 sockets->tcp_server->listen,
114 error)) { 351 error)) {
115 return scoped_ptr<SocketsManifestData>(); 352 return scoped_ptr<SocketsManifestData>();
116 } 353 }
117 } 354 }
118 return result.Pass(); 355 return result.Pass();
119 } 356 }
120 357
(...skipping 16 matching lines...) Expand all
137 return true; 374 return true;
138 } 375 }
139 376
140 void SocketsManifestData::AddPermission(const SocketPermissionEntry& entry) { 377 void SocketsManifestData::AddPermission(const SocketPermissionEntry& entry) {
141 permissions_.insert(entry); 378 permissions_.insert(entry);
142 } 379 }
143 380
144 bool SocketsManifestData::CheckRequestImpl( 381 bool SocketsManifestData::CheckRequestImpl(
145 const Extension* extension, 382 const Extension* extension,
146 const content::SocketPermissionRequest& request) { 383 const content::SocketPermissionRequest& request) {
147 for (PermissionSet::const_iterator it = permissions_.begin(); 384 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
148 it != permissions_.end(); ++it) { 385 it != permissions_.end(); ++it) {
149 if (it->Check(request)) 386 if (it->Check(request))
150 return true; 387 return true;
151 } 388 }
152 return false; 389 return false;
153 } 390 }
154 391
392 bool SocketsManifestData::HasMessages() const {
393 bool is_empty = permissions_.empty() && (kinds_ == kNone);
394 return !is_empty;
395 }
396
397 PermissionMessages SocketsManifestData::GetPermissionMessages() const {
398 // TODO(rpaquay): This function and callees is (almost) a copy/paste
399 // from |extensions::SocketPermission|.
400 PermissionMessages result;
401 if (!AddAnyHostMessage(result)) {
402 AddSpecificHostMessage(result);
403 AddSubdomainHostMessage(result);
404 }
405 AddNetworkListMessage(result);
406 return result;
407 }
408
409 SocketsManifestData* SocketsManifestData::Diff(const SocketsManifestData* rhs)
410 const {
411 scoped_ptr<SocketsManifestData> data(new SocketsManifestData());
412 std::set_difference(
413 permissions_.begin(), permissions_.end(),
414 rhs->permissions_.begin(), rhs->permissions_.end(),
415 std::inserter<SocketPermissionEntrySet>(
416 data->permissions_, data->permissions_.begin()));
417
418 data->kinds_ = (kinds_ & (~rhs->kinds_));
419 return data.release();
420 }
421
422 SocketsManifestData* SocketsManifestData::Union(const SocketsManifestData* rhs)
423 const {
424 scoped_ptr<SocketsManifestData> data(new SocketsManifestData());
425 std::set_union(
426 permissions_.begin(), permissions_.end(),
427 rhs->permissions_.begin(), rhs->permissions_.end(),
428 std::inserter<SocketPermissionEntrySet>(
429 data->permissions_, data->permissions_.begin()));
430
431 data->kinds_ = (kinds_ | rhs->kinds_);
432 return data.release();
433 }
434
435 SocketsManifestData* SocketsManifestData::Intersect(
436 const SocketsManifestData* rhs) const {
437 scoped_ptr<SocketsManifestData> data(new SocketsManifestData());
438 std::set_intersection(
439 permissions_.begin(), permissions_.end(),
440 rhs->permissions_.begin(), rhs->permissions_.end(),
441 std::inserter<SocketPermissionEntrySet>(
442 data->permissions_, data->permissions_.begin()));
443
444 data->kinds_ = (kinds_ & rhs->kinds_);
445 return data.release();
446 }
447
448 bool SocketsManifestData::Contains(const SocketsManifestData* rhs) const {
449 return std::includes(
450 entries().begin(), entries().end(),
451 rhs->entries().begin(), rhs->entries().end()) &&
452 ((kinds_ | rhs->kinds_) == kinds_);
453 }
454
455 bool SocketsManifestData::Equal(const SocketsManifestData* rhs) const {
456 return (permissions_ == rhs->permissions_) &&
457 (kinds_ == rhs->kinds_);
458 }
459
460 SocketsManifestData* SocketsManifestData::Clone() const {
461 scoped_ptr<SocketsManifestData> result(new SocketsManifestData());
462 result->permissions_ = permissions_;
463 result->kinds_ = kinds_;
464 return result.release();
465 }
466
467 void SocketsManifestData::Write(IPC::Message* m) const {
468 IPC::WriteParam(m, permissions_);
469 IPC::WriteParam(m, kinds_);
470 }
471
472 bool SocketsManifestData::Read(const IPC::Message* m, PickleIterator* iter) {
473 return IPC::ReadParam(m, iter, &permissions_) &&
474 IPC::ReadParam(m, iter, &kinds_);
475 }
476
477 void SocketsManifestData::Log(std::string* log) const {
478 IPC::LogParam(permissions_, log);
479 IPC::LogParam(kinds_, log);
480 }
481
482 bool SocketsManifestData::AddAnyHostMessage(
483 PermissionMessages& messages) const {
484 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
485 it != permissions_.end(); ++it) {
486 if (it->IsAddressBoundType() &&
487 it->GetHostType() == SocketPermissionEntry::ANY_HOST) {
488 messages.push_back(PermissionMessage(
489 PermissionMessage::kSocketAnyHost,
490 l10n_util::GetStringUTF16(
491 IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST)));
492 return true;
493 }
494 }
495 return false;
496 }
497
498 void SocketsManifestData::AddSubdomainHostMessage(
499 PermissionMessages& messages) const {
500 std::set<string16> domains;
501 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
502 it != permissions_.end(); ++it) {
503 if (it->GetHostType() == SocketPermissionEntry::HOSTS_IN_DOMAINS)
504 domains.insert(UTF8ToUTF16(it->pattern().host));
505 }
506 if (!domains.empty()) {
507 int id = (domains.size() == 1) ?
508 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN :
509 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS;
510 messages.push_back(PermissionMessage(
511 PermissionMessage::kSocketDomainHosts,
512 l10n_util::GetStringFUTF16(
513 id,
514 JoinString(
515 std::vector<string16>(
516 domains.begin(), domains.end()), ' '))));
517 }
518 }
519
520 void SocketsManifestData::AddSpecificHostMessage(
521 PermissionMessages& messages) const {
522 std::set<string16> hostnames;
523 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
524 it != permissions_.end(); ++it) {
525 if (it->GetHostType() == SocketPermissionEntry::SPECIFIC_HOSTS)
526 hostnames.insert(UTF8ToUTF16(it->pattern().host));
527 }
528 if (!hostnames.empty()) {
529 int id = (hostnames.size() == 1) ?
530 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST :
531 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS;
532 messages.push_back(PermissionMessage(
533 PermissionMessage::kSocketSpecificHosts,
534 l10n_util::GetStringFUTF16(
535 id,
536 JoinString(
537 std::vector<string16>(
538 hostnames.begin(), hostnames.end()), ' '))));
539 }
540 }
541
542 void SocketsManifestData::AddNetworkListMessage(
543 PermissionMessages& messages) const {
544 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
545 it != permissions_.end(); ++it) {
546 if (it->pattern().type == content::SocketPermissionRequest::NETWORK_STATE) {
547 messages.push_back(PermissionMessage(
548 PermissionMessage::kNetworkState,
549 l10n_util::GetStringUTF16(
550 IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE)));
551 }
552 }
553 }
554
155 } // namespace extensions 555 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698