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