OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/extensions/settings/settings_frontend.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/file_path.h" | |
12 #include "base/json/json_reader.h" | |
13 #include "chrome/browser/extensions/event_names.h" | |
14 #include "chrome/browser/extensions/event_router.h" | |
15 #include "chrome/browser/extensions/extension_service.h" | |
16 #include "chrome/browser/extensions/extension_system.h" | |
17 #include "chrome/browser/extensions/settings/leveldb_settings_storage_factory.h" | |
18 #include "chrome/browser/extensions/settings/settings_backend.h" | |
19 #include "chrome/browser/extensions/settings/sync_or_local_value_store_cache.h" | |
20 #include "chrome/browser/profiles/profile.h" | |
21 #include "chrome/common/extensions/api/storage.h" | |
22 #include "content/public/browser/browser_thread.h" | |
23 | |
24 #if defined(ENABLE_CONFIGURATION_POLICY) | |
25 #include "chrome/browser/extensions/settings/managed_value_store_cache.h" | |
26 #endif | |
27 | |
28 using content::BrowserThread; | |
29 | |
30 namespace extensions { | |
31 | |
32 namespace { | |
33 | |
34 // Settings change Observer which forwards changes on to the extension | |
35 // processes for |profile| and its incognito partner if it exists. | |
36 class DefaultObserver : public SettingsObserver { | |
37 public: | |
38 explicit DefaultObserver(Profile* profile) : profile_(profile) {} | |
39 | |
40 // SettingsObserver implementation. | |
41 virtual void OnSettingsChanged( | |
42 const std::string& extension_id, | |
43 settings_namespace::Namespace settings_namespace, | |
44 const std::string& change_json) OVERRIDE { | |
45 // TODO(gdk): This is a temporary hack while the refactoring for | |
46 // string-based event payloads is removed. http://crbug.com/136045 | |
47 scoped_ptr<ListValue> args(new ListValue()); | |
48 args->Append(base::JSONReader::Read(change_json)); | |
49 args->Append(Value::CreateStringValue(settings_namespace::ToString( | |
50 settings_namespace))); | |
51 scoped_ptr<Event> event(new Event( | |
52 event_names::kOnSettingsChanged, args.Pass())); | |
53 ExtensionSystem::Get(profile_)->event_router()-> | |
54 DispatchEventToExtension(extension_id, event.Pass()); | |
55 } | |
56 | |
57 private: | |
58 Profile* const profile_; | |
59 }; | |
60 | |
61 SettingsStorageQuotaEnforcer::Limits GetLocalLimits() { | |
62 SettingsStorageQuotaEnforcer::Limits limits = { | |
63 static_cast<size_t>(api::storage::local::QUOTA_BYTES), | |
64 std::numeric_limits<size_t>::max(), | |
65 std::numeric_limits<size_t>::max() | |
66 }; | |
67 return limits; | |
68 } | |
69 | |
70 SettingsStorageQuotaEnforcer::Limits GetSyncLimits() { | |
71 SettingsStorageQuotaEnforcer::Limits limits = { | |
72 static_cast<size_t>(api::storage::sync::QUOTA_BYTES), | |
73 static_cast<size_t>(api::storage::sync::QUOTA_BYTES_PER_ITEM), | |
74 static_cast<size_t>(api::storage::sync::MAX_ITEMS) | |
75 }; | |
76 return limits; | |
77 } | |
78 | |
79 } // namespace | |
80 | |
81 // static | |
82 SettingsFrontend* SettingsFrontend::Create(Profile* profile) { | |
83 return new SettingsFrontend(new LeveldbSettingsStorageFactory(), profile); | |
84 } | |
85 | |
86 // static | |
87 SettingsFrontend* SettingsFrontend::Create( | |
88 const scoped_refptr<SettingsStorageFactory>& storage_factory, | |
89 Profile* profile) { | |
90 return new SettingsFrontend(storage_factory, profile); | |
91 } | |
92 | |
93 SettingsFrontend::SettingsFrontend( | |
94 const scoped_refptr<SettingsStorageFactory>& factory, Profile* profile) | |
95 : local_quota_limit_(GetLocalLimits()), | |
96 sync_quota_limit_(GetSyncLimits()), | |
97 profile_(profile), | |
98 observers_(new SettingsObserverList()), | |
99 profile_observer_(new DefaultObserver(profile)) { | |
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
101 DCHECK(!profile->IsOffTheRecord()); | |
102 | |
103 observers_->AddObserver(profile_observer_.get()); | |
104 | |
105 const FilePath& profile_path = profile->GetPath(); | |
106 caches_[settings_namespace::LOCAL] = | |
107 new SyncOrLocalValueStoreCache( | |
108 settings_namespace::LOCAL, | |
109 factory, | |
110 local_quota_limit_, | |
111 observers_, | |
112 profile_path); | |
113 caches_[settings_namespace::SYNC] = | |
114 new SyncOrLocalValueStoreCache( | |
115 settings_namespace::SYNC, | |
116 factory, | |
117 sync_quota_limit_, | |
118 observers_, | |
119 profile_path); | |
120 | |
121 #if defined(ENABLE_CONFIGURATION_POLICY) | |
122 caches_[settings_namespace::MANAGED] = | |
123 new ManagedValueStoreCache( | |
124 profile->GetPolicyService(), | |
125 ExtensionSystem::Get(profile)->event_router(), | |
126 factory, | |
127 observers_, | |
128 profile_path); | |
129 #endif | |
130 } | |
131 | |
132 SettingsFrontend::~SettingsFrontend() { | |
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
134 observers_->RemoveObserver(profile_observer_.get()); | |
135 for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) { | |
136 ValueStoreCache* cache = it->second; | |
137 cache->ShutdownOnUI(); | |
138 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache); | |
139 } | |
140 } | |
141 | |
142 syncer::SyncableService* SettingsFrontend::GetBackendForSync( | |
143 syncer::ModelType type) const { | |
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
145 CacheMap::const_iterator it = caches_.find(settings_namespace::SYNC); | |
146 DCHECK(it != caches_.end()); | |
147 const SyncOrLocalValueStoreCache* sync_cache = | |
148 static_cast<const SyncOrLocalValueStoreCache*>(it->second); | |
149 switch (type) { | |
150 case syncer::APP_SETTINGS: | |
151 return sync_cache->GetAppBackend(); | |
152 case syncer::EXTENSION_SETTINGS: | |
153 return sync_cache->GetExtensionBackend(); | |
154 default: | |
155 NOTREACHED(); | |
156 return NULL; | |
157 } | |
158 } | |
159 | |
160 bool SettingsFrontend::IsStorageEnabled( | |
161 settings_namespace::Namespace settings_namespace) const { | |
162 return caches_.find(settings_namespace) != caches_.end(); | |
163 } | |
164 | |
165 void SettingsFrontend::RunWithStorage( | |
166 const std::string& extension_id, | |
167 settings_namespace::Namespace settings_namespace, | |
168 const ValueStoreCache::StorageCallback& callback) { | |
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
170 | |
171 ValueStoreCache* cache = caches_[settings_namespace]; | |
172 CHECK(cache); | |
173 | |
174 // The |extension| has already been referenced earlier in the stack, so it | |
175 // can't be gone here. | |
176 // TODO(kalman): change RunWithStorage() to take a | |
177 // scoped_refptr<const Extension> instead. | |
178 scoped_refptr<const Extension> extension = | |
179 extensions::ExtensionSystem::Get(profile_)->extension_service()-> | |
180 GetExtensionById(extension_id, true); | |
181 CHECK(extension); | |
182 | |
183 BrowserThread::PostTask( | |
184 BrowserThread::FILE, FROM_HERE, | |
185 base::Bind(&ValueStoreCache::RunWithValueStoreForExtension, | |
186 base::Unretained(cache), callback, extension)); | |
187 } | |
188 | |
189 void SettingsFrontend::DeleteStorageSoon( | |
190 const std::string& extension_id) { | |
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
192 for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) { | |
193 ValueStoreCache* cache = it->second; | |
194 BrowserThread::PostTask( | |
195 BrowserThread::FILE, FROM_HERE, | |
196 base::Bind(&ValueStoreCache::DeleteStorageSoon, | |
197 base::Unretained(cache), | |
198 extension_id)); | |
199 } | |
200 } | |
201 | |
202 scoped_refptr<SettingsObserverList> SettingsFrontend::GetObservers() { | |
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
204 return observers_; | |
205 } | |
206 | |
207 void SettingsFrontend::DisableStorageForTesting( | |
208 settings_namespace::Namespace settings_namespace) { | |
209 CacheMap::iterator it = caches_.find(settings_namespace); | |
210 if (it != caches_.end()) { | |
211 ValueStoreCache* cache = it->second; | |
212 cache->ShutdownOnUI(); | |
213 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache); | |
214 caches_.erase(it); | |
215 } | |
216 } | |
217 | |
218 } // namespace extensions | |
OLD | NEW |