1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 3792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// found in the LICENSE file. 4792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 5792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "chrome/browser/content_settings/content_settings_origin_identifier_value_map.h" 6792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 7792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "base/compiler_specific.h" 8792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "base/logging.h" 9792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "base/memory/scoped_ptr.h" 10792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "base/synchronization/lock.h" 11792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "base/values.h" 12792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "chrome/browser/content_settings/content_settings_rule.h" 13792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "chrome/browser/content_settings/content_settings_utils.h" 14792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "chrome/common/content_settings_types.h" 15792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project#include "url/gurl.h" 16792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 17792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectnamespace content_settings { 18792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 19f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissennamespace { 20f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 21792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// This iterator is used for iterating the rules for |content_type| and 22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project// |resource_identifier| in the precedence order of the rules. 23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectclass RuleIteratorImpl : public RuleIterator { 24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project public: 253fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen // |RuleIteratorImpl| takes the ownership of |auto_lock|. 26792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project RuleIteratorImpl( 27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const OriginIdentifierValueMap::Rules::const_iterator& current_rule, 28792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const OriginIdentifierValueMap::Rules::const_iterator& rule_end, 29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project base::AutoLock* auto_lock) 303fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen : current_rule_(current_rule), 31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project rule_end_(rule_end), 32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project auto_lock_(auto_lock) { 33792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project virtual ~RuleIteratorImpl() {} 35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 36792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project virtual bool HasNext() const OVERRIDE { 37792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return (current_rule_ != rule_end_); 383fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen } 39792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 401968e38c437d7419ba01e5b7c1081f01ae618783Marco Nelissen virtual Rule Next() OVERRIDE { 41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project DCHECK(current_rule_ != rule_end_); 42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project DCHECK(current_rule_->second.get()); 43792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project Rule to_return(current_rule_->first.primary_pattern, 44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project current_rule_->first.secondary_pattern, 45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project current_rule_->second.get()->DeepCopy()); 46792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ++current_rule_; 47792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return to_return; 48792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 49792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 50792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project private: 51792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project OriginIdentifierValueMap::Rules::const_iterator current_rule_; 52792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project OriginIdentifierValueMap::Rules::const_iterator rule_end_; 53792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project scoped_ptr<base::AutoLock> auto_lock_; 54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project}; 55792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} // namespace 573fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 583fdd97fb21031de30e604d470fc8458b814e6587Marco NelissenOriginIdentifierValueMap::EntryMapKey::EntryMapKey( 59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentSettingsType content_type, 60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ResourceIdentifier& resource_identifier) 61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project : content_type(content_type), 62792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project resource_identifier(resource_identifier) { 63792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 64792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 65792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectbool OriginIdentifierValueMap::EntryMapKey::operator<( 66792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const OriginIdentifierValueMap::EntryMapKey& other) const { 67792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (content_type != other.content_type) 68792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return content_type < other.content_type; 69792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project return (resource_identifier < other.resource_identifier); 70792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 71f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen 72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source ProjectOriginIdentifierValueMap::PatternPair::PatternPair( 73792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ContentSettingsPattern& primary_pattern, 74792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ContentSettingsPattern& secondary_pattern) 75792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project : primary_pattern(primary_pattern), 76792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project secondary_pattern(secondary_pattern) { 77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectbool OriginIdentifierValueMap::PatternPair::operator<( 80792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const OriginIdentifierValueMap::PatternPair& other) const { 81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // Note that this operator is the other way around than 82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // |ContentSettingsPattern::operator<|. It sorts patterns with higher 833fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen // precedence first. 84f33a575c2b09095d58ad7af527113f767e4c37b1Marco Nelissen if (primary_pattern > other.primary_pattern) 853fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen return true; 863fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen else if (other.primary_pattern > primary_pattern) 873fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen return false; 883fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen return (secondary_pattern > other.secondary_pattern); 893fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen} 90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 91792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source ProjectRuleIterator* OriginIdentifierValueMap::GetRuleIterator( 92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentSettingsType content_type, 93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ResourceIdentifier& resource_identifier, 94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project base::Lock* lock) const { 95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project EntryMapKey key(content_type, resource_identifier); 963fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen // We access |entries_| here, so we need to lock |lock_| first. The lock must 979882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen // be passed to the |RuleIteratorImpl| in a locked state, so that nobody can 983fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen // access |entries_| after |find()| but before the |RuleIteratorImpl| is 999882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen // created. 1003fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen scoped_ptr<base::AutoLock> auto_lock; 1013fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen if (lock) 1023fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen auto_lock.reset(new base::AutoLock(*lock)); 1033fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen EntryMap::const_iterator it = entries_.find(key); 1043fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen if (it == entries_.end()) 1053fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen return new EmptyRuleIterator(); 106bd447b61c42589133257fb7992ccbed18a507a46Marco Nelissen return new RuleIteratorImpl(it->second.begin(), 1073fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen it->second.end(), 1083fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen auto_lock.release()); 1093fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen} 1103fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 1113fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissensize_t OriginIdentifierValueMap::size() const { 1123fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen size_t size = 0; 1133fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen EntryMap::const_iterator it; 1143fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen for (it = entries_.begin(); it != entries_.end(); ++it) 1153fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen size += it->second.size(); 1163fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen return size; 1173fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen} 1183fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 1193fdd97fb21031de30e604d470fc8458b814e6587Marco NelissenOriginIdentifierValueMap::OriginIdentifierValueMap() {} 1203fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 1213fdd97fb21031de30e604d470fc8458b814e6587Marco NelissenOriginIdentifierValueMap::~OriginIdentifierValueMap() {} 1223fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 1233fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissenbase::Value* OriginIdentifierValueMap::GetValue( 1243fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen const GURL& primary_url, 1253fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen const GURL& secondary_url, 126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentSettingsType content_type, 127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ResourceIdentifier& resource_identifier) const { 1289882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen EntryMapKey key(content_type, resource_identifier); 1293fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen EntryMap::const_iterator it = entries_.find(key); 1309882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen if (it == entries_.end()) 1319882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen return NULL; 1329882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen 1339882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen // Iterate the entries in until a match is found. Since the rules are stored 1349882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen // in the order of decreasing precedence, the most specific match is found 1359882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen // first. 1369882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen Rules::const_iterator entry; 1379882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen for (entry = it->second.begin(); entry != it->second.end(); ++entry) { 1389882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen if (entry->first.primary_pattern.Matches(primary_url) && 1399882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen entry->first.secondary_pattern.Matches(secondary_url)) { 1409882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen return entry->second.get(); 1419882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen } 1429882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen } 1439882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen return NULL; 1449882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen} 1459882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen 1469882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissenvoid OriginIdentifierValueMap::SetValue( 1479882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen const ContentSettingsPattern& primary_pattern, 1489882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen const ContentSettingsPattern& secondary_pattern, 1499882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen ContentSettingsType content_type, 1509882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen const ResourceIdentifier& resource_identifier, 1519882f540844f6a613eeb5edf5f076d1dcc72bf9fMarco Nelissen base::Value* value) { 152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project DCHECK(primary_pattern.IsValid()); 153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project DCHECK(secondary_pattern.IsValid()); 154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project DCHECK(value); 155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project EntryMapKey key(content_type, resource_identifier); 156792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project PatternPair patterns(primary_pattern, secondary_pattern); 157792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project // This will create the entry and the linked_ptr if needed. 158792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project entries_[key][patterns].reset(value); 159792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 160792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 161792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectvoid OriginIdentifierValueMap::DeleteValue( 162792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ContentSettingsPattern& primary_pattern, 163792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ContentSettingsPattern& secondary_pattern, 164792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentSettingsType content_type, 165792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ResourceIdentifier& resource_identifier) { 166792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project EntryMapKey key(content_type, resource_identifier); 167792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project PatternPair patterns(primary_pattern, secondary_pattern); 168792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project entries_[key].erase(patterns); 169792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project if (entries_[key].empty()) { 170792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project entries_.erase(key); 171792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project } 172792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectvoid OriginIdentifierValueMap::DeleteValues( 175792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project ContentSettingsType content_type, 176792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project const ResourceIdentifier& resource_identifier) { 177792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project EntryMapKey key(content_type, resource_identifier); 178792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project entries_.erase(key); 179792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project} 180792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project 181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectvoid OriginIdentifierValueMap::clear() { 1823fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen // Delete all owned value objects. 1833fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen entries_.clear(); 1843fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen} 1853fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen 1863fdd97fb21031de30e604d470fc8458b814e6587Marco Nelissen} // namespace content_settings 187792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project