| Index: chrome/browser/extensions/api/content_settings/content_settings_store.cc
|
| diff --git a/chrome/browser/extensions/api/content_settings/content_settings_store.cc b/chrome/browser/extensions/api/content_settings/content_settings_store.cc
|
| index 3df22217d4eda7481216e34241e2ca84cd04c33c..a3d28d9d303123fb2ae90ed501edb06391cb211a 100644
|
| --- a/chrome/browser/extensions/api/content_settings/content_settings_store.cc
|
| +++ b/chrome/browser/extensions/api/content_settings/content_settings_store.cc
|
| @@ -4,15 +4,14 @@
|
|
|
| #include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
|
|
|
| +#include <algorithm>
|
| #include <memory>
|
| #include <set>
|
| #include <utility>
|
| -#include <vector>
|
|
|
| #include "base/debug/alias.h"
|
| #include "base/logging.h"
|
| #include "base/memory/ptr_util.h"
|
| -#include "base/stl_util.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/values.h"
|
| #include "chrome/browser/extensions/api/content_settings/content_settings_api_constants.h"
|
| @@ -36,8 +35,10 @@ namespace helpers = content_settings_helpers;
|
| namespace keys = content_settings_api_constants;
|
|
|
| struct ContentSettingsStore::ExtensionEntry {
|
| - // Extension id
|
| + // Extension id.
|
| std::string id;
|
| + // Installation time.
|
| + base::Time install_time;
|
| // Whether extension is enabled in the profile.
|
| bool enabled;
|
| // Content settings.
|
| @@ -53,7 +54,6 @@ ContentSettingsStore::ContentSettingsStore() {
|
| }
|
|
|
| ContentSettingsStore::~ContentSettingsStore() {
|
| - base::STLDeleteValues(&entries_);
|
| }
|
|
|
| std::unique_ptr<RuleIterator> ContentSettingsStore::GetRuleIterator(
|
| @@ -61,16 +61,14 @@ std::unique_ptr<RuleIterator> ContentSettingsStore::GetRuleIterator(
|
| const content_settings::ResourceIdentifier& identifier,
|
| bool incognito) const {
|
| std::vector<std::unique_ptr<RuleIterator>> iterators;
|
| - // Iterate the extensions based on install time (last installed extensions
|
| - // first).
|
| - ExtensionEntryMap::const_reverse_iterator entry_it;
|
|
|
| // The individual |RuleIterators| shouldn't lock; pass |lock_| to the
|
| // |ConcatenationIterator| in a locked state.
|
| std::unique_ptr<base::AutoLock> auto_lock(new base::AutoLock(lock_));
|
|
|
| - for (entry_it = entries_.rbegin(); entry_it != entries_.rend(); ++entry_it) {
|
| - auto* entry = entry_it->second;
|
| + // Iterate the extensions based on install time (most-recently installed
|
| + // items first).
|
| + for (const auto& entry : entries_) {
|
| if (!entry->enabled)
|
| continue;
|
|
|
| @@ -128,13 +126,23 @@ void ContentSettingsStore::RegisterExtension(
|
| const base::Time& install_time,
|
| bool is_enabled) {
|
| base::AutoLock lock(lock_);
|
| - ExtensionEntryMap::iterator i = FindEntry(ext_id);
|
| - ExtensionEntry* entry;
|
| + auto i = FindIterator(ext_id);
|
| + ExtensionEntry* entry = nullptr;
|
| if (i != entries_.end()) {
|
| - entry = i->second;
|
| + entry = i->get();
|
| } else {
|
| entry = new ExtensionEntry;
|
| - entries_.insert(std::make_pair(install_time, entry));
|
| + entry->install_time = install_time;
|
| +
|
| + // Insert in reverse-chronological order to maintain the invariant.
|
| + auto unique_entry = base::WrapUnique(entry);
|
| + auto location =
|
| + std::upper_bound(entries_.begin(), entries_.end(), unique_entry,
|
| + [](const std::unique_ptr<ExtensionEntry>& a,
|
| + const std::unique_ptr<ExtensionEntry>& b) {
|
| + return a->install_time > b->install_time;
|
| + });
|
| + entries_.insert(location, std::move(unique_entry));
|
| }
|
|
|
| entry->id = ext_id;
|
| @@ -147,14 +155,13 @@ void ContentSettingsStore::UnregisterExtension(
|
| bool notify_incognito = false;
|
| {
|
| base::AutoLock lock(lock_);
|
| - ExtensionEntryMap::iterator i = FindEntry(ext_id);
|
| + auto i = FindIterator(ext_id);
|
| if (i == entries_.end())
|
| return;
|
| - notify = !i->second->settings.empty();
|
| - notify_incognito = !i->second->incognito_persistent_settings.empty() ||
|
| - !i->second->incognito_session_only_settings.empty();
|
| + notify = !(*i)->settings.empty();
|
| + notify_incognito = !(*i)->incognito_persistent_settings.empty() ||
|
| + !(*i)->incognito_session_only_settings.empty();
|
|
|
| - delete i->second;
|
| entries_.erase(i);
|
| }
|
| if (notify)
|
| @@ -169,14 +176,15 @@ void ContentSettingsStore::SetExtensionState(
|
| bool notify_incognito = false;
|
| {
|
| base::AutoLock lock(lock_);
|
| - ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
|
| - if (i == entries_.end())
|
| + ExtensionEntry* entry = FindEntry(ext_id);
|
| + if (!entry)
|
| return;
|
| - notify = !i->second->settings.empty();
|
| - notify_incognito = !i->second->incognito_persistent_settings.empty() ||
|
| - !i->second->incognito_session_only_settings.empty();
|
|
|
| - i->second->enabled = is_enabled;
|
| + notify = !entry->settings.empty();
|
| + notify_incognito = !entry->incognito_persistent_settings.empty() ||
|
| + !entry->incognito_session_only_settings.empty();
|
| +
|
| + entry->enabled = is_enabled;
|
| }
|
| if (notify)
|
| NotifyOfContentSettingChanged(ext_id, false);
|
| @@ -187,46 +195,34 @@ void ContentSettingsStore::SetExtensionState(
|
| OriginIdentifierValueMap* ContentSettingsStore::GetValueMap(
|
| const std::string& ext_id,
|
| ExtensionPrefsScope scope) {
|
| - ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
|
| - if (i != entries_.end()) {
|
| - switch (scope) {
|
| - case kExtensionPrefsScopeRegular:
|
| - return &(i->second->settings);
|
| - case kExtensionPrefsScopeRegularOnly:
|
| - // TODO(bauerb): Implement regular-only content settings.
|
| - NOTREACHED();
|
| - return NULL;
|
| - case kExtensionPrefsScopeIncognitoPersistent:
|
| - return &(i->second->incognito_persistent_settings);
|
| - case kExtensionPrefsScopeIncognitoSessionOnly:
|
| - return &(i->second->incognito_session_only_settings);
|
| - }
|
| - }
|
| - return NULL;
|
| + const OriginIdentifierValueMap* result =
|
| + static_cast<const ContentSettingsStore*>(this)->GetValueMap(ext_id,
|
| + scope);
|
| + return const_cast<OriginIdentifierValueMap*>(result);
|
| }
|
|
|
| const OriginIdentifierValueMap* ContentSettingsStore::GetValueMap(
|
| const std::string& ext_id,
|
| ExtensionPrefsScope scope) const {
|
| - ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
|
| - if (i == entries_.end())
|
| - return NULL;
|
| + ExtensionEntry* entry = FindEntry(ext_id);
|
| + if (!entry)
|
| + return nullptr;
|
|
|
| switch (scope) {
|
| case kExtensionPrefsScopeRegular:
|
| - return &(i->second->settings);
|
| + return &(entry->settings);
|
| case kExtensionPrefsScopeRegularOnly:
|
| // TODO(bauerb): Implement regular-only content settings.
|
| NOTREACHED();
|
| - return NULL;
|
| + return nullptr;
|
| case kExtensionPrefsScopeIncognitoPersistent:
|
| - return &(i->second->incognito_persistent_settings);
|
| + return &(entry->incognito_persistent_settings);
|
| case kExtensionPrefsScopeIncognitoSessionOnly:
|
| - return &(i->second->incognito_session_only_settings);
|
| + return &(entry->incognito_session_only_settings);
|
| }
|
|
|
| NOTREACHED();
|
| - return NULL;
|
| + return nullptr;
|
| }
|
|
|
| void ContentSettingsStore::ClearContentSettingsForExtension(
|
| @@ -375,24 +371,22 @@ bool ContentSettingsStore::OnCorrectThread() {
|
| BrowserThread::CurrentlyOn(BrowserThread::UI);
|
| }
|
|
|
| -ContentSettingsStore::ExtensionEntryMap::iterator
|
| -ContentSettingsStore::FindEntry(const std::string& ext_id) {
|
| - ExtensionEntryMap::iterator i;
|
| - for (i = entries_.begin(); i != entries_.end(); ++i) {
|
| - if (i->second->id == ext_id)
|
| - return i;
|
| - }
|
| - return entries_.end();
|
| +ContentSettingsStore::ExtensionEntry* ContentSettingsStore::FindEntry(
|
| + const std::string& ext_id) const {
|
| + auto iter =
|
| + std::find_if(entries_.begin(), entries_.end(),
|
| + [ext_id](const std::unique_ptr<ExtensionEntry>& entry) {
|
| + return entry->id == ext_id;
|
| + });
|
| + return iter == entries_.end() ? nullptr : iter->get();
|
| }
|
|
|
| -ContentSettingsStore::ExtensionEntryMap::const_iterator
|
| -ContentSettingsStore::FindEntry(const std::string& ext_id) const {
|
| - ExtensionEntryMap::const_iterator i;
|
| - for (i = entries_.begin(); i != entries_.end(); ++i) {
|
| - if (i->second->id == ext_id)
|
| - return i;
|
| - }
|
| - return entries_.end();
|
| +ContentSettingsStore::ExtensionEntries::iterator
|
| +ContentSettingsStore::FindIterator(const std::string& ext_id) {
|
| + return std::find_if(entries_.begin(), entries_.end(),
|
| + [ext_id](const std::unique_ptr<ExtensionEntry>& entry) {
|
| + return entry->id == ext_id;
|
| + });
|
| }
|
|
|
| } // namespace extensions
|
|
|