1 // Copyright 2017 The Chromium Embedded Framework Authors.
2 // Portions copyright 2014 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "libcef/browser/extensions/api/storage/sync_value_store_cache.h"
7
8 #include <stddef.h>
9
10 #include <limits>
11 #include <utility>
12
13 #include "components/value_store/value_store_factory.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "extensions/browser/api/storage/backend_task_runner.h"
16 #include "extensions/browser/api/storage/value_store_util.h"
17 #include "extensions/browser/api/storage/weak_unlimited_settings_storage.h"
18 #include "extensions/common/api/storage.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/permissions/permissions_data.h"
21
22 using content::BrowserThread;
23
24 namespace extensions {
25
26 namespace cef {
27
28 namespace {
29
30 // Returns the quota limit for local storage, taken from the schema in
31 // extensions/common/api/storage.json.
GetLocalQuotaLimits()32 SettingsStorageQuotaEnforcer::Limits GetLocalQuotaLimits() {
33 SettingsStorageQuotaEnforcer::Limits limits = {
34 static_cast<size_t>(api::storage::local::QUOTA_BYTES),
35 std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max()};
36 return limits;
37 }
38
39 } // namespace
40
SyncValueStoreCache(scoped_refptr<value_store::ValueStoreFactory> factory)41 SyncValueStoreCache::SyncValueStoreCache(
42 scoped_refptr<value_store::ValueStoreFactory> factory)
43 : storage_factory_(std::move(factory)), quota_(GetLocalQuotaLimits()) {
44 DCHECK_CURRENTLY_ON(BrowserThread::UI);
45 }
46
~SyncValueStoreCache()47 SyncValueStoreCache::~SyncValueStoreCache() {
48 DCHECK(IsOnBackendSequence());
49 }
50
RunWithValueStoreForExtension(StorageCallback callback,scoped_refptr<const Extension> extension)51 void SyncValueStoreCache::RunWithValueStoreForExtension(
52 StorageCallback callback,
53 scoped_refptr<const Extension> extension) {
54 DCHECK(IsOnBackendSequence());
55
56 value_store::ValueStore* storage = GetStorage(extension.get());
57
58 // A neat way to implement unlimited storage; if the extension has the
59 // unlimited storage permission, force through all calls to Set().
60 if (extension->permissions_data()->HasAPIPermission(
61 mojom::APIPermissionID::kUnlimitedStorage)) {
62 WeakUnlimitedSettingsStorage unlimited_storage(storage);
63 std::move(callback).Run(&unlimited_storage);
64 } else {
65 std::move(callback).Run(storage);
66 }
67 }
68
DeleteStorageSoon(const std::string & extension_id)69 void SyncValueStoreCache::DeleteStorageSoon(const std::string& extension_id) {
70 DCHECK(IsOnBackendSequence());
71 storage_map_.erase(extension_id);
72
73 value_store_util::DeleteValueStore(settings_namespace::SYNC,
74 value_store_util::ModelType::APP,
75 extension_id, storage_factory_);
76
77 value_store_util::DeleteValueStore(settings_namespace::SYNC,
78 value_store_util::ModelType::EXTENSION,
79 extension_id, storage_factory_);
80 }
81
GetStorage(const Extension * extension)82 value_store::ValueStore* SyncValueStoreCache::GetStorage(
83 const Extension* extension) {
84 auto iter = storage_map_.find(extension->id());
85 if (iter != storage_map_.end())
86 return iter->second.get();
87
88 value_store_util::ModelType model_type =
89 extension->is_app() ? value_store_util::ModelType::APP
90 : value_store_util::ModelType::EXTENSION;
91 std::unique_ptr<value_store::ValueStore> store =
92 value_store_util::CreateSettingsStore(settings_namespace::LOCAL,
93 model_type, extension->id(),
94 storage_factory_);
95 std::unique_ptr<SettingsStorageQuotaEnforcer> storage(
96 new SettingsStorageQuotaEnforcer(quota_, std::move(store)));
97 DCHECK(storage.get());
98
99 value_store::ValueStore* storage_ptr = storage.get();
100 storage_map_[extension->id()] = std::move(storage);
101 return storage_ptr;
102 }
103 } // namespace cef
104 } // namespace extensions
105