1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_API_STORAGE_STORAGE_FRONTEND_H_
#define EXTENSIONS_BROWSER_API_STORAGE_STORAGE_FRONTEND_H_
#include <map>
#include <memory>
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "components/value_store/value_store.h"
#include "extensions/browser/api/storage/session_storage_manager.h"
#include "extensions/browser/api/storage/settings_namespace.h"
#include "extensions/browser/api/storage/settings_observer.h"
#include "extensions/browser/api/storage/value_store_cache.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/common/api/storage.h"
#include "extensions/common/extension_id.h"
namespace content {
class BrowserContext;
}
namespace value_store {
class ValueStoreFactory;
}
namespace extensions {
// The component of the Storage API which runs on the UI thread.
class StorageFrontend : public BrowserContextKeyedAPI {
public:
struct ResultStatus {
ResultStatus();
ResultStatus(const ResultStatus&);
~ResultStatus();
bool success = true;
std::optional<std::string> error;
};
struct GetKeysResult {
GetKeysResult();
GetKeysResult(const GetKeysResult&) = delete;
GetKeysResult(GetKeysResult&& other);
~GetKeysResult();
ResultStatus status;
std::optional<base::Value::List> data;
};
struct GetResult {
GetResult();
GetResult(const GetResult&) = delete;
GetResult(GetResult&& other);
~GetResult();
ResultStatus status;
std::optional<base::Value::Dict> data;
};
// Returns the current instance for `context`.
static StorageFrontend* Get(content::BrowserContext* context);
// Creates with a specific `storage_factory`.
static std::unique_ptr<StorageFrontend> CreateForTesting(
scoped_refptr<value_store::ValueStoreFactory> storage_factory,
content::BrowserContext* context);
explicit StorageFrontend(content::BrowserContext* context);
StorageFrontend(const StorageFrontend&) = delete;
StorageFrontend& operator=(const StorageFrontend&) = delete;
// Public so tests can create and delete their own instances.
~StorageFrontend() override;
// Returns the value store cache for `settings_namespace`.
ValueStoreCache* GetValueStoreCache(
settings_namespace::Namespace settings_namespace) const;
// Returns true if `settings_namespace` is a valid namespace.
bool IsStorageEnabled(settings_namespace::Namespace settings_namespace) const;
// Runs `callback` with the storage area of the given `settings_namespace`
// for the `extension`.
void RunWithStorage(scoped_refptr<const Extension> extension,
settings_namespace::Namespace settings_namespace,
ValueStoreCache::StorageCallback callback);
// Deletes the settings for the given `extension_id` and synchronously invokes
// `done_callback` once the settings are deleted.
void DeleteStorageSoon(const ExtensionId& extension_id,
base::OnceClosure done_callback);
// For a given `extension` and `storage_area`, retrieves a map of key value
// pairs from storage and fires `callback` with the result. If `keys` is
// specified, only the specified keys are retrieved. Otherwise, all data is
// returned.
void GetValues(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
std::optional<std::vector<std::string>> keys,
base::OnceCallback<void(GetResult)> callback);
// For a given `extension` and `storage_area`, retrieves a list of keys and
// fires `callback` with the result.
void GetKeys(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
base::OnceCallback<void(GetKeysResult)> callback);
// For a given `extension` and `storage_area`, determines the number of bytes
// in use and fires `callback` with the result. If `keys` is specified, the
// result is based only on keys contained within the vector. Otherwise, all
// keys are included.
void GetBytesInUse(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
std::optional<std::vector<std::string>> keys,
base::OnceCallback<void(size_t)> callback);
// For a given `extension` and `storage_area`, sets the values specified by
// `values` in storage and fires `callback`.
void Set(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
base::Value::Dict values,
base::OnceCallback<void(ResultStatus)> callback);
// For a given `extension` and `storage_area`, removes the items specified by
// `keys` from storage and fires `callback`.
void Remove(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
const std::vector<std::string>& keys,
base::OnceCallback<void(ResultStatus)> callback);
// For a given `extension` and `storage_area`, clears the storage and fires
// `callback`.
void Clear(scoped_refptr<const Extension> extension,
StorageAreaNamespace storage_area,
base::OnceCallback<void(ResultStatus)> callback);
// Gets the Settings change callback.
SettingsChangedCallback GetObserver();
void SetCacheForTesting(settings_namespace::Namespace settings_namespace,
std::unique_ptr<ValueStoreCache> cache);
void DisableStorageForTesting(
settings_namespace::Namespace settings_namespace);
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<StorageFrontend>* GetFactoryInstance();
static const char* service_name();
static const bool kServiceRedirectedInIncognito = true;
static const bool kServiceIsNULLWhileTesting = true;
private:
friend class BrowserContextKeyedAPIFactory<StorageFrontend>;
typedef std::map<settings_namespace::Namespace,
raw_ptr<ValueStoreCache, CtnExperimental>>
CacheMap;
// Constructor for tests.
StorageFrontend(scoped_refptr<value_store::ValueStoreFactory> storage_factory,
content::BrowserContext* context);
void Init(scoped_refptr<value_store::ValueStoreFactory> storage_factory);
// Should be called on the UI thread after a read has been performed in
// `storage_area`. Fires `callback` with the keys from `result`.
void OnReadKeysFinished(base::OnceCallback<void(GetKeysResult)> callback,
value_store::ValueStore::ReadResult result);
// Should be called on the UI thread after a read has been performed in
// `storage_area`. Fires `callback` with the `result` from the read
// operation.
void OnReadFinished(const ExtensionId& extension_id,
StorageAreaNamespace storage_area,
base::OnceCallback<void(GetResult)> callback,
value_store::ValueStore::ReadResult result);
// Should be called on the UI thread after a write has been performed in
// `storage_area`. Fires events if any values were changed and then runs
// `callback` with the `result` from the write operation.
void OnWriteFinished(const ExtensionId& extension_id,
StorageAreaNamespace storage_area,
base::OnceCallback<void(ResultStatus)> callback,
value_store::ValueStore::WriteResult result);
// Called when storage with `storage_area` for `extension_id` is updated with
// `changes`. Must include `session_access_level` iff `storage_area` is
// session (other storage areas don't support access levels, see
// crbug.com/1508463).
void OnSettingsChanged(
const ExtensionId& extension_id,
StorageAreaNamespace storage_area,
std::optional<api::storage::AccessLevel> session_access_level,
base::Value changes);
// The (non-incognito) browser context this Frontend belongs to.
const raw_ptr<content::BrowserContext> browser_context_;
// Maps a known namespace to its corresponding ValueStoreCache. The caches
// are owned by this object.
CacheMap caches_;
base::WeakPtrFactory<StorageFrontend> weak_factory_{this};
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_STORAGE_STORAGE_FRONTEND_H_
|