EME test page application.
[chromium-blink-merge.git] / chrome / browser / extensions / state_store.cc
blobfa1fd254e727da4048dc9206a226d82e67ca5681
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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/state_store.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "content/public/browser/notification_service.h"
11 #include "content/public/browser/notification_types.h"
12 #include "extensions/common/extension.h"
14 namespace {
16 // Delay, in seconds, before we should open the State Store database. We
17 // defer it to avoid slowing down startup. See http://crbug.com/161848
18 const int kInitDelaySeconds = 1;
20 std::string GetFullKey(const std::string& extension_id,
21 const std::string& key) {
22 return extension_id + "." + key;
25 } // namespace
27 namespace extensions {
29 // Helper class to delay tasks until we're ready to start executing them.
30 class StateStore::DelayedTaskQueue {
31 public:
32 DelayedTaskQueue() : ready_(false) {}
33 ~DelayedTaskQueue() {}
35 // Queues up a task for invoking once we're ready. Invokes immediately if
36 // we're already ready.
37 void InvokeWhenReady(base::Closure task);
39 // Marks us ready, and invokes all pending tasks.
40 void SetReady();
42 // Return whether or not the DelayedTaskQueue is |ready_|.
43 bool ready() const { return ready_; }
45 private:
46 bool ready_;
47 std::vector<base::Closure> pending_tasks_;
50 void StateStore::DelayedTaskQueue::InvokeWhenReady(base::Closure task) {
51 if (ready_) {
52 task.Run();
53 } else {
54 pending_tasks_.push_back(task);
58 void StateStore::DelayedTaskQueue::SetReady() {
59 ready_ = true;
61 for (size_t i = 0; i < pending_tasks_.size(); ++i)
62 pending_tasks_[i].Run();
63 pending_tasks_.clear();
66 StateStore::StateStore(Profile* profile,
67 const base::FilePath& db_path,
68 bool deferred_load)
69 : db_path_(db_path), task_queue_(new DelayedTaskQueue()) {
70 registrar_.Add(this,
71 chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
72 content::Source<Profile>(profile));
73 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
74 content::Source<Profile>(profile));
76 if (deferred_load) {
77 // Don't Init until the first page is loaded or the session restored.
78 registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
79 content::NotificationService::
80 AllBrowserContextsAndSources());
81 registrar_.Add(this, chrome::NOTIFICATION_SESSION_RESTORE_DONE,
82 content::NotificationService::
83 AllBrowserContextsAndSources());
84 } else {
85 Init();
89 StateStore::StateStore(Profile* profile, scoped_ptr<ValueStore> value_store)
90 : store_(value_store.Pass()), task_queue_(new DelayedTaskQueue()) {
91 registrar_.Add(this,
92 chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
93 content::Source<Profile>(profile));
94 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
95 content::Source<Profile>(profile));
97 // This constructor is for testing. No need to delay Init.
98 Init();
101 StateStore::~StateStore() {
104 void StateStore::RegisterKey(const std::string& key) {
105 registered_keys_.insert(key);
108 void StateStore::GetExtensionValue(const std::string& extension_id,
109 const std::string& key,
110 ReadCallback callback) {
111 task_queue_->InvokeWhenReady(
112 base::Bind(&ValueStoreFrontend::Get, base::Unretained(&store_),
113 GetFullKey(extension_id, key), callback));
116 void StateStore::SetExtensionValue(
117 const std::string& extension_id,
118 const std::string& key,
119 scoped_ptr<base::Value> value) {
120 task_queue_->InvokeWhenReady(
121 base::Bind(&ValueStoreFrontend::Set, base::Unretained(&store_),
122 GetFullKey(extension_id, key), base::Passed(&value)));
125 void StateStore::RemoveExtensionValue(const std::string& extension_id,
126 const std::string& key) {
127 task_queue_->InvokeWhenReady(
128 base::Bind(&ValueStoreFrontend::Remove, base::Unretained(&store_),
129 GetFullKey(extension_id, key)));
132 bool StateStore::IsInitialized() const { return task_queue_->ready(); }
134 void StateStore::Observe(int type,
135 const content::NotificationSource& source,
136 const content::NotificationDetails& details) {
137 switch (type) {
138 case chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED:
139 RemoveKeysForExtension(
140 content::Details<const InstalledExtensionInfo>(details)->extension->
141 id());
142 break;
143 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
144 RemoveKeysForExtension(
145 content::Details<const Extension>(details)->id());
146 break;
147 case chrome::NOTIFICATION_SESSION_RESTORE_DONE:
148 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME:
149 registrar_.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
150 content::NotificationService::AllSources());
151 registrar_.Remove(this, chrome::NOTIFICATION_SESSION_RESTORE_DONE,
152 content::NotificationService::AllSources());
153 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
154 base::Bind(&StateStore::Init, AsWeakPtr()),
155 base::TimeDelta::FromSeconds(kInitDelaySeconds));
156 break;
157 default:
158 NOTREACHED();
159 return;
163 void StateStore::Init() {
164 if (!db_path_.empty())
165 store_.Init(db_path_);
166 task_queue_->SetReady();
169 void StateStore::RemoveKeysForExtension(const std::string& extension_id) {
170 for (std::set<std::string>::iterator key = registered_keys_.begin();
171 key != registered_keys_.end(); ++key) {
172 task_queue_->InvokeWhenReady(
173 base::Bind(&ValueStoreFrontend::Remove, base::Unretained(&store_),
174 GetFullKey(extension_id, *key)));
178 } // namespace extensions