Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: chrome/browser/extensions/settings/settings_frontend.cc

Issue 9284013: Extension Storage API: expose storage quota information to extensions, via: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: with use-after-free fixed Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/settings/settings_frontend.h" 5 #include "chrome/browser/extensions/settings/settings_frontend.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/string_number_conversions.h"
9 #include "chrome/browser/extensions/extension_event_names.h" 10 #include "chrome/browser/extensions/extension_event_names.h"
10 #include "chrome/browser/extensions/extension_event_router.h" 11 #include "chrome/browser/extensions/extension_event_router.h"
11 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/settings/settings_backend.h" 13 #include "chrome/browser/extensions/settings/settings_backend.h"
13 #include "chrome/browser/extensions/settings/settings_namespace.h" 14 #include "chrome/browser/extensions/settings/settings_namespace.h"
14 #include "chrome/browser/extensions/settings/settings_leveldb_storage.h" 15 #include "chrome/browser/extensions/settings/settings_leveldb_storage.h"
15 #include "chrome/browser/extensions/settings/weak_unlimited_settings_storage.h" 16 #include "chrome/browser/extensions/settings/weak_unlimited_settings_storage.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/extensions/api/extension_api.h"
17 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_service.h" 20 #include "content/public/browser/notification_service.h"
19 21
20 using content::BrowserThread; 22 using content::BrowserThread;
21 23
22 namespace extensions { 24 namespace extensions {
23 25
24 namespace { 26 namespace {
25 27
26 const SettingsStorageQuotaEnforcer::Limits kSyncQuota = {
27 // 100K should be enough for simple use, but this can be increased as demand
28 // increases.
29 100 * 1024,
30
31 // Sync supports 5k per settings, so be a bit more restrictive than that.
32 2048,
33
34 // Keep low for sync.
35 512
36 };
37
38 const SettingsStorageQuotaEnforcer::Limits kLocalQuota = {
39 // Same as localStorage (5MB).
40 5 * 1000 * 1024,
41
42 // No need to be restrictive per key here.
43 UINT_MAX,
44
45 // Ditto.
46 UINT_MAX
47 };
48
49 // Settings change Observer which forwards changes on to the extension 28 // Settings change Observer which forwards changes on to the extension
50 // processes for |profile| and its incognito partner if it exists. 29 // processes for |profile| and its incognito partner if it exists.
51 class DefaultObserver : public SettingsObserver { 30 class DefaultObserver : public SettingsObserver {
52 public: 31 public:
53 explicit DefaultObserver(Profile* profile) : profile_(profile) {} 32 explicit DefaultObserver(Profile* profile) : profile_(profile) {}
54 33
55 // SettingsObserver implementation. 34 // SettingsObserver implementation.
56 virtual void OnSettingsChanged( 35 virtual void OnSettingsChanged(
57 const std::string& extension_id, 36 const std::string& extension_id,
58 settings_namespace::Namespace settings_namespace, 37 settings_namespace::Namespace settings_namespace,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 void CallbackWithUnlimitedStorage( 81 void CallbackWithUnlimitedStorage(
103 const std::string& extension_id, 82 const std::string& extension_id,
104 const SettingsFrontend::StorageCallback& callback, 83 const SettingsFrontend::StorageCallback& callback,
105 SettingsBackend* backend) { 84 SettingsBackend* backend) {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
107 WeakUnlimitedSettingsStorage unlimited_storage( 86 WeakUnlimitedSettingsStorage unlimited_storage(
108 backend->GetStorage(extension_id)); 87 backend->GetStorage(extension_id));
109 callback.Run(&unlimited_storage); 88 callback.Run(&unlimited_storage);
110 } 89 }
111 90
91 // Returns the integer at |path| in |dict| as a size_t, or a default value if
92 // there's nothing found at that path.
93 size_t GetStringAsInteger(
94 const DictionaryValue& dict, const std::string& path, size_t default_size) {
95 std::string as_string;
96 if (!dict.GetString(path, &as_string))
97 return default_size;
98 size_t as_integer = default_size;
99 CHECK(base::StringToSizeT(as_string, &as_integer));
100 return as_integer;
101 }
102
103 // Constructs a |Limits| configuration by looking up the QUOTA_BYTES,
104 // QUOTA_BYTES_PER_ITEM, and MAX_ITEMS properties of a storage area defined
105 // in chrome/common/extensions/api/storage.json (via ExtensionAPI).
106 SettingsStorageQuotaEnforcer::Limits GetLimitsFromExtensionAPI(
107 const std::string& storage_area_id) {
108 const DictionaryValue* storage_schema =
109 ExtensionAPI::GetInstance()->GetSchema("storage");
110 CHECK(storage_schema);
111
112 DictionaryValue* properties = NULL;
113 storage_schema->GetDictionary(
114 "properties." + storage_area_id + ".properties", &properties);
115 CHECK(properties);
116
117 SettingsStorageQuotaEnforcer::Limits limits = {
118 GetStringAsInteger(*properties, "QUOTA_BYTES.value", UINT_MAX),
119 GetStringAsInteger(*properties, "QUOTA_BYTES_PER_ITEM.value", UINT_MAX),
120 GetStringAsInteger(*properties, "MAX_ITEMS.value", UINT_MAX),
121 };
122 return limits;
123 }
124
112 } // namespace 125 } // namespace
113 126
114 // Ref-counted container for a SettingsBackend object. 127 // Ref-counted container for a SettingsBackend object.
115 class SettingsFrontend::BackendWrapper 128 class SettingsFrontend::BackendWrapper
116 : public base::RefCountedThreadSafe<BackendWrapper> { 129 : public base::RefCountedThreadSafe<BackendWrapper> {
117 public: 130 public:
118 // Creates a new BackendWrapper and initializes it on the FILE thread. 131 // Creates a new BackendWrapper and initializes it on the FILE thread.
119 static scoped_refptr<BackendWrapper> CreateAndInit( 132 static scoped_refptr<BackendWrapper> CreateAndInit(
120 const scoped_refptr<SettingsStorageFactory>& factory, 133 const scoped_refptr<SettingsStorageFactory>& factory,
121 const SettingsStorageQuotaEnforcer::Limits& quota, 134 const SettingsStorageQuotaEnforcer::Limits& quota,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 } 194 }
182 195
183 void RunWithBackendOnFileThread(const BackendCallback& callback) { 196 void RunWithBackendOnFileThread(const BackendCallback& callback) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
185 DCHECK(backend_); 198 DCHECK(backend_);
186 callback.Run(backend_); 199 callback.Run(backend_);
187 } 200 }
188 201
189 // Only need these until |backend_| exists. 202 // Only need these until |backend_| exists.
190 scoped_refptr<SettingsStorageFactory> storage_factory_; 203 scoped_refptr<SettingsStorageFactory> storage_factory_;
191 const SettingsStorageQuotaEnforcer::Limits& quota_; 204 const SettingsStorageQuotaEnforcer::Limits quota_;
192 scoped_refptr<SettingsObserverList> observers_; 205 scoped_refptr<SettingsObserverList> observers_;
193 206
194 // Wrapped Backend. Used exclusively on the FILE thread, and is created on 207 // Wrapped Backend. Used exclusively on the FILE thread, and is created on
195 // the FILE thread in InitOnFileThread. 208 // the FILE thread in InitOnFileThread.
196 SettingsBackend* backend_; 209 SettingsBackend* backend_;
197 210
198 DISALLOW_COPY_AND_ASSIGN(BackendWrapper); 211 DISALLOW_COPY_AND_ASSIGN(BackendWrapper);
199 }; 212 };
200 213
201 // SettingsFrontend 214 // SettingsFrontend
202 215
203 // static 216 // static
204 SettingsFrontend* SettingsFrontend::Create(Profile* profile) { 217 SettingsFrontend* SettingsFrontend::Create(Profile* profile) {
205 return new SettingsFrontend(new SettingsLeveldbStorage::Factory(), profile); 218 return new SettingsFrontend(new SettingsLeveldbStorage::Factory(), profile);
206 } 219 }
207 220
208 // static 221 // static
209 SettingsFrontend* SettingsFrontend::Create( 222 SettingsFrontend* SettingsFrontend::Create(
210 const scoped_refptr<SettingsStorageFactory>& storage_factory, 223 const scoped_refptr<SettingsStorageFactory>& storage_factory,
211 Profile* profile) { 224 Profile* profile) {
212 return new SettingsFrontend(storage_factory, profile); 225 return new SettingsFrontend(storage_factory, profile);
213 } 226 }
214 227
215 SettingsFrontend::SettingsFrontend( 228 SettingsFrontend::SettingsFrontend(
216 const scoped_refptr<SettingsStorageFactory>& factory, Profile* profile) 229 const scoped_refptr<SettingsStorageFactory>& factory, Profile* profile)
217 : profile_(profile), 230 : local_quota_limit_(GetLimitsFromExtensionAPI("local")),
231 sync_quota_limit_(GetLimitsFromExtensionAPI("sync")),
232 profile_(profile),
218 observers_(new SettingsObserverList()), 233 observers_(new SettingsObserverList()),
219 profile_observer_(new DefaultObserver(profile)) { 234 profile_observer_(new DefaultObserver(profile)) {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
221 DCHECK(!profile->IsOffTheRecord()); 236 DCHECK(!profile->IsOffTheRecord());
222 237
223 observers_->AddObserver(profile_observer_.get()); 238 observers_->AddObserver(profile_observer_.get());
224 239
225 const FilePath& profile_path = profile->GetPath(); 240 const FilePath& profile_path = profile->GetPath();
226 backends_[settings_namespace::LOCAL].app = 241 backends_[settings_namespace::LOCAL].app =
227 BackendWrapper::CreateAndInit( 242 BackendWrapper::CreateAndInit(
228 factory, 243 factory,
229 kLocalQuota, 244 local_quota_limit_,
230 observers_, 245 observers_,
231 profile_path.AppendASCII( 246 profile_path.AppendASCII(
232 ExtensionService::kLocalAppSettingsDirectoryName)); 247 ExtensionService::kLocalAppSettingsDirectoryName));
233 backends_[settings_namespace::LOCAL].extension = 248 backends_[settings_namespace::LOCAL].extension =
234 BackendWrapper::CreateAndInit( 249 BackendWrapper::CreateAndInit(
235 factory, 250 factory,
236 kLocalQuota, 251 local_quota_limit_,
237 observers_, 252 observers_,
238 profile_path.AppendASCII( 253 profile_path.AppendASCII(
239 ExtensionService::kLocalExtensionSettingsDirectoryName)); 254 ExtensionService::kLocalExtensionSettingsDirectoryName));
240 backends_[settings_namespace::SYNC].app = 255 backends_[settings_namespace::SYNC].app =
241 BackendWrapper::CreateAndInit( 256 BackendWrapper::CreateAndInit(
242 factory, 257 factory,
243 kSyncQuota, 258 sync_quota_limit_,
244 observers_, 259 observers_,
245 profile_path.AppendASCII( 260 profile_path.AppendASCII(
246 ExtensionService::kSyncAppSettingsDirectoryName)); 261 ExtensionService::kSyncAppSettingsDirectoryName));
247 backends_[settings_namespace::SYNC].extension = 262 backends_[settings_namespace::SYNC].extension =
248 BackendWrapper::CreateAndInit( 263 BackendWrapper::CreateAndInit(
249 factory, 264 factory,
250 kSyncQuota, 265 sync_quota_limit_,
251 observers_, 266 observers_,
252 profile_path.AppendASCII( 267 profile_path.AppendASCII(
253 ExtensionService::kSyncExtensionSettingsDirectoryName)); 268 ExtensionService::kSyncExtensionSettingsDirectoryName));
254 } 269 }
255 270
256 SettingsFrontend::~SettingsFrontend() { 271 SettingsFrontend::~SettingsFrontend() {
257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
258 observers_->RemoveObserver(profile_observer_.get()); 273 observers_->RemoveObserver(profile_observer_.get());
259 } 274 }
260 275
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
334 return observers_; 349 return observers_;
335 } 350 }
336 351
337 // BackendWrappers 352 // BackendWrappers
338 353
339 SettingsFrontend::BackendWrappers::BackendWrappers() {} 354 SettingsFrontend::BackendWrappers::BackendWrappers() {}
340 SettingsFrontend::BackendWrappers::~BackendWrappers() {} 355 SettingsFrontend::BackendWrappers::~BackendWrappers() {}
341 356
342 } // namespace extensions 357 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/settings/settings_frontend.h ('k') | chrome/browser/extensions/settings/settings_leveldb_storage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698