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

Side by Side Diff: chrome/common/extensions/permissions/chrome_permission_message_provider.cc

Issue 980353003: Extensions: Switch to new permission message system, part I (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup;rebase Created 5 years, 9 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
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/permissions/chrome_permission_message_provide r.h" 5 #include "chrome/common/extensions/permissions/chrome_permission_message_provide r.h"
6 6
7 #include "base/memory/scoped_vector.h" 7 #include "base/memory/scoped_vector.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 kSuppressList.insert( 129 kSuppressList.insert(
130 {PermissionMessage::kHostsAll, PermissionMessage::kTabs}); 130 {PermissionMessage::kHostsAll, PermissionMessage::kTabs});
131 // Tabs already allows reading favicons. 131 // Tabs already allows reading favicons.
132 kSuppressList.insert({PermissionMessage::kTabs, PermissionMessage::kFavicon}); 132 kSuppressList.insert({PermissionMessage::kTabs, PermissionMessage::kFavicon});
133 // Tabs already allows reading the list of most frequently visited sites. 133 // Tabs already allows reading the list of most frequently visited sites.
134 kSuppressList.insert( 134 kSuppressList.insert(
135 {PermissionMessage::kTabs, PermissionMessage::kTopSites}); 135 {PermissionMessage::kTabs, PermissionMessage::kTopSites});
136 136
137 PermissionMsgSet host_msgs = 137 PermissionMsgSet host_msgs =
138 GetHostPermissionMessages(permissions, NULL, extension_type); 138 GetHostPermissionMessages(permissions, NULL, extension_type);
139 PermissionMsgSet api_msgs = GetAPIPermissionMessages(permissions, NULL); 139 PermissionMsgSet api_msgs =
140 GetAPIPermissionMessages(permissions, NULL, extension_type);
140 PermissionMsgSet manifest_permission_msgs = 141 PermissionMsgSet manifest_permission_msgs =
141 GetManifestPermissionMessages(permissions, NULL); 142 GetManifestPermissionMessages(permissions, NULL);
142 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end()); 143 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end());
143 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end()); 144 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end());
144 messages.insert(messages.end(), manifest_permission_msgs.begin(), 145 messages.insert(messages.end(), manifest_permission_msgs.begin(),
145 manifest_permission_msgs.end()); 146 manifest_permission_msgs.end());
146 147
147 for (std::multimap<PermissionMessage::ID, 148 for (std::multimap<PermissionMessage::ID,
148 PermissionMessage::ID>::const_iterator it = 149 PermissionMessage::ID>::const_iterator it =
149 kSuppressList.begin(); 150 kSuppressList.begin();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 183 }
183 } 184 }
184 185
185 return messages; 186 return messages;
186 } 187 }
187 188
188 std::vector<base::string16> ChromePermissionMessageProvider::GetWarningMessages( 189 std::vector<base::string16> ChromePermissionMessageProvider::GetWarningMessages(
189 const PermissionSet* permissions, 190 const PermissionSet* permissions,
190 Manifest::Type extension_type) const { 191 Manifest::Type extension_type) const {
191 std::vector<base::string16> message_strings; 192 std::vector<base::string16> message_strings;
192 PermissionMessages messages = 193 std::vector<base::string16> message_details_strings;
193 GetPermissionMessages(permissions, extension_type); 194 CoalesceWarningMessages(permissions,
194 195 extension_type,
195 // WARNING: When modifying a coalescing rule in this list, be sure to also 196 &message_strings,
196 // modify the corresponding rule in 197 &message_details_strings);
197 // ChromePermissionMessageProvider::GetCoalescedPermissionMessages().
198 // TODO(sashab): Deprecate this function, and remove this list.
199 for (PermissionMessages::const_iterator i = messages.begin();
200 i != messages.end(); ++i) {
201 int id = i->id();
202 // Access to users' devices should provide a single warning message
203 // specifying the transport method used; serial and/or Bluetooth.
204 if (id == PermissionMessage::kBluetooth ||
205 id == PermissionMessage::kSerial) {
206 if (ContainsMessages(messages,
207 PermissionMessage::kBluetooth,
208 PermissionMessage::kSerial)) {
209 if (id == PermissionMessage::kBluetooth) {
210 message_strings.push_back(l10n_util::GetStringUTF16(
211 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_SERIAL));
212 }
213 continue;
214 }
215 }
216 if (id == PermissionMessage::kAccessibilityFeaturesModify ||
217 id == PermissionMessage::kAccessibilityFeaturesRead) {
218 if (ContainsMessages(messages,
219 PermissionMessage::kAccessibilityFeaturesModify,
220 PermissionMessage::kAccessibilityFeaturesRead)) {
221 if (id == PermissionMessage::kAccessibilityFeaturesModify) {
222 message_strings.push_back(l10n_util::GetStringUTF16(
223 IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_READ_MODIFY));
224 }
225 continue;
226 }
227 }
228 if (id == PermissionMessage::kAudioCapture ||
229 id == PermissionMessage::kVideoCapture) {
230 if (ContainsMessages(messages,
231 PermissionMessage::kAudioCapture,
232 PermissionMessage::kVideoCapture)) {
233 if (id == PermissionMessage::kAudioCapture) {
234 message_strings.push_back(l10n_util::GetStringUTF16(
235 IDS_EXTENSION_PROMPT_WARNING_AUDIO_AND_VIDEO_CAPTURE));
236 }
237 continue;
238 }
239 }
240 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo ||
241 id == PermissionMessage::kMediaGalleriesAllGalleriesDelete ||
242 id == PermissionMessage::kMediaGalleriesAllGalleriesRead) {
243 if (ContainsMessages(
244 messages,
245 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
246 PermissionMessage::kMediaGalleriesAllGalleriesDelete,
247 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
248 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo) {
249 message_strings.push_back(l10n_util::GetStringUTF16(
250 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE_DELETE));
251 }
252 continue;
253 }
254 if (ContainsMessages(
255 messages,
256 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
257 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
258 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo) {
259 message_strings.push_back(l10n_util::GetStringUTF16(
260 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE));
261 }
262 continue;
263 }
264 if (ContainsMessages(
265 messages,
266 PermissionMessage::kMediaGalleriesAllGalleriesDelete,
267 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
268 if (id == PermissionMessage::kMediaGalleriesAllGalleriesDelete) {
269 message_strings.push_back(l10n_util::GetStringUTF16(
270 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_DELETE));
271 }
272 continue;
273 }
274 }
275 if (permissions->HasAPIPermission(APIPermission::kSessions) &&
276 id == PermissionMessage::kTabs) {
277 message_strings.push_back(l10n_util::GetStringUTF16(
278 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS));
279 continue;
280 }
281 if (permissions->HasAPIPermission(APIPermission::kSessions) &&
282 id == PermissionMessage::kBrowsingHistory) {
283 message_strings.push_back(l10n_util::GetStringUTF16(
284 IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_AND_SESSIONS));
285 continue;
286 }
287
288 message_strings.push_back(i->message());
289 }
290
291 return message_strings; 198 return message_strings;
292 } 199 }
293 200
294 std::vector<base::string16> 201 std::vector<base::string16>
295 ChromePermissionMessageProvider::GetWarningMessagesDetails( 202 ChromePermissionMessageProvider::GetWarningMessagesDetails(
296 const PermissionSet* permissions, 203 const PermissionSet* permissions,
297 Manifest::Type extension_type) const { 204 Manifest::Type extension_type) const {
298 std::vector<base::string16> message_strings; 205 std::vector<base::string16> message_strings;
299 PermissionMessages messages = 206 std::vector<base::string16> message_details_strings;
300 GetPermissionMessages(permissions, extension_type); 207 CoalesceWarningMessages(permissions,
Marc Treib 2015/03/09 14:08:02 Before, we'd coalesce the warnings, but not their
Yoyo Zhou 2015/03/11 01:33:23 Is there a test for this case?
Marc Treib 2015/03/11 13:08:52 Not yet. I'll pull this part out into a separate C
301 208 extension_type,
302 for (PermissionMessages::const_iterator i = messages.begin(); 209 &message_strings,
303 i != messages.end(); ++i) 210 &message_details_strings);
304 message_strings.push_back(i->details()); 211 return message_details_strings;
305
306 return message_strings;
307 } 212 }
308 213
309 bool ChromePermissionMessageProvider::IsPrivilegeIncrease( 214 bool ChromePermissionMessageProvider::IsPrivilegeIncrease(
310 const PermissionSet* old_permissions, 215 const PermissionSet* old_permissions,
311 const PermissionSet* new_permissions, 216 const PermissionSet* new_permissions,
312 Manifest::Type extension_type) const { 217 Manifest::Type extension_type) const {
313 // Things can't get worse than native code access. 218 // Things can't get worse than native code access.
314 if (old_permissions->HasEffectiveFullAccess()) 219 if (old_permissions->HasEffectiveFullAccess())
315 return false; 220 return false;
316 221
317 // Otherwise, it's a privilege increase if the new one has full access. 222 // Otherwise, it's a privilege increase if the new one has full access.
318 if (new_permissions->HasEffectiveFullAccess()) 223 if (new_permissions->HasEffectiveFullAccess())
319 return true; 224 return true;
320 225
321 if (IsHostPrivilegeIncrease(old_permissions, new_permissions, extension_type)) 226 if (IsHostPrivilegeIncrease(old_permissions, new_permissions, extension_type))
322 return true; 227 return true;
323 228
324 if (IsAPIPrivilegeIncrease(old_permissions, new_permissions)) 229 if (IsAPIPrivilegeIncrease(old_permissions, new_permissions, extension_type))
325 return true; 230 return true;
326 231
327 if (IsManifestPermissionPrivilegeIncrease(old_permissions, new_permissions)) 232 if (IsManifestPermissionPrivilegeIncrease(old_permissions, new_permissions))
328 return true; 233 return true;
329 234
330 return false; 235 return false;
331 } 236 }
332 237
333 PermissionIDSet ChromePermissionMessageProvider::GetAllPermissionIDs( 238 PermissionIDSet ChromePermissionMessageProvider::GetAllPermissionIDs(
334 const PermissionSet* permissions, 239 const PermissionSet* permissions,
335 Manifest::Type extension_type) const { 240 Manifest::Type extension_type) const {
336 PermissionIDSet permission_ids; 241 PermissionIDSet permission_ids;
337 GetAPIPermissionMessages(permissions, &permission_ids); 242 GetAPIPermissionMessages(permissions, &permission_ids, extension_type);
338 GetManifestPermissionMessages(permissions, &permission_ids); 243 GetManifestPermissionMessages(permissions, &permission_ids);
339 GetHostPermissionMessages(permissions, &permission_ids, extension_type); 244 GetHostPermissionMessages(permissions, &permission_ids, extension_type);
340 return permission_ids; 245 return permission_ids;
341 } 246 }
342 247
343 std::set<PermissionMessage> 248 std::set<PermissionMessage>
344 ChromePermissionMessageProvider::GetAPIPermissionMessages( 249 ChromePermissionMessageProvider::GetAPIPermissionMessages(
345 const PermissionSet* permissions, 250 const PermissionSet* permissions,
346 PermissionIDSet* permission_ids) const { 251 PermissionIDSet* permission_ids,
252 Manifest::Type extension_type) const {
347 PermissionMsgSet messages; 253 PermissionMsgSet messages;
348 for (APIPermissionSet::const_iterator permission_it = 254 for (APIPermissionSet::const_iterator permission_it =
349 permissions->apis().begin(); 255 permissions->apis().begin();
350 permission_it != permissions->apis().end(); ++permission_it) { 256 permission_it != permissions->apis().end(); ++permission_it) {
351 if (permission_ids != NULL) 257 if (permission_ids != NULL)
352 permission_ids->InsertAll(permission_it->GetPermissions()); 258 permission_ids->InsertAll(permission_it->GetPermissions());
353 if (permission_it->HasMessages()) { 259 if (permission_it->HasMessages()) {
354 PermissionMessages new_messages = permission_it->GetMessages(); 260 PermissionMessages new_messages = permission_it->GetMessages();
355 messages.insert(new_messages.begin(), new_messages.end()); 261 messages.insert(new_messages.begin(), new_messages.end());
356 } 262 }
357 } 263 }
358 264
359 // A special hack: The warning message for declarativeWebRequest 265 // A special hack: The warning message for declarativeWebRequest
360 // permissions speaks about blocking parts of pages, which is a 266 // permissions speaks about blocking parts of pages, which is a
361 // subset of what the "<all_urls>" access allows. Therefore we 267 // subset of what the "<all_urls>" access allows. Therefore we
362 // display only the "<all_urls>" warning message if both permissions 268 // display only the "<all_urls>" warning message if both permissions
363 // are required. 269 // are required.
364 if (permissions->ShouldWarnAllHosts()) { 270 if (permissions->ShouldWarnAllHosts()) {
365 if (permission_ids != NULL) 271 // Platform apps don't show hosts warnings. See crbug.com/255229.
272 if (permission_ids != NULL && extension_type != Manifest::TYPE_PLATFORM_APP)
Marc Treib 2015/03/09 14:08:02 Platform apps never show the "all urls" warning in
366 permission_ids->insert(APIPermission::kHostsAll); 273 permission_ids->insert(APIPermission::kHostsAll);
367 messages.erase( 274 messages.erase(
368 PermissionMessage( 275 PermissionMessage(
369 PermissionMessage::kDeclarativeWebRequest, base::string16())); 276 PermissionMessage::kDeclarativeWebRequest, base::string16()));
370 } 277 }
371 return messages; 278 return messages;
372 } 279 }
373 280
374 std::set<PermissionMessage> 281 std::set<PermissionMessage>
375 ChromePermissionMessageProvider::GetManifestPermissionMessages( 282 ChromePermissionMessageProvider::GetManifestPermissionMessages(
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 permission_message_util::AddHostPermissions( 332 permission_message_util::AddHostPermissions(
426 permission_ids, hosts, permission_message_util::kReadWrite); 333 permission_ids, hosts, permission_message_util::kReadWrite);
427 } 334 }
428 messages.insert(permission_message_util::CreateFromHostList( 335 messages.insert(permission_message_util::CreateFromHostList(
429 hosts, permission_message_util::kReadWrite)); 336 hosts, permission_message_util::kReadWrite));
430 } 337 }
431 } 338 }
432 return messages; 339 return messages;
433 } 340 }
434 341
342 void ChromePermissionMessageProvider::CoalesceWarningMessages(
343 const PermissionSet* permissions,
344 Manifest::Type extension_type,
345 std::vector<base::string16>* message_strings,
346 std::vector<base::string16>* message_details_strings) const {
347 PermissionMessages messages =
348 GetPermissionMessages(permissions, extension_type);
349
350 // WARNING: When modifying a coalescing rule in this list, be sure to also
351 // modify the corresponding rule in
352 // ChromePermissionMessageProvider::GetCoalescedPermissionMessages().
353 // TODO(sashab): Deprecate this function, and remove this list.
354 for (PermissionMessages::const_iterator i = messages.begin();
355 i != messages.end(); ++i) {
356 int id = i->id();
357 // Access to users' devices should provide a single warning message
358 // specifying the transport method used; serial and/or Bluetooth.
359 if (id == PermissionMessage::kBluetooth ||
360 id == PermissionMessage::kSerial) {
361 if (ContainsMessages(messages,
362 PermissionMessage::kBluetooth,
363 PermissionMessage::kSerial)) {
364 if (id == PermissionMessage::kBluetooth) {
365 message_strings->push_back(l10n_util::GetStringUTF16(
366 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_SERIAL));
367 message_details_strings->push_back(base::string16());
368 }
369 continue;
370 }
371 }
372 if (id == PermissionMessage::kAccessibilityFeaturesModify ||
373 id == PermissionMessage::kAccessibilityFeaturesRead) {
374 if (ContainsMessages(messages,
375 PermissionMessage::kAccessibilityFeaturesModify,
376 PermissionMessage::kAccessibilityFeaturesRead)) {
377 if (id == PermissionMessage::kAccessibilityFeaturesModify) {
378 message_strings->push_back(l10n_util::GetStringUTF16(
379 IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_READ_MODIFY));
380 message_details_strings->push_back(base::string16());
381 }
382 continue;
383 }
384 }
385 if (id == PermissionMessage::kAudioCapture ||
386 id == PermissionMessage::kVideoCapture) {
387 if (ContainsMessages(messages,
388 PermissionMessage::kAudioCapture,
389 PermissionMessage::kVideoCapture)) {
390 if (id == PermissionMessage::kAudioCapture) {
391 message_strings->push_back(l10n_util::GetStringUTF16(
392 IDS_EXTENSION_PROMPT_WARNING_AUDIO_AND_VIDEO_CAPTURE));
393 message_details_strings->push_back(base::string16());
394 }
395 continue;
396 }
397 }
398 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo ||
399 id == PermissionMessage::kMediaGalleriesAllGalleriesDelete ||
400 id == PermissionMessage::kMediaGalleriesAllGalleriesRead) {
401 if (ContainsMessages(
402 messages,
403 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
404 PermissionMessage::kMediaGalleriesAllGalleriesDelete,
405 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
406 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo) {
407 message_strings->push_back(l10n_util::GetStringUTF16(
408 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE_DELETE));
409 message_details_strings->push_back(base::string16());
410 }
411 continue;
412 }
413 if (ContainsMessages(
414 messages,
415 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo,
416 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
417 if (id == PermissionMessage::kMediaGalleriesAllGalleriesCopyTo) {
418 message_strings->push_back(l10n_util::GetStringUTF16(
419 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE));
420 message_details_strings->push_back(base::string16());
421 }
422 continue;
423 }
424 if (ContainsMessages(
425 messages,
426 PermissionMessage::kMediaGalleriesAllGalleriesDelete,
427 PermissionMessage::kMediaGalleriesAllGalleriesRead)) {
428 if (id == PermissionMessage::kMediaGalleriesAllGalleriesDelete) {
429 message_strings->push_back(l10n_util::GetStringUTF16(
430 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_DELETE));
431 message_details_strings->push_back(base::string16());
432 }
433 continue;
434 }
435 }
436 if (permissions->HasAPIPermission(APIPermission::kSessions) &&
437 id == PermissionMessage::kTabs) {
438 message_strings->push_back(l10n_util::GetStringUTF16(
439 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS));
440 message_details_strings->push_back(base::string16());
441 continue;
442 }
443 if (permissions->HasAPIPermission(APIPermission::kSessions) &&
444 id == PermissionMessage::kBrowsingHistory) {
445 message_strings->push_back(l10n_util::GetStringUTF16(
446 IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_AND_SESSIONS));
447 message_details_strings->push_back(base::string16());
448 continue;
449 }
450
451 message_strings->push_back(i->message());
452 message_details_strings->push_back(i->details());
453 }
454 }
455
435 bool ChromePermissionMessageProvider::IsAPIPrivilegeIncrease( 456 bool ChromePermissionMessageProvider::IsAPIPrivilegeIncrease(
436 const PermissionSet* old_permissions, 457 const PermissionSet* old_permissions,
437 const PermissionSet* new_permissions) const { 458 const PermissionSet* new_permissions,
459 Manifest::Type extension_type) const {
438 if (new_permissions == NULL) 460 if (new_permissions == NULL)
439 return false; 461 return false;
440 462
441 PermissionMsgSet old_warnings = 463 PermissionMsgSet old_warnings =
442 GetAPIPermissionMessages(old_permissions, NULL); 464 GetAPIPermissionMessages(old_permissions, NULL, extension_type);
443 PermissionMsgSet new_warnings = 465 PermissionMsgSet new_warnings =
444 GetAPIPermissionMessages(new_permissions, NULL); 466 GetAPIPermissionMessages(new_permissions, NULL, extension_type);
445 PermissionMsgSet delta_warnings = 467 PermissionMsgSet delta_warnings =
446 base::STLSetDifference<PermissionMsgSet>(new_warnings, old_warnings); 468 base::STLSetDifference<PermissionMsgSet>(new_warnings, old_warnings);
447 469
448 // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory. 470 // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory.
449 // TODO(sammc): Remove this. See http://crbug.com/284849. 471 // TODO(sammc): Remove this. See http://crbug.com/284849.
450 if (old_warnings.find(PermissionMessage( 472 if (old_warnings.find(PermissionMessage(
451 PermissionMessage::kFileSystemWriteDirectory, base::string16())) != 473 PermissionMessage::kFileSystemWriteDirectory, base::string16())) !=
452 old_warnings.end()) { 474 old_warnings.end()) {
453 delta_warnings.erase( 475 delta_warnings.erase(
454 PermissionMessage(PermissionMessage::kFileSystemDirectory, 476 PermissionMessage(PermissionMessage::kFileSystemDirectory,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 std::set<std::string> old_hosts_set( 527 std::set<std::string> old_hosts_set(
506 permission_message_util::GetDistinctHosts(old_list, false, false)); 528 permission_message_util::GetDistinctHosts(old_list, false, false));
507 std::set<std::string> new_hosts_only = 529 std::set<std::string> new_hosts_only =
508 base::STLSetDifference<std::set<std::string> >(new_hosts_set, 530 base::STLSetDifference<std::set<std::string> >(new_hosts_set,
509 old_hosts_set); 531 old_hosts_set);
510 532
511 return !new_hosts_only.empty(); 533 return !new_hosts_only.empty();
512 } 534 }
513 535
514 } // namespace extensions 536 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698