This source file includes following definitions.
- GetFullKey
- DelayedTaskQueue
- DelayedTaskQueue
- ready
- InvokeWhenReady
- SetReady
- task_queue_
- task_queue_
- RegisterKey
- GetExtensionValue
- SetExtensionValue
- RemoveExtensionValue
- IsInitialized
- Observe
- Init
- RemoveKeysForExtension
#include "chrome/browser/extensions/state_store.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "extensions/common/extension.h"
namespace {
const int kInitDelaySeconds = 1;
std::string GetFullKey(const std::string& extension_id,
const std::string& key) {
return extension_id + "." + key;
}
}
namespace extensions {
class StateStore::DelayedTaskQueue {
public:
DelayedTaskQueue() : ready_(false) {}
~DelayedTaskQueue() {}
void InvokeWhenReady(base::Closure task);
void SetReady();
bool ready() const { return ready_; }
private:
bool ready_;
std::vector<base::Closure> pending_tasks_;
};
void StateStore::DelayedTaskQueue::InvokeWhenReady(base::Closure task) {
if (ready_) {
task.Run();
} else {
pending_tasks_.push_back(task);
}
}
void StateStore::DelayedTaskQueue::SetReady() {
ready_ = true;
for (size_t i = 0; i < pending_tasks_.size(); ++i)
pending_tasks_[i].Run();
pending_tasks_.clear();
}
StateStore::StateStore(Profile* profile,
const base::FilePath& db_path,
bool deferred_load)
: db_path_(db_path), task_queue_(new DelayedTaskQueue()) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<Profile>(profile));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile));
if (deferred_load) {
registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
content::NotificationService::
AllBrowserContextsAndSources());
registrar_.Add(this, chrome::NOTIFICATION_SESSION_RESTORE_DONE,
content::NotificationService::
AllBrowserContextsAndSources());
} else {
Init();
}
}
StateStore::StateStore(Profile* profile, scoped_ptr<ValueStore> value_store)
: store_(value_store.Pass()), task_queue_(new DelayedTaskQueue()) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<Profile>(profile));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile));
Init();
}
StateStore::~StateStore() {
}
void StateStore::RegisterKey(const std::string& key) {
registered_keys_.insert(key);
}
void StateStore::GetExtensionValue(const std::string& extension_id,
const std::string& key,
ReadCallback callback) {
task_queue_->InvokeWhenReady(
base::Bind(&ValueStoreFrontend::Get, base::Unretained(&store_),
GetFullKey(extension_id, key), callback));
}
void StateStore::SetExtensionValue(
const std::string& extension_id,
const std::string& key,
scoped_ptr<base::Value> value) {
task_queue_->InvokeWhenReady(
base::Bind(&ValueStoreFrontend::Set, base::Unretained(&store_),
GetFullKey(extension_id, key), base::Passed(&value)));
}
void StateStore::RemoveExtensionValue(const std::string& extension_id,
const std::string& key) {
task_queue_->InvokeWhenReady(
base::Bind(&ValueStoreFrontend::Remove, base::Unretained(&store_),
GetFullKey(extension_id, key)));
}
bool StateStore::IsInitialized() const { return task_queue_->ready(); }
void StateStore::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
case chrome::NOTIFICATION_EXTENSION_INSTALLED:
RemoveKeysForExtension(
content::Details<const InstalledExtensionInfo>(details)->extension->
id());
break;
case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
RemoveKeysForExtension(
content::Details<const Extension>(details)->id());
break;
case chrome::NOTIFICATION_SESSION_RESTORE_DONE:
case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME:
registrar_.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
content::NotificationService::AllSources());
registrar_.Remove(this, chrome::NOTIFICATION_SESSION_RESTORE_DONE,
content::NotificationService::AllSources());
base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
base::Bind(&StateStore::Init, AsWeakPtr()),
base::TimeDelta::FromSeconds(kInitDelaySeconds));
break;
default:
NOTREACHED();
return;
}
}
void StateStore::Init() {
if (!db_path_.empty())
store_.Init(db_path_);
task_queue_->SetReady();
}
void StateStore::RemoveKeysForExtension(const std::string& extension_id) {
for (std::set<std::string>::iterator key = registered_keys_.begin();
key != registered_keys_.end(); ++key) {
task_queue_->InvokeWhenReady(
base::Bind(&ValueStoreFrontend::Remove, base::Unretained(&store_),
GetFullKey(extension_id, *key)));
}
}
}