15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/content_settings/core/browser/content_settings_origin_identifier_value_map.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/content_settings/core/browser/content_settings_rule.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/content_settings/core/common/content_settings_types.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content_settings { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This iterator is used for iterating the rules for |content_type| and 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |resource_identifier| in the precedence order of the rules. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RuleIteratorImpl : public RuleIterator { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |RuleIteratorImpl| takes the ownership of |auto_lock|. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RuleIteratorImpl( 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OriginIdentifierValueMap::Rules::const_iterator& current_rule, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OriginIdentifierValueMap::Rules::const_iterator& rule_end, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock* auto_lock) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : current_rule_(current_rule), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_end_(rule_end), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto_lock_(auto_lock) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~RuleIteratorImpl() {} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasNext() const OVERRIDE { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (current_rule_ != rule_end_); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Rule Next() OVERRIDE { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_rule_ != rule_end_); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_rule_->second.get()); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rule to_return(current_rule_->first.primary_pattern, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_rule_->first.secondary_pattern, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_rule_->second.get()->DeepCopy()); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++current_rule_; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return to_return; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginIdentifierValueMap::Rules::const_iterator current_rule_; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginIdentifierValueMap::Rules::const_iterator rule_end_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::AutoLock> auto_lock_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OriginIdentifierValueMap::EntryMapKey::EntryMapKey( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : content_type(content_type), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_identifier(resource_identifier) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OriginIdentifierValueMap::EntryMapKey::operator<( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OriginIdentifierValueMap::EntryMapKey& other) const { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content_type != other.content_type) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content_type < other.content_type; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (resource_identifier < other.resource_identifier); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OriginIdentifierValueMap::PatternPair::PatternPair( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& primary_pattern, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& secondary_pattern) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : primary_pattern(primary_pattern), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) secondary_pattern(secondary_pattern) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OriginIdentifierValueMap::PatternPair::operator<( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OriginIdentifierValueMap::PatternPair& other) const { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this operator is the other way around than 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ContentSettingsPattern::operator<|. It sorts patterns with higher 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // precedence first. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (primary_pattern > other.primary_pattern) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (other.primary_pattern > primary_pattern) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (secondary_pattern > other.secondary_pattern); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RuleIterator* OriginIdentifierValueMap::GetRuleIterator( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock* lock) const { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMapKey key(content_type, resource_identifier); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We access |entries_| here, so we need to lock |lock_| first. The lock must 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be passed to the |RuleIteratorImpl| in a locked state, so that nobody can 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // access |entries_| after |find()| but before the |RuleIteratorImpl| is 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // created. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::AutoLock> auto_lock; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lock) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto_lock.reset(new base::AutoLock(*lock)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMap::const_iterator it = entries_.find(key); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == entries_.end()) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new EmptyRuleIterator(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new RuleIteratorImpl(it->second.begin(), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.end(), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto_lock.release()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t OriginIdentifierValueMap::size() const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMap::const_iterator it; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = entries_.begin(); it != entries_.end(); ++it) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size += it->second.size(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OriginIdentifierValueMap::OriginIdentifierValueMap() {} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OriginIdentifierValueMap::~OriginIdentifierValueMap() {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Value* OriginIdentifierValueMap::GetValue( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& primary_url, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& secondary_url, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier) const { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMapKey key(content_type, resource_identifier); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMap::const_iterator it = entries_.find(key); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == entries_.end()) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterate the entries in until a match is found. Since the rules are stored 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the order of decreasing precedence, the most specific match is found 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rules::const_iterator entry; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (entry = it->second.begin(); entry != it->second.end(); ++entry) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->first.primary_pattern.Matches(primary_url) && 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->first.secondary_pattern.Matches(secondary_url)) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entry->second.get(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OriginIdentifierValueMap::SetValue( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& primary_pattern, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& secondary_pattern, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier, 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Value* value) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(primary_pattern.IsValid()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(secondary_pattern.IsValid()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(value); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMapKey key(content_type, resource_identifier); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PatternPair patterns(primary_pattern, secondary_pattern); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will create the entry and the linked_ptr if needed. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[key][patterns].reset(value); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OriginIdentifierValueMap::DeleteValue( 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& primary_pattern, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& secondary_pattern, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMapKey key(content_type, resource_identifier); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PatternPair patterns(primary_pattern, secondary_pattern); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_[key].erase(patterns); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entries_[key].empty()) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(key); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OriginIdentifierValueMap::DeleteValues( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsType content_type, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceIdentifier& resource_identifier) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMapKey key(content_type, resource_identifier); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(key); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OriginIdentifierValueMap::clear() { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete all owned value objects. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.clear(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content_settings 186