| OLD | NEW |
| 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/browser/extensions/api/declarative/rules_cache_delegate.h" | 5 #include "chrome/browser/extensions/api/declarative/rules_cache_delegate.h" |
| 6 | 6 |
| 7 #include "chrome/browser/chrome_notification_types.h" | 7 #include "chrome/browser/chrome_notification_types.h" |
| 8 #include "chrome/browser/extensions/api/declarative/rules_registry.h" | 8 #include "chrome/browser/extensions/api/declarative/rules_registry.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/extensions/extension_util.h" | 10 #include "chrome/browser/extensions/extension_util.h" |
| 11 #include "chrome/browser/profiles/profile.h" | 11 #include "content/public/browser/browser_context.h" |
| 12 #include "content/public/browser/notification_details.h" | 12 #include "content/public/browser/notification_details.h" |
| 13 #include "content/public/browser/notification_source.h" | 13 #include "content/public/browser/notification_source.h" |
| 14 #include "extensions/browser/extension_prefs.h" | 14 #include "extensions/browser/extension_prefs.h" |
| 15 #include "extensions/browser/extension_registry.h" | 15 #include "extensions/browser/extension_registry.h" |
| 16 #include "extensions/browser/extension_system.h" | 16 #include "extensions/browser/extension_system.h" |
| 17 #include "extensions/browser/info_map.h" | 17 #include "extensions/browser/info_map.h" |
| 18 #include "extensions/browser/state_store.h" | 18 #include "extensions/browser/state_store.h" |
| 19 #include "extensions/common/permissions/permissions_data.h" | 19 #include "extensions/common/permissions/permissions_data.h" |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 33 } // namespace | 33 } // namespace |
| 34 | 34 |
| 35 namespace extensions { | 35 namespace extensions { |
| 36 | 36 |
| 37 // RulesCacheDelegate | 37 // RulesCacheDelegate |
| 38 | 38 |
| 39 const char RulesCacheDelegate::kRulesStoredKey[] = | 39 const char RulesCacheDelegate::kRulesStoredKey[] = |
| 40 "has_declarative_rules"; | 40 "has_declarative_rules"; |
| 41 | 41 |
| 42 RulesCacheDelegate::RulesCacheDelegate(bool log_storage_init_delay) | 42 RulesCacheDelegate::RulesCacheDelegate(bool log_storage_init_delay) |
| 43 : profile_(NULL), | 43 : browser_context_(NULL), |
| 44 log_storage_init_delay_(log_storage_init_delay), | 44 log_storage_init_delay_(log_storage_init_delay), |
| 45 notified_registry_(false), | 45 notified_registry_(false), |
| 46 weak_ptr_factory_(this) { | 46 weak_ptr_factory_(this) { |
| 47 } | 47 } |
| 48 | 48 |
| 49 RulesCacheDelegate::~RulesCacheDelegate() {} | 49 RulesCacheDelegate::~RulesCacheDelegate() {} |
| 50 | 50 |
| 51 // Returns the key to use for storing whether the rules have been stored. | 51 // Returns the key to use for storing whether the rules have been stored. |
| 52 // static | 52 // static |
| 53 std::string RulesCacheDelegate::GetRulesStoredKey(const std::string& event_name, | 53 std::string RulesCacheDelegate::GetRulesStoredKey(const std::string& event_name, |
| 54 bool incognito) { | 54 bool incognito) { |
| 55 std::string result(kRulesStoredKey); | 55 std::string result(kRulesStoredKey); |
| 56 result += incognito ? ".incognito." : "."; | 56 result += incognito ? ".incognito." : "."; |
| 57 return result + event_name; | 57 return result + event_name; |
| 58 } | 58 } |
| 59 | 59 |
| 60 // This is called from the constructor of RulesRegistry, so it is | 60 // This is called from the constructor of RulesRegistry, so it is |
| 61 // important that it both | 61 // important that it both |
| 62 // 1. calls no (in particular virtual) methods of the rules registry, and | 62 // 1. calls no (in particular virtual) methods of the rules registry, and |
| 63 // 2. does not create scoped_refptr holding the registry. (A short-lived | 63 // 2. does not create scoped_refptr holding the registry. (A short-lived |
| 64 // scoped_refptr might delete the rules registry before it is constructed.) | 64 // scoped_refptr might delete the rules registry before it is constructed.) |
| 65 void RulesCacheDelegate::Init(RulesRegistry* registry) { | 65 void RulesCacheDelegate::Init(RulesRegistry* registry) { |
| 66 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 66 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 67 | 67 |
| 68 // WARNING: The first use of |registry_| will bind it to the calling thread | 68 // WARNING: The first use of |registry_| will bind it to the calling thread |
| 69 // so don't use this here. | 69 // so don't use this here. |
| 70 registry_ = registry->GetWeakPtr(); | 70 registry_ = registry->GetWeakPtr(); |
| 71 | 71 |
| 72 profile_ = registry->profile(); | 72 browser_context_ = registry->browser_context(); |
| 73 storage_key_ = | 73 storage_key_ = |
| 74 GetDeclarativeRuleStorageKey(registry->event_name(), | 74 GetDeclarativeRuleStorageKey(registry->event_name(), |
| 75 profile_->IsOffTheRecord()); | 75 browser_context_->IsOffTheRecord()); |
| 76 rules_stored_key_ = GetRulesStoredKey(registry->event_name(), | 76 rules_stored_key_ = GetRulesStoredKey(registry->event_name(), |
| 77 profile_->IsOffTheRecord()); | 77 browser_context_->IsOffTheRecord()); |
| 78 rules_registry_thread_ = registry->owner_thread(); | 78 rules_registry_thread_ = registry->owner_thread(); |
| 79 | 79 |
| 80 ExtensionSystem& system = *ExtensionSystem::Get(profile_); | 80 ExtensionSystem& system = *ExtensionSystem::Get(browser_context_); |
| 81 StateStore* store = system.rules_store(); | 81 StateStore* store = system.rules_store(); |
| 82 if (store) | 82 if (store) |
| 83 store->RegisterKey(storage_key_); | 83 store->RegisterKey(storage_key_); |
| 84 | 84 |
| 85 if (profile_->IsOffTheRecord()) | 85 if (browser_context_->IsOffTheRecord()) |
| 86 log_storage_init_delay_ = false; | 86 log_storage_init_delay_ = false; |
| 87 | 87 |
| 88 system.ready().Post( | 88 system.ready().Post( |
| 89 FROM_HERE, | 89 FROM_HERE, |
| 90 base::Bind(&RulesCacheDelegate::ReadRulesForInstalledExtensions, | 90 base::Bind(&RulesCacheDelegate::ReadRulesForInstalledExtensions, |
| 91 weak_ptr_factory_.GetWeakPtr())); | 91 weak_ptr_factory_.GetWeakPtr())); |
| 92 system.ready().Post(FROM_HERE, | 92 system.ready().Post(FROM_HERE, |
| 93 base::Bind(&RulesCacheDelegate::CheckIfReady, | 93 base::Bind(&RulesCacheDelegate::CheckIfReady, |
| 94 weak_ptr_factory_.GetWeakPtr())); | 94 weak_ptr_factory_.GetWeakPtr())); |
| 95 } | 95 } |
| 96 | 96 |
| 97 void RulesCacheDelegate::WriteToStorage(const std::string& extension_id, | 97 void RulesCacheDelegate::WriteToStorage(const std::string& extension_id, |
| 98 scoped_ptr<base::Value> value) { | 98 scoped_ptr<base::Value> value) { |
| 99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 100 if (!profile_) | 100 if (!browser_context_) |
| 101 return; | 101 return; |
| 102 | 102 |
| 103 const base::ListValue* rules = NULL; | 103 const base::ListValue* rules = NULL; |
| 104 CHECK(value->GetAsList(&rules)); | 104 CHECK(value->GetAsList(&rules)); |
| 105 bool rules_stored_previously = GetDeclarativeRulesStored(extension_id); | 105 bool rules_stored_previously = GetDeclarativeRulesStored(extension_id); |
| 106 bool store_rules = !rules->empty(); | 106 bool store_rules = !rules->empty(); |
| 107 SetDeclarativeRulesStored(extension_id, store_rules); | 107 SetDeclarativeRulesStored(extension_id, store_rules); |
| 108 if (!rules_stored_previously && !store_rules) | 108 if (!rules_stored_previously && !store_rules) |
| 109 return; | 109 return; |
| 110 | 110 |
| 111 StateStore* store = ExtensionSystem::Get(profile_)->rules_store(); | 111 StateStore* store = ExtensionSystem::Get(browser_context_)->rules_store(); |
| 112 if (store) | 112 if (store) |
| 113 store->SetExtensionValue(extension_id, storage_key_, value.Pass()); | 113 store->SetExtensionValue(extension_id, storage_key_, value.Pass()); |
| 114 } | 114 } |
| 115 | 115 |
| 116 void RulesCacheDelegate::CheckIfReady() { | 116 void RulesCacheDelegate::CheckIfReady() { |
| 117 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 117 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 118 if (notified_registry_ || !waiting_for_extensions_.empty()) | 118 if (notified_registry_ || !waiting_for_extensions_.empty()) |
| 119 return; | 119 return; |
| 120 | 120 |
| 121 content::BrowserThread::PostTask( | 121 content::BrowserThread::PostTask( |
| 122 rules_registry_thread_, | 122 rules_registry_thread_, |
| 123 FROM_HERE, | 123 FROM_HERE, |
| 124 base::Bind( | 124 base::Bind( |
| 125 &RulesRegistry::MarkReady, registry_, storage_init_time_)); | 125 &RulesRegistry::MarkReady, registry_, storage_init_time_)); |
| 126 notified_registry_ = true; | 126 notified_registry_ = true; |
| 127 } | 127 } |
| 128 | 128 |
| 129 void RulesCacheDelegate::ReadRulesForInstalledExtensions() { | 129 void RulesCacheDelegate::ReadRulesForInstalledExtensions() { |
| 130 ExtensionSystem& system = *ExtensionSystem::Get(profile_); | 130 ExtensionSystem& system = *ExtensionSystem::Get(browser_context_); |
| 131 ExtensionService* extension_service = system.extension_service(); | 131 ExtensionService* extension_service = system.extension_service(); |
| 132 DCHECK(extension_service); | 132 DCHECK(extension_service); |
| 133 // In an OTR profile, we start on top of a normal profile already, so the | 133 // In an OTR context, we start on top of a normal context already, so the |
| 134 // extension service should be ready. | 134 // extension service should be ready. |
| 135 DCHECK(!profile_->IsOffTheRecord() || extension_service->is_ready()); | 135 DCHECK(!browser_context_->IsOffTheRecord() || extension_service->is_ready()); |
| 136 if (extension_service->is_ready()) { | 136 if (extension_service->is_ready()) { |
| 137 const ExtensionSet* extensions = extension_service->extensions(); | 137 const ExtensionSet* extensions = extension_service->extensions(); |
| 138 for (ExtensionSet::const_iterator i = extensions->begin(); | 138 for (ExtensionSet::const_iterator i = extensions->begin(); |
| 139 i != extensions->end(); | 139 i != extensions->end(); |
| 140 ++i) { | 140 ++i) { |
| 141 bool needs_apis_storing_rules = | 141 bool needs_apis_storing_rules = |
| 142 (*i)->permissions_data()->HasAPIPermission( | 142 (*i)->permissions_data()->HasAPIPermission( |
| 143 APIPermission::kDeclarativeContent) || | 143 APIPermission::kDeclarativeContent) || |
| 144 (*i)->permissions_data()->HasAPIPermission( | 144 (*i)->permissions_data()->HasAPIPermission( |
| 145 APIPermission::kDeclarativeWebRequest); | 145 APIPermission::kDeclarativeWebRequest); |
| 146 bool respects_off_the_record = | 146 bool respects_off_the_record = |
| 147 !(profile_->IsOffTheRecord()) || | 147 !(browser_context_->IsOffTheRecord()) || |
| 148 util::IsIncognitoEnabled((*i)->id(), profile_); | 148 util::IsIncognitoEnabled((*i)->id(), browser_context_); |
| 149 if (needs_apis_storing_rules && respects_off_the_record) | 149 if (needs_apis_storing_rules && respects_off_the_record) |
| 150 ReadFromStorage((*i)->id()); | 150 ReadFromStorage((*i)->id()); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 void RulesCacheDelegate::ReadFromStorage(const std::string& extension_id) { | 155 void RulesCacheDelegate::ReadFromStorage(const std::string& extension_id) { |
| 156 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 156 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 157 if (!profile_) | 157 if (!browser_context_) |
| 158 return; | 158 return; |
| 159 | 159 |
| 160 if (log_storage_init_delay_ && storage_init_time_.is_null()) | 160 if (log_storage_init_delay_ && storage_init_time_.is_null()) |
| 161 storage_init_time_ = base::Time::Now(); | 161 storage_init_time_ = base::Time::Now(); |
| 162 | 162 |
| 163 if (!GetDeclarativeRulesStored(extension_id)) { | 163 if (!GetDeclarativeRulesStored(extension_id)) { |
| 164 ExtensionSystem::Get(profile_)->ready().Post( | 164 ExtensionSystem::Get(browser_context_)->ready().Post( |
| 165 FROM_HERE, base::Bind(&RulesCacheDelegate::CheckIfReady, | 165 FROM_HERE, base::Bind(&RulesCacheDelegate::CheckIfReady, |
| 166 weak_ptr_factory_.GetWeakPtr())); | 166 weak_ptr_factory_.GetWeakPtr())); |
| 167 return; | 167 return; |
| 168 } | 168 } |
| 169 | 169 |
| 170 StateStore* store = ExtensionSystem::Get(profile_)->rules_store(); | 170 StateStore* store = ExtensionSystem::Get(browser_context_)->rules_store(); |
| 171 if (!store) | 171 if (!store) |
| 172 return; | 172 return; |
| 173 waiting_for_extensions_.insert(extension_id); | 173 waiting_for_extensions_.insert(extension_id); |
| 174 store->GetExtensionValue( | 174 store->GetExtensionValue( |
| 175 extension_id, | 175 extension_id, |
| 176 storage_key_, | 176 storage_key_, |
| 177 base::Bind(&RulesCacheDelegate::ReadFromStorageCallback, | 177 base::Bind(&RulesCacheDelegate::ReadFromStorageCallback, |
| 178 weak_ptr_factory_.GetWeakPtr(), | 178 weak_ptr_factory_.GetWeakPtr(), |
| 179 extension_id)); | 179 extension_id)); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void RulesCacheDelegate::ReadFromStorageCallback( | 182 void RulesCacheDelegate::ReadFromStorageCallback( |
| 183 const std::string& extension_id, | 183 const std::string& extension_id, |
| 184 scoped_ptr<base::Value> value) { | 184 scoped_ptr<base::Value> value) { |
| 185 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 185 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 186 content::BrowserThread::PostTask( | 186 content::BrowserThread::PostTask( |
| 187 rules_registry_thread_, | 187 rules_registry_thread_, |
| 188 FROM_HERE, | 188 FROM_HERE, |
| 189 base::Bind(&RulesRegistry::DeserializeAndAddRules, | 189 base::Bind(&RulesRegistry::DeserializeAndAddRules, |
| 190 registry_, | 190 registry_, |
| 191 extension_id, | 191 extension_id, |
| 192 base::Passed(&value))); | 192 base::Passed(&value))); |
| 193 | 193 |
| 194 waiting_for_extensions_.erase(extension_id); | 194 waiting_for_extensions_.erase(extension_id); |
| 195 | 195 |
| 196 if (waiting_for_extensions_.empty()) | 196 if (waiting_for_extensions_.empty()) |
| 197 ExtensionSystem::Get(profile_)->ready().Post( | 197 ExtensionSystem::Get(browser_context_)->ready().Post( |
| 198 FROM_HERE, base::Bind(&RulesCacheDelegate::CheckIfReady, | 198 FROM_HERE, base::Bind(&RulesCacheDelegate::CheckIfReady, |
| 199 weak_ptr_factory_.GetWeakPtr())); | 199 weak_ptr_factory_.GetWeakPtr())); |
| 200 } | 200 } |
| 201 | 201 |
| 202 bool RulesCacheDelegate::GetDeclarativeRulesStored( | 202 bool RulesCacheDelegate::GetDeclarativeRulesStored( |
| 203 const std::string& extension_id) const { | 203 const std::string& extension_id) const { |
| 204 CHECK(profile_); | 204 CHECK(browser_context_); |
| 205 const ExtensionScopedPrefs* extension_prefs = ExtensionPrefs::Get(profile_); | 205 const ExtensionScopedPrefs* extension_prefs = |
| 206 ExtensionPrefs::Get(browser_context_); |
| 206 | 207 |
| 207 bool rules_stored = true; | 208 bool rules_stored = true; |
| 208 if (extension_prefs->ReadPrefAsBoolean( | 209 if (extension_prefs->ReadPrefAsBoolean( |
| 209 extension_id, rules_stored_key_, &rules_stored)) | 210 extension_id, rules_stored_key_, &rules_stored)) |
| 210 return rules_stored; | 211 return rules_stored; |
| 211 | 212 |
| 212 // Safe default -- if we don't know that the rules are not stored, we force | 213 // Safe default -- if we don't know that the rules are not stored, we force |
| 213 // a read by returning true. | 214 // a read by returning true. |
| 214 return true; | 215 return true; |
| 215 } | 216 } |
| 216 | 217 |
| 217 void RulesCacheDelegate::SetDeclarativeRulesStored( | 218 void RulesCacheDelegate::SetDeclarativeRulesStored( |
| 218 const std::string& extension_id, | 219 const std::string& extension_id, |
| 219 bool rules_stored) { | 220 bool rules_stored) { |
| 220 CHECK(profile_); | 221 CHECK(browser_context_); |
| 221 DCHECK(ExtensionRegistry::Get(profile_) | 222 DCHECK(ExtensionRegistry::Get(browser_context_) |
| 222 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING)); | 223 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING)); |
| 223 | 224 |
| 224 ExtensionScopedPrefs* extension_prefs = ExtensionPrefs::Get(profile_); | 225 ExtensionScopedPrefs* extension_prefs = ExtensionPrefs::Get(browser_context_); |
| 225 extension_prefs->UpdateExtensionPref( | 226 extension_prefs->UpdateExtensionPref( |
| 226 extension_id, | 227 extension_id, |
| 227 rules_stored_key_, | 228 rules_stored_key_, |
| 228 new base::FundamentalValue(rules_stored)); | 229 new base::FundamentalValue(rules_stored)); |
| 229 } | 230 } |
| 230 | 231 |
| 231 } // namespace extensions | 232 } // namespace extensions |
| OLD | NEW |