Make default apps cache multiprofile friendly
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / external_pref_cache_loader.cc
blob74811ccebd6eca132eb8fb6579b6e652167478ab
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"
7 #include "base/bind.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"
16 namespace chromeos {
18 namespace {
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 {
27 public:
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,
48 int base_path_id) {
49 pref_loaders_.AddObserver(observer);
51 if (base_path_id_ == 0) {
52 // First ExternalPrefCacheLoader is registered.
53 base_path_id_ = base_path_id;
54 return false;
55 } else {
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());
62 return true;
66 void UnregisterExternalPrefCacheLoader(ExternalPrefCacheLoader* observer) {
67 pref_loaders_.RemoveObserver(observer);
70 private:
71 friend struct DefaultSingletonTraits<ExternalCacheDispatcher>;
73 ExternalCacheDispatcher()
74 : external_cache_(kPreinstalledAppsCacheDir,
75 g_browser_process->system_request_context(), this, true),
76 base_path_id_(0),
77 is_extensions_list_ready_(false) {
80 ExternalCache external_cache_;
81 ObserverList<ExternalPrefCacheLoader> pref_loaders_;
82 int base_path_id_;
83 bool is_extensions_list_ready_;
85 DISALLOW_COPY_AND_ASSIGN(ExternalCacheDispatcher);
88 } // namespace
90 ExternalPrefCacheLoader::ExternalPrefCacheLoader(int base_path_id)
91 : ExternalPrefLoader(base_path_id, ExternalPrefLoader::NONE) {
94 ExternalPrefCacheLoader::~ExternalPrefCacheLoader() {
95 ExternalCacheDispatcher::GetInstance()->UnregisterExternalPrefCacheLoader(
96 this);
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