Chromium Code Reviews| Index: extensions/browser/api/lock_screen_data/item_storage.h |
| diff --git a/extensions/browser/api/lock_screen_data/item_storage.h b/extensions/browser/api/lock_screen_data/item_storage.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a2a34a000633ef6a3da6575e4ada26480ee562ce |
| --- /dev/null |
| +++ b/extensions/browser/api/lock_screen_data/item_storage.h |
| @@ -0,0 +1,177 @@ |
| +// Copyright 2017 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 EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_ITEM_STORAGE_H_ |
| +#define EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_ITEM_STORAGE_H_ |
| + |
| +#include <map> |
| +#include <memory> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/callback.h" |
| +#include "base/files/file_path.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/scoped_observer.h" |
| +#include "base/sequenced_task_runner.h" |
| +#include "extensions/browser/api/lock_screen_data/data_item.h" |
| +#include "extensions/browser/extension_registry_observer.h" |
| + |
| +class PrefRegistrySimple; |
| +class PrefService; |
| + |
| +namespace base { |
| +class Value; |
| +} |
| + |
| +namespace content { |
| +class BrowserContext; |
| +} |
| + |
| +namespace extensions { |
| + |
| +class Extension; |
| +class ExtensionRegistry; |
| + |
| +namespace lock_screen_data { |
| + |
| +class DataItem; |
| +enum class OperationResult; |
| + |
| +// Keeps track of lock screen data items created by extensions. |
| +// Note only single instance is allowed per process - once created, the instance |
| +// can be retrieved using ItemStorage::Get(). |
| +class ItemStorage : public ExtensionRegistryObserver { |
| + public: |
| + using WriteCallback = DataItem::WriteCallback; |
| + using ReadCallback = DataItem::ReadCallback; |
| + |
| + static void RegisterLocalState(PrefRegistrySimple* registry); |
| + |
| + // Gets the global ItemStorage instance. |
| + // |context| - Context from which the item storage is needed, if the context |
| + // is not allowed to use ItemStorage, this will return null. |
| + // ItemStorage can be only used from: |
| + // * lock screen browser context while session state is set to locked |
| + // * from the browser process passed to the ItemStorage ctor when the |
|
rkc
2017/06/22 18:35:48
Should ItemStorage be context keyed? What happens
tbarzic
2017/06/26 22:21:42
It will be supported only for the primary user.
|
| + // session state is set to unlocked. |
| + static ItemStorage* Get(content::BrowserContext* context); |
| + |
| + // Creates a ItemStorage instance. Note that only one ItemStorage can be |
| + // present at a time - the constructor will set a global reference to the |
| + // created object that can be retrieved using ItemStorage::Get (the reference |
| + // will be reset when the instance goes out of scoped, i.e. in ~ItemStorage). |
| + // |
| + // |context| - primary user context, only apps from that context should be |
| + // able to use the storage. |
| + // |local_state| - Local state preference - used to persist set of created |
| + // item metadata. |
| + // |crypto_key| - Symmetric key that should be used to encrypt data content |
| + // when it's persisted on the disk. |
| + // |storage_root| - Directory on the disk to which data item content should be |
| + // persisted. |
| + ItemStorage(content::BrowserContext* context, |
| + PrefService* local_state, |
| + const std::string& crypto_key, |
| + const base::FilePath& storage_root); |
| + ~ItemStorage() override; |
| + |
| + using ItemFactoryCallback = |
| + base::Callback<std::unique_ptr<DataItem>(const std::string& id)>; |
| + static void SetItemFactoryForTesting(ItemFactoryCallback* callback); |
| + |
| + // Updates the ItemStorage's view of whether the user session is locked. |
| + void SetSessionLocked(bool session_locked); |
| + |
| + // Creates a new data item for the extension. |
| + const DataItem* CreateItem(const std::string& extension_id); |
| + |
| + // Returns all existing data items associated with the extension. |
| + std::vector<const DataItem*> GetAllForExtension( |
| + const std::string& extension_id); |
| + |
| + // Updates the content of the item identified by |item_id| that is associated |
| + // with the provided extension. |
| + OperationResult SetItemContent(const std::string& extension_id, |
|
rkc
2017/06/22 18:35:48
Same comment as on the DataItem class. Can we avoi
tbarzic
2017/06/26 22:21:42
Done.
|
| + const std::string& item_id, |
| + const std::vector<char>& data, |
| + const WriteCallback& callback); |
| + |
| + // Retrieves the content of the item identified by |item_id| that is |
| + // associated with the provided extension. |
| + OperationResult GetItemContent(const std::string& extension_id, |
| + const std::string& item_id, |
| + const ReadCallback& callback); |
| + |
| + // Deletes the data item associated with the extension. |
| + OperationResult DeleteItem(const std::string& extension_id, |
| + const std::string& item_id); |
| + |
| + // extensions::ExtensionRegistryObserver: |
| + void OnExtensionUninstalled(content::BrowserContext* browser_context, |
| + const Extension* extension, |
| + UninstallReason reason) override; |
| + |
| + // Exposed so test code can ensure that all tasks on the task runner are run |
| + // before testing an expectation. |
| + scoped_refptr<base::SequencedTaskRunner> task_runner_for_testing() { |
| + return task_runner_; |
| + } |
| + |
| + private: |
| + // Maps a data item ID to the data item instance. |
| + using DataItemMap = std::map<std::string, std::unique_ptr<DataItem>>; |
|
rkc
2017/06/22 18:35:48
would using unordered_map here and below be better
tbarzic
2017/06/26 22:21:42
hm, I'm not sure. it might.
|
| + // Maps an extension ID to data items associated with the extension. |
| + using ExtensionDataItemMap = std::map<std::string, DataItemMap>; |
| + |
| + // The session state as seen by the ItemStorage. |
| + enum class SessionLockedState { kUnknown, kLocked, kNotLocked }; |
| + |
| + // Gets the key in lock screen data preferences for the item. |
| + std::string GetDataItemPrefKey(const std::string& extension_id, |
| + const std::string& item_id); |
| + |
| + // Whether the context is allowed to use ItemStorage. |
| + // Result depends on the current ItemStorage state - see ItemStorage::Get. |
| + bool IsContextAllowed(content::BrowserContext* context); |
| + |
| + // Finds a data item associated with the extension. |
| + DataItem* FindItem(const std::string& extension_id, |
| + const std::string& item_id); |
| + |
| + // Clears all data items associated with the extension. |
| + void ClearDataForExtension(const std::string& extension_id); |
| + |
| + // Used on startup to load extension -> data item mapping from local state |
| + // prefs. |
| + void ReloadDataItems(); |
| + bool LoadDataItemsForExtension(const std::string& extension_id, |
| + const base::Value& extension_pref); |
| + |
| + content::BrowserContext* context_; |
| + |
| + // The user associated with the primary profile. |
| + const std::string user_id_; |
| + const std::string crypto_key_; |
| + PrefService* local_state_; |
| + const base::FilePath storage_root_; |
| + |
| + SessionLockedState session_locked_state_ = SessionLockedState::kUnknown; |
| + |
| + ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| + extension_registry_observer_; |
| + |
| + // Mapping containing all known data items for extensions. |
| + ExtensionDataItemMap data_items_; |
| + |
| + scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ItemStorage); |
| +}; |
| + |
| +} // namespace lock_screen_data |
| +} // namespace extensions |
| + |
| +#endif // EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_ITEM_STORAGE_H_ |