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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "components/policy/core/common/schema_registry.h" | 31 #include "components/policy/core/common/schema_registry.h" |
32 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/notification_details.h" | 33 #include "content/public/browser/notification_details.h" |
34 #include "content/public/browser/notification_observer.h" | 34 #include "content/public/browser/notification_observer.h" |
35 #include "content/public/browser/notification_registrar.h" | 35 #include "content/public/browser/notification_registrar.h" |
36 #include "content/public/browser/notification_source.h" | 36 #include "content/public/browser/notification_source.h" |
37 #include "extensions/common/constants.h" | 37 #include "extensions/common/constants.h" |
38 #include "extensions/common/extension.h" | 38 #include "extensions/common/extension.h" |
39 #include "extensions/common/manifest.h" | 39 #include "extensions/common/manifest.h" |
40 #include "extensions/common/manifest_constants.h" | 40 #include "extensions/common/manifest_constants.h" |
| 41 #include "extensions/common/one_shot_event.h" |
41 #include "extensions/common/permissions/api_permission.h" | 42 #include "extensions/common/permissions/api_permission.h" |
42 | 43 |
43 using content::BrowserThread; | 44 using content::BrowserThread; |
44 | 45 |
45 namespace extensions { | 46 namespace extensions { |
46 | 47 |
47 namespace storage = api::storage; | 48 namespace storage = api::storage; |
48 | 49 |
49 namespace { | 50 namespace { |
50 | 51 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 content::Source<Profile>(profile_)); | 100 content::Source<Profile>(profile_)); |
100 registrar_.Add(this, | 101 registrar_.Add(this, |
101 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 102 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
102 content::Source<Profile>(profile_)); | 103 content::Source<Profile>(profile_)); |
103 } | 104 } |
104 | 105 |
105 void ManagedValueStoreCache::ExtensionTracker::Observe( | 106 void ManagedValueStoreCache::ExtensionTracker::Observe( |
106 int type, | 107 int type, |
107 const content::NotificationSource& source, | 108 const content::NotificationSource& source, |
108 const content::NotificationDetails& details) { | 109 const content::NotificationDetails& details) { |
| 110 // Some extensions are installed on the first run before the ExtensionService |
| 111 // becomes ready. Wait until all of them are ready before registering the |
| 112 // schemas of managed extensions, so that the policy loaders are reloaded at |
| 113 // most once. |
| 114 if (!ExtensionSystem::Get(profile_)->ready().is_signaled()) |
| 115 return; |
| 116 |
109 scoped_ptr<ExtensionSet> added; | 117 scoped_ptr<ExtensionSet> added; |
110 const Extension* removed = NULL; | 118 const Extension* removed = NULL; |
111 | 119 |
112 switch (type) { | 120 switch (type) { |
113 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 121 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
114 ExtensionService* service = | 122 ExtensionService* service = |
115 ExtensionSystem::Get(profile_)->extension_service(); | 123 ExtensionSystem::Get(profile_)->extension_service(); |
116 added = service->GenerateInstalledExtensionsSet(); | 124 added = service->GenerateInstalledExtensionsSet(); |
117 break; | 125 break; |
118 } | 126 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
263 callback.Run(GetStoreFor(extension->id())); | 271 callback.Run(GetStoreFor(extension->id())); |
264 } | 272 } |
265 | 273 |
266 void ManagedValueStoreCache::DeleteStorageSoon( | 274 void ManagedValueStoreCache::DeleteStorageSoon( |
267 const std::string& extension_id) { | 275 const std::string& extension_id) { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
269 // It's possible that the store exists, but hasn't been loaded yet | 277 // It's possible that the store exists, but hasn't been loaded yet |
270 // (because the extension is unloaded, for example). Open the database to | 278 // (because the extension is unloaded, for example). Open the database to |
271 // clear it if it exists. | 279 // clear it if it exists. |
272 // TODO(joaodasilva): move this check to a ValueStore method. | 280 if (!HasStore(extension_id)) |
273 if (!base::DirectoryExists(base_path_.AppendASCII(extension_id))) | |
274 return; | 281 return; |
275 GetStoreFor(extension_id)->DeleteStorage(); | 282 GetStoreFor(extension_id)->DeleteStorage(); |
276 store_map_.erase(extension_id); | 283 store_map_.erase(extension_id); |
277 } | 284 } |
278 | 285 |
279 void ManagedValueStoreCache::OnPolicyServiceInitialized( | 286 void ManagedValueStoreCache::OnPolicyServiceInitialized( |
280 policy::PolicyDomain domain) { | 287 policy::PolicyDomain domain) { |
281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
282 | 289 |
283 if (domain != policy::POLICY_DOMAIN_EXTENSIONS) | 290 if (domain != policy::POLICY_DOMAIN_EXTENSIONS) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, | 328 base::Bind(&ManagedValueStoreCache::UpdatePolicyOnFILE, |
322 base::Unretained(this), | 329 base::Unretained(this), |
323 ns.component_id, | 330 ns.component_id, |
324 base::Passed(current.DeepCopy()))); | 331 base::Passed(current.DeepCopy()))); |
325 } | 332 } |
326 | 333 |
327 void ManagedValueStoreCache::UpdatePolicyOnFILE( | 334 void ManagedValueStoreCache::UpdatePolicyOnFILE( |
328 const std::string& extension_id, | 335 const std::string& extension_id, |
329 scoped_ptr<policy::PolicyMap> current_policy) { | 336 scoped_ptr<policy::PolicyMap> current_policy) { |
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 338 |
| 339 if (!HasStore(extension_id) && current_policy->empty()) { |
| 340 // Don't create the store now if there are no policies configured for this |
| 341 // extension. If the extension uses the storage.managed API then the store |
| 342 // will be created at RunWithValueStoreForExtension(). |
| 343 return; |
| 344 } |
| 345 |
331 GetStoreFor(extension_id)->SetCurrentPolicy(*current_policy); | 346 GetStoreFor(extension_id)->SetCurrentPolicy(*current_policy); |
332 } | 347 } |
333 | 348 |
334 PolicyValueStore* ManagedValueStoreCache::GetStoreFor( | 349 PolicyValueStore* ManagedValueStoreCache::GetStoreFor( |
335 const std::string& extension_id) { | 350 const std::string& extension_id) { |
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
337 | 352 |
338 PolicyValueStoreMap::iterator it = store_map_.find(extension_id); | 353 PolicyValueStoreMap::iterator it = store_map_.find(extension_id); |
339 if (it != store_map_.end()) | 354 if (it != store_map_.end()) |
340 return it->second.get(); | 355 return it->second.get(); |
341 | 356 |
342 // Create the store now, and serve the cached policy until the PolicyService | 357 // Create the store now, and serve the cached policy until the PolicyService |
343 // sends updated values. | 358 // sends updated values. |
344 PolicyValueStore* store = new PolicyValueStore( | 359 PolicyValueStore* store = new PolicyValueStore( |
345 extension_id, | 360 extension_id, |
346 observers_, | 361 observers_, |
347 make_scoped_ptr(storage_factory_->Create(base_path_, extension_id))); | 362 make_scoped_ptr(storage_factory_->Create(base_path_, extension_id))); |
348 store_map_[extension_id] = make_linked_ptr(store); | 363 store_map_[extension_id] = make_linked_ptr(store); |
349 | 364 |
350 return store; | 365 return store; |
351 } | 366 } |
352 | 367 |
| 368 bool ManagedValueStoreCache::HasStore(const std::string& extension_id) const { |
| 369 // TODO(joaodasilva): move this check to a ValueStore method. |
| 370 return base::DirectoryExists(base_path_.AppendASCII(extension_id)); |
| 371 } |
| 372 |
353 } // namespace extensions | 373 } // namespace extensions |
OLD | NEW |