Add support for Chrome Storage Extension API (issue #1947)

- Supports chrome.storage.local and chrome.storage.sync
- chrome.storage.sync behaves identically to chrome.storage.local
This commit is contained in:
Ryan Shetley
2017-09-11 18:42:30 +00:00
committed by Marshall Greenblatt
parent a028976ac4
commit d8a602ed2f
15 changed files with 1159 additions and 5 deletions

View File

@ -0,0 +1,97 @@
// Copyright 2017 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/extensions/api/storage/sync_value_store_cache.h"
#include <stddef.h>
#include <limits>
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/weak_unlimited_settings_storage.h"
#include "extensions/browser/value_store/value_store_factory.h"
#include "extensions/common/api/storage.h"
#include "extensions/common/extension.h"
#include "extensions/common/permissions/permissions_data.h"
using content::BrowserThread;
namespace extensions {
namespace cef {
namespace {
// Returns the quota limit for local storage, taken from the schema in
// extensions/common/api/storage.json.
SettingsStorageQuotaEnforcer::Limits GetLocalQuotaLimits() {
SettingsStorageQuotaEnforcer::Limits limits = {
static_cast<size_t>(api::storage::local::QUOTA_BYTES),
std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max()};
return limits;
}
} // namespace
SyncValueStoreCache::SyncValueStoreCache(
const scoped_refptr<ValueStoreFactory>& factory)
: storage_factory_(factory), quota_(GetLocalQuotaLimits()) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
SyncValueStoreCache::~SyncValueStoreCache() {
DCHECK(IsOnBackendSequence());
}
void SyncValueStoreCache::RunWithValueStoreForExtension(
const StorageCallback& callback,
scoped_refptr<const Extension> extension) {
DCHECK(IsOnBackendSequence());
ValueStore* storage = GetStorage(extension.get());
// A neat way to implement unlimited storage; if the extension has the
// unlimited storage permission, force through all calls to Set().
if (extension->permissions_data()->HasAPIPermission(
APIPermission::kUnlimitedStorage)) {
WeakUnlimitedSettingsStorage unlimited_storage(storage);
callback.Run(&unlimited_storage);
} else {
callback.Run(storage);
}
}
void SyncValueStoreCache::DeleteStorageSoon(const std::string& extension_id) {
DCHECK(IsOnBackendSequence());
storage_map_.erase(extension_id);
storage_factory_->DeleteSettings(settings_namespace::SYNC,
ValueStoreFactory::ModelType::APP,
extension_id);
storage_factory_->DeleteSettings(settings_namespace::SYNC,
ValueStoreFactory::ModelType::EXTENSION,
extension_id);
}
ValueStore* SyncValueStoreCache::GetStorage(const Extension* extension) {
StorageMap::iterator iter = storage_map_.find(extension->id());
if (iter != storage_map_.end())
return iter->second.get();
ValueStoreFactory::ModelType model_type =
extension->is_app() ? ValueStoreFactory::ModelType::APP
: ValueStoreFactory::ModelType::EXTENSION;
std::unique_ptr<ValueStore> store = storage_factory_->CreateSettingsStore(
settings_namespace::SYNC, model_type, extension->id());
std::unique_ptr<SettingsStorageQuotaEnforcer> storage(
new SettingsStorageQuotaEnforcer(quota_, std::move(store)));
DCHECK(storage.get());
ValueStore* storage_ptr = storage.get();
storage_map_[extension->id()] = std::move(storage);
return storage_ptr;
}
} // namespace cef
} // namespace extensions

View File

@ -0,0 +1,56 @@
// Copyright 2017 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_EXTENSIONS_API_STORAGE_SYNC_VALUE_STORE_CACHE_H_
#define CEF_LIBCEF_BROWSER_EXTENSIONS_API_STORAGE_SYNC_VALUE_STORE_CACHE_H_
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "extensions/browser/api/storage/settings_storage_quota_enforcer.h"
#include "extensions/browser/api/storage/value_store_cache.h"
namespace extensions {
class ValueStoreFactory;
namespace cef {
// Based on LocalValueStoreCache
// ValueStoreCache for the SYNC namespace. It owns a backend for apps and
// another for extensions. Each backend takes care of persistence.
class SyncValueStoreCache : public ValueStoreCache {
public:
explicit SyncValueStoreCache(const scoped_refptr<ValueStoreFactory>& factory);
~SyncValueStoreCache() override;
// ValueStoreCache implementation:
void RunWithValueStoreForExtension(
const StorageCallback& callback,
scoped_refptr<const Extension> extension) override;
void DeleteStorageSoon(const std::string& extension_id) override;
private:
using StorageMap = std::map<std::string, std::unique_ptr<ValueStore>>;
ValueStore* GetStorage(const Extension* extension);
// The Factory to use for creating new ValueStores.
const scoped_refptr<ValueStoreFactory> storage_factory_;
// Quota limits (see SettingsStorageQuotaEnforcer).
const SettingsStorageQuotaEnforcer::Limits quota_;
// The collection of ValueStores for local storage.
StorageMap storage_map_;
DISALLOW_COPY_AND_ASSIGN(SyncValueStoreCache);
};
} // namespace cef
} // namespace extensions
#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_API_STORAGE_SYNC_VALUE_STORE_CACHE_H_