1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/extensions/external_pref_cache_loader.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/singleton.h"
10 #include "base/observer_list.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/extensions/external_cache.h"
14 #include "content/public/browser/browser_thread.h"
20 // Directory where the extensions are cached.
21 const char kPreinstalledAppsCacheDir
[] = "/var/cache/external_cache";
23 // Singleton class that holds ExternalCache and dispatches cache update events
24 // to per-profile instances of ExternalPrefCacheLoader. This multiplexing
25 // is required for multi-profile case.
26 class ExternalCacheDispatcher
: public ExternalCache::Delegate
{
28 static ExternalCacheDispatcher
* GetInstance() {
29 return Singleton
<ExternalCacheDispatcher
>::get();
32 // Implementation of ExternalCache::Delegate:
33 virtual void OnExtensionListsUpdated(
34 const base::DictionaryValue
* prefs
) OVERRIDE
{
35 is_extensions_list_ready_
= true;
36 FOR_EACH_OBSERVER(ExternalPrefCacheLoader
, pref_loaders_
,
37 OnExtensionListsUpdated(prefs
));
40 void UpdateExtensionsList(scoped_ptr
<base::DictionaryValue
> prefs
) {
41 DCHECK(!is_extensions_list_ready_
);
42 external_cache_
.UpdateExtensionsList(prefs
.Pass());
45 // Return false if cache doesn't have list of extensions and it needs to
46 // be provided via UpdateExtensionsList.
47 bool RegisterExternalPrefCacheLoader(ExternalPrefCacheLoader
* observer
,
49 pref_loaders_
.AddObserver(observer
);
51 if (base_path_id_
== 0) {
52 // First ExternalPrefCacheLoader is registered.
53 base_path_id_
= base_path_id
;
56 CHECK_EQ(base_path_id_
, base_path_id
);
57 if (is_extensions_list_ready_
) {
58 // If list of extensions is not ready, |observer| will be notified later
59 // in OnExtensionListsUpdated.
60 observer
->OnExtensionListsUpdated(external_cache_
.cached_extensions());
66 void UnregisterExternalPrefCacheLoader(ExternalPrefCacheLoader
* observer
) {
67 pref_loaders_
.RemoveObserver(observer
);
71 friend struct DefaultSingletonTraits
<ExternalCacheDispatcher
>;
73 ExternalCacheDispatcher()
74 : external_cache_(kPreinstalledAppsCacheDir
,
75 g_browser_process
->system_request_context(), this, true),
77 is_extensions_list_ready_(false) {
80 ExternalCache external_cache_
;
81 ObserverList
<ExternalPrefCacheLoader
> pref_loaders_
;
83 bool is_extensions_list_ready_
;
85 DISALLOW_COPY_AND_ASSIGN(ExternalCacheDispatcher
);
90 ExternalPrefCacheLoader::ExternalPrefCacheLoader(int base_path_id
)
91 : ExternalPrefLoader(base_path_id
, ExternalPrefLoader::NONE
) {
94 ExternalPrefCacheLoader::~ExternalPrefCacheLoader() {
95 ExternalCacheDispatcher::GetInstance()->UnregisterExternalPrefCacheLoader(
99 void ExternalPrefCacheLoader::OnExtensionListsUpdated(
100 const base::DictionaryValue
* prefs
) {
101 prefs_
.reset(prefs
->DeepCopy());
102 ExternalPrefLoader::LoadFinished();
105 void ExternalPrefCacheLoader::StartLoading() {
106 if (!ExternalCacheDispatcher::GetInstance()->RegisterExternalPrefCacheLoader(
107 this, base_path_id_
)) {
108 // ExternalCacheDispatcher doesn't know list of extensions load it.
109 ExternalPrefLoader::StartLoading();
113 void ExternalPrefCacheLoader::LoadFinished() {
114 ExternalCacheDispatcher::GetInstance()->UpdateExtensionsList(prefs_
.Pass());
117 } // namespace chromeos