Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/storage/managed_value_store_cache.h" | 5 #include "chrome/browser/extensions/api/storage/managed_value_store_cache.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
| 16 #include "base/scoped_observer.h" | 16 #include "base/scoped_observer.h" |
| 17 #include "chrome/browser/extensions/api/storage/policy_value_store.h" | 17 #include "chrome/browser/extensions/api/storage/policy_value_store.h" |
| 18 #include "chrome/browser/policy/profile_policy_connector.h" | 18 #include "chrome/browser/policy/profile_policy_connector.h" |
| 19 #include "chrome/browser/policy/profile_policy_connector_factory.h" | 19 #include "chrome/browser/policy/profile_policy_connector_factory.h" |
| 20 #include "chrome/browser/policy/schema_registry_service.h" | 20 #include "chrome/browser/policy/schema_registry_service.h" |
| 21 #include "chrome/browser/policy/schema_registry_service_factory.h" | 21 #include "chrome/browser/policy/schema_registry_service_factory.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h " | 23 #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h " |
| 24 #include "components/policy/core/common/policy_namespace.h" | |
| 25 #include "components/policy/core/common/schema.h" | 24 #include "components/policy/core/common/schema.h" |
| 26 #include "components/policy/core/common/schema_map.h" | 25 #include "components/policy/core/common/schema_map.h" |
| 27 #include "components/policy/core/common/schema_registry.h" | 26 #include "components/policy/core/common/schema_registry.h" |
| 28 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 29 #include "extensions/browser/extension_prefs.h" | 28 #include "extensions/browser/extension_prefs.h" |
| 30 #include "extensions/browser/extension_registry.h" | 29 #include "extensions/browser/extension_registry.h" |
| 31 #include "extensions/browser/extension_registry_observer.h" | 30 #include "extensions/browser/extension_registry_observer.h" |
| 32 #include "extensions/browser/extension_system.h" | 31 #include "extensions/browser/extension_system.h" |
| 33 #include "extensions/browser/value_store/value_store_change.h" | 32 #include "extensions/browser/value_store/value_store_change.h" |
| 34 #include "extensions/browser/value_store/value_store_factory.h" | 33 #include "extensions/browser/value_store/value_store_factory.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 60 } // namespace | 59 } // namespace |
| 61 | 60 |
| 62 // This helper observes initialization of all the installed extensions and | 61 // This helper observes initialization of all the installed extensions and |
| 63 // subsequent loads and unloads, and keeps the SchemaRegistry of the Profile | 62 // subsequent loads and unloads, and keeps the SchemaRegistry of the Profile |
| 64 // in sync with the current list of extensions. This allows the PolicyService | 63 // in sync with the current list of extensions. This allows the PolicyService |
| 65 // to fetch cloud policy for those extensions, and allows its providers to | 64 // to fetch cloud policy for those extensions, and allows its providers to |
| 66 // selectively load only extension policy that has users. | 65 // selectively load only extension policy that has users. |
| 67 class ManagedValueStoreCache::ExtensionTracker | 66 class ManagedValueStoreCache::ExtensionTracker |
| 68 : public ExtensionRegistryObserver { | 67 : public ExtensionRegistryObserver { |
| 69 public: | 68 public: |
| 70 explicit ExtensionTracker(Profile* profile); | 69 ExtensionTracker(Profile* profile, policy::PolicyDomain policy_domain); |
| 71 ~ExtensionTracker() override {} | 70 ~ExtensionTracker() override {} |
| 72 | 71 |
| 73 private: | 72 private: |
| 74 // ExtensionRegistryObserver implementation. | 73 // ExtensionRegistryObserver implementation. |
| 75 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, | 74 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, |
| 76 const Extension* extension, | 75 const Extension* extension, |
| 77 bool is_update, | 76 bool is_update, |
| 78 const std::string& old_name) override; | 77 const std::string& old_name) override; |
| 79 void OnExtensionUninstalled(content::BrowserContext* browser_context, | 78 void OnExtensionUninstalled(content::BrowserContext* browser_context, |
| 80 const Extension* extension, | 79 const Extension* extension, |
| 81 extensions::UninstallReason reason) override; | 80 extensions::UninstallReason reason) override; |
| 82 | 81 |
| 83 // Handler for the signal from ExtensionSystem::ready(). | 82 // Handler for the signal from ExtensionSystem::ready(). |
| 84 void OnExtensionsReady(); | 83 void OnExtensionsReady(); |
| 85 | 84 |
| 86 // Starts a schema load for all extensions that use managed storage. | 85 // Starts a schema load for all extensions that use managed storage. |
| 87 void LoadSchemas(std::unique_ptr<ExtensionSet> added); | 86 void LoadSchemas(std::unique_ptr<ExtensionSet> added); |
| 88 | 87 |
| 89 bool UsesManagedStorage(const Extension* extension) const; | 88 bool UsesManagedStorage(const Extension* extension) const; |
| 90 | 89 |
| 91 // Loads the schemas of the |extensions| and passes a ComponentMap to | 90 // Loads the schemas of the |extensions| and passes a ComponentMap to |
| 92 // Register(). | 91 // Register(). |
| 93 static void LoadSchemasOnBlockingPool( | 92 static void LoadSchemasOnBlockingPool( |
| 94 std::unique_ptr<ExtensionSet> extensions, | 93 std::unique_ptr<ExtensionSet> extensions, |
| 95 base::WeakPtr<ExtensionTracker> self); | 94 base::WeakPtr<ExtensionTracker> self); |
| 96 void Register(const policy::ComponentMap* components); | 95 void Register(const policy::ComponentMap* components); |
| 97 | 96 |
| 98 Profile* profile_; | 97 Profile* profile_; |
| 98 policy::PolicyDomain policy_domain_; | |
| 99 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> | 99 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| 100 extension_registry_observer_; | 100 extension_registry_observer_; |
| 101 policy::SchemaRegistry* schema_registry_; | 101 policy::SchemaRegistry* schema_registry_; |
| 102 base::WeakPtrFactory<ExtensionTracker> weak_factory_; | 102 base::WeakPtrFactory<ExtensionTracker> weak_factory_; |
| 103 | 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(ExtensionTracker); | 104 DISALLOW_COPY_AND_ASSIGN(ExtensionTracker); |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 ManagedValueStoreCache::ExtensionTracker::ExtensionTracker(Profile* profile) | 107 ManagedValueStoreCache::ExtensionTracker::ExtensionTracker( |
| 108 Profile* profile, | |
| 109 policy::PolicyDomain policy_domain) | |
| 108 : profile_(profile), | 110 : profile_(profile), |
| 111 policy_domain_(policy_domain), | |
| 109 extension_registry_observer_(this), | 112 extension_registry_observer_(this), |
| 110 schema_registry_(policy::SchemaRegistryServiceFactory::GetForContext( | 113 schema_registry_( |
| 111 profile)->registry()), | 114 policy::SchemaRegistryServiceFactory::GetForContext(profile) |
| 115 ->registry()), | |
| 112 weak_factory_(this) { | 116 weak_factory_(this) { |
| 113 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | 117 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); |
| 114 // Load schemas when the extension system is ready. It might be ready now. | 118 // Load schemas when the extension system is ready. It might be ready now. |
| 115 ExtensionSystem::Get(profile_)->ready().Post( | 119 ExtensionSystem::Get(profile_)->ready().Post( |
| 116 FROM_HERE, | 120 FROM_HERE, |
| 117 base::Bind(&ExtensionTracker::OnExtensionsReady, | 121 base::Bind(&ExtensionTracker::OnExtensionsReady, |
| 118 weak_factory_.GetWeakPtr())); | 122 weak_factory_.GetWeakPtr())); |
| 119 } | 123 } |
| 120 | 124 |
| 121 void ManagedValueStoreCache::ExtensionTracker::OnExtensionWillBeInstalled( | 125 void ManagedValueStoreCache::ExtensionTracker::OnExtensionWillBeInstalled( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 134 LoadSchemas(std::move(added)); | 138 LoadSchemas(std::move(added)); |
| 135 } | 139 } |
| 136 | 140 |
| 137 void ManagedValueStoreCache::ExtensionTracker::OnExtensionUninstalled( | 141 void ManagedValueStoreCache::ExtensionTracker::OnExtensionUninstalled( |
| 138 content::BrowserContext* browser_context, | 142 content::BrowserContext* browser_context, |
| 139 const Extension* extension, | 143 const Extension* extension, |
| 140 extensions::UninstallReason reason) { | 144 extensions::UninstallReason reason) { |
| 141 if (!ExtensionSystem::Get(profile_)->ready().is_signaled()) | 145 if (!ExtensionSystem::Get(profile_)->ready().is_signaled()) |
| 142 return; | 146 return; |
| 143 if (extension && UsesManagedStorage(extension)) { | 147 if (extension && UsesManagedStorage(extension)) { |
| 144 schema_registry_->UnregisterComponent(policy::PolicyNamespace( | 148 schema_registry_->UnregisterComponent( |
| 145 policy::POLICY_DOMAIN_EXTENSIONS, extension->id())); | 149 policy::PolicyNamespace(policy_domain_, extension->id())); |
| 146 } | 150 } |
| 147 } | 151 } |
| 148 | 152 |
| 149 void ManagedValueStoreCache::ExtensionTracker::OnExtensionsReady() { | 153 void ManagedValueStoreCache::ExtensionTracker::OnExtensionsReady() { |
| 150 // Load schemas for all installed extensions. | 154 // Load schemas for all installed extensions. |
| 151 LoadSchemas( | 155 LoadSchemas( |
| 152 ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet()); | 156 ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet()); |
| 153 } | 157 } |
| 154 | 158 |
| 155 void ManagedValueStoreCache::ExtensionTracker::LoadSchemas( | 159 void ManagedValueStoreCache::ExtensionTracker::LoadSchemas( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 } | 211 } |
| 208 | 212 |
| 209 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 213 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 210 base::Bind(&ExtensionTracker::Register, self, | 214 base::Bind(&ExtensionTracker::Register, self, |
| 211 base::Owned(components.release()))); | 215 base::Owned(components.release()))); |
| 212 } | 216 } |
| 213 | 217 |
| 214 void ManagedValueStoreCache::ExtensionTracker::Register( | 218 void ManagedValueStoreCache::ExtensionTracker::Register( |
| 215 const policy::ComponentMap* components) { | 219 const policy::ComponentMap* components) { |
| 216 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 220 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 217 schema_registry_->RegisterComponents(policy::POLICY_DOMAIN_EXTENSIONS, | 221 schema_registry_->RegisterComponents(policy_domain_, *components); |
| 218 *components); | |
| 219 | 222 |
| 220 // The first SetReady() call is performed after the ExtensionSystem is ready, | 223 // The first SetReady() call is performed after the ExtensionSystem is ready, |
| 221 // even if there are no managed extensions. It will trigger a loading of the | 224 // even if there are no managed extensions. It will trigger a loading of the |
| 222 // initial policy for any managed extensions, and eventually the PolicyService | 225 // initial policy for any managed extensions, and eventually the PolicyService |
| 223 // will become ready for POLICY_DOMAIN_EXTENSIONS, and | 226 // will become ready for policy for extensions, and |
| 224 // OnPolicyServiceInitialized() will be invoked. | 227 // OnPolicyServiceInitialized() will be invoked. |
| 225 // Subsequent calls to SetReady() are ignored. | 228 // Subsequent calls to SetReady() are ignored. |
| 229 // | |
| 230 // Note that instead of using the |policy_domain_| value here, both of the | |
|
Devlin
2016/10/27 00:50:34
I'm confused by this, despite the helpful comment.
emaxx
2016/10/27 13:34:22
OK, so probably my comment is not clarifying the t
Devlin
2016/10/27 14:47:33
Thanks for the explanation. If this is the only p
emaxx
2016/10/27 16:15:48
Sounds reasonable. I've updated the CL accordingly
| |
| 231 // extensions-related policy domains are marked as ready. That's due to | |
| 232 // some logic in the policy stack that is depending on the readiness state of | |
| 233 // schema registry, which is defined as a logical conjunction of the readiness | |
| 234 // state of all policy domains. As there is no other relevant piece in the | |
| 235 // code that could set the readiness state of the domain different from | |
| 236 // |policy_domain_|, it has to be done here. | |
| 226 schema_registry_->SetReady(policy::POLICY_DOMAIN_EXTENSIONS); | 237 schema_registry_->SetReady(policy::POLICY_DOMAIN_EXTENSIONS); |
| 238 schema_registry_->SetReady(policy::POLICY_DOMAIN_SIGNIN_EXTENSIONS); | |
| 227 } | 239 } |
| 228 | 240 |
| 229 ManagedValueStoreCache::ManagedValueStoreCache( | 241 ManagedValueStoreCache::ManagedValueStoreCache( |
| 230 BrowserContext* context, | 242 BrowserContext* context, |
| 231 const scoped_refptr<ValueStoreFactory>& factory, | 243 const scoped_refptr<ValueStoreFactory>& factory, |
| 232 const scoped_refptr<SettingsObserverList>& observers) | 244 const scoped_refptr<SettingsObserverList>& observers) |
| 233 : profile_(Profile::FromBrowserContext(context)), | 245 : profile_(Profile::FromBrowserContext(context)), |
| 246 policy_domain_(policy::POLICY_DOMAIN_EXTENSIONS), | |
| 234 policy_service_( | 247 policy_service_( |
| 235 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(context) | 248 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(context) |
| 236 ->policy_service()), | 249 ->policy_service()), |
| 237 storage_factory_(factory), | 250 storage_factory_(factory), |
| 238 observers_(observers) { | 251 observers_(observers) { |
| 239 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 252 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 240 | 253 |
| 241 policy_service_->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); | 254 policy_service_->AddObserver(policy_domain_, this); |
| 242 | 255 |
| 243 extension_tracker_.reset(new ExtensionTracker(profile_)); | 256 extension_tracker_.reset(new ExtensionTracker(profile_, policy_domain_)); |
| 244 | 257 |
| 245 if (policy_service_->IsInitializationComplete( | 258 if (policy_service_->IsInitializationComplete(policy_domain_)) |
| 246 policy::POLICY_DOMAIN_EXTENSIONS)) { | 259 OnPolicyServiceInitialized(policy_domain_); |
| 247 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_EXTENSIONS); | |
| 248 } | |
| 249 } | 260 } |
| 250 | 261 |
| 251 ManagedValueStoreCache::~ManagedValueStoreCache() { | 262 ManagedValueStoreCache::~ManagedValueStoreCache() { |
| 252 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 263 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 253 // Delete the PolicyValueStores on FILE. | 264 // Delete the PolicyValueStores on FILE. |
| 254 store_map_.clear(); | 265 store_map_.clear(); |
| 255 } | 266 } |
| 256 | 267 |
| 257 void ManagedValueStoreCache::ShutdownOnUI() { | 268 void ManagedValueStoreCache::ShutdownOnUI() { |
| 258 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 269 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 259 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this); | 270 policy_service_->RemoveObserver(policy_domain_, this); |
| 260 extension_tracker_.reset(); | 271 extension_tracker_.reset(); |
| 261 } | 272 } |
| 262 | 273 |
| 263 void ManagedValueStoreCache::RunWithValueStoreForExtension( | 274 void ManagedValueStoreCache::RunWithValueStoreForExtension( |
| 264 const StorageCallback& callback, | 275 const StorageCallback& callback, |
| 265 scoped_refptr<const Extension> extension) { | 276 scoped_refptr<const Extension> extension) { |
| 266 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 277 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 267 callback.Run(GetStoreFor(extension->id())); | 278 callback.Run(GetStoreFor(extension->id())); |
| 268 } | 279 } |
| 269 | 280 |
| 270 void ManagedValueStoreCache::DeleteStorageSoon( | 281 void ManagedValueStoreCache::DeleteStorageSoon( |
| 271 const std::string& extension_id) { | 282 const std::string& extension_id) { |
| 272 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 283 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 273 // It's possible that the store exists, but hasn't been loaded yet | 284 // It's possible that the store exists, but hasn't been loaded yet |
| 274 // (because the extension is unloaded, for example). Open the database to | 285 // (because the extension is unloaded, for example). Open the database to |
| 275 // clear it if it exists. | 286 // clear it if it exists. |
| 276 if (!HasStore(extension_id)) | 287 if (!HasStore(extension_id)) |
| 277 return; | 288 return; |
| 278 GetStoreFor(extension_id)->DeleteStorage(); | 289 GetStoreFor(extension_id)->DeleteStorage(); |
| 279 store_map_.erase(extension_id); | 290 store_map_.erase(extension_id); |
| 280 } | 291 } |
| 281 | 292 |
| 282 void ManagedValueStoreCache::OnPolicyServiceInitialized( | 293 void ManagedValueStoreCache::OnPolicyServiceInitialized( |
| 283 policy::PolicyDomain domain) { | 294 policy::PolicyDomain domain) { |
| 284 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 295 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 285 | 296 |
| 286 if (domain != policy::POLICY_DOMAIN_EXTENSIONS) | 297 if (domain != policy_domain_) |
| 287 return; | 298 return; |
| 288 | 299 |
| 289 // The PolicyService now has all the initial policies ready. Send policy | 300 // The PolicyService now has all the initial policies ready. Send policy |
| 290 // for all the managed extensions to their backing stores now. | 301 // for all the managed extensions to their backing stores now. |
| 291 policy::SchemaRegistry* registry = | 302 policy::SchemaRegistry* registry = |
| 292 policy::SchemaRegistryServiceFactory::GetForContext(profile_)->registry(); | 303 policy::SchemaRegistryServiceFactory::GetForContext(profile_)->registry(); |
| 293 const policy::ComponentMap* map = registry->schema_map()->GetComponents( | 304 const policy::ComponentMap* map = |
| 294 policy::POLICY_DOMAIN_EXTENSIONS); | 305 registry->schema_map()->GetComponents(policy_domain_); |
| 295 if (!map) | 306 if (!map) |
| 296 return; | 307 return; |
| 297 | 308 |
| 298 const policy::PolicyMap empty_map; | 309 const policy::PolicyMap empty_map; |
| 299 for (policy::ComponentMap::const_iterator it = map->begin(); | 310 for (policy::ComponentMap::const_iterator it = map->begin(); |
| 300 it != map->end(); ++it) { | 311 it != map->end(); ++it) { |
| 301 const policy::PolicyNamespace ns(policy::POLICY_DOMAIN_EXTENSIONS, | 312 const policy::PolicyNamespace ns(policy_domain_, it->first); |
| 302 it->first); | |
| 303 // If there is no policy for |ns| then this will clear the previous store, | 313 // If there is no policy for |ns| then this will clear the previous store, |
| 304 // if there is one. | 314 // if there is one. |
| 305 OnPolicyUpdated(ns, empty_map, policy_service_->GetPolicies(ns)); | 315 OnPolicyUpdated(ns, empty_map, policy_service_->GetPolicies(ns)); |
| 306 } | 316 } |
| 307 } | 317 } |
| 308 | 318 |
| 309 void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns, | 319 void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns, |
| 310 const policy::PolicyMap& previous, | 320 const policy::PolicyMap& previous, |
| 311 const policy::PolicyMap& current) { | 321 const policy::PolicyMap& current) { |
| 312 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 322 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 313 | 323 |
| 314 if (!policy_service_->IsInitializationComplete( | 324 if (!policy_service_->IsInitializationComplete(policy_domain_)) { |
| 315 policy::POLICY_DOMAIN_EXTENSIONS)) { | |
| 316 // OnPolicyUpdated is called whenever a policy changes, but it doesn't | 325 // OnPolicyUpdated is called whenever a policy changes, but it doesn't |
| 317 // mean that all the policy providers are ready; wait until we get the | 326 // mean that all the policy providers are ready; wait until we get the |
| 318 // final policy values before passing them to the store. | 327 // final policy values before passing them to the store. |
| 319 return; | 328 return; |
| 320 } | 329 } |
| 321 | 330 |
| 322 BrowserThread::PostTask( | 331 BrowserThread::PostTask( |
| 323 BrowserThread::FILE, FROM_HERE, | 332 BrowserThread::FILE, FROM_HERE, |
| 324 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, | 333 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, |
| 325 base::Unretained(this), | 334 base::Unretained(this), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 return store; | 370 return store; |
| 362 } | 371 } |
| 363 | 372 |
| 364 bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const { | 373 bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const { |
| 365 // Note: Currently only manage extensions (not apps). | 374 // Note: Currently only manage extensions (not apps). |
| 366 return storage_factory_->HasSettings(settings_namespace::MANAGED, | 375 return storage_factory_->HasSettings(settings_namespace::MANAGED, |
| 367 kManagedModelType, extension_id); | 376 kManagedModelType, extension_id); |
| 368 } | 377 } |
| 369 | 378 |
| 370 } // namespace extensions | 379 } // namespace extensions |
| OLD | NEW |