This source file includes following definitions.
- AddObserver
- RemoveObserver
- ObserverCount
- OnStorageChange
- MaybeDispatchEvent
- ScheduleUpdateForObserver
- DispatchPendingEvent
- weak_factory_
- AddObserver
- RemoveObserver
- ContainsObservers
- NotifyUsageChange
- StartInitialization
- GotHostUsageAndQuota
- DispatchEvent
- AddObserver
- RemoveObserver
- RemoveObserverForFilter
- GetHostObservers
- NotifyUsageChange
- AddObserver
- RemoveObserver
- RemoveObserverForFilter
- GetStorageTypeObservers
- NotifyUsageChange
#include "webkit/browser/quota/storage_monitor.h"
#include <algorithm>
#include "base/stl_util.h"
#include "net/base/net_util.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/quota/quota_status_code.h"
namespace quota {
StorageObserverList::ObserverState::ObserverState()
: requires_update(false) {
}
StorageObserverList::StorageObserverList() {}
StorageObserverList::~StorageObserverList() {}
void StorageObserverList::AddObserver(
StorageObserver* observer, const StorageObserver::MonitorParams& params) {
ObserverState& observer_state = observers_[observer];
observer_state.origin = params.filter.origin;
observer_state.rate = params.rate;
}
void StorageObserverList::RemoveObserver(StorageObserver* observer) {
observers_.erase(observer);
}
int StorageObserverList::ObserverCount() const {
return observers_.size();
}
void StorageObserverList::OnStorageChange(const StorageObserver::Event& event) {
for (StorageObserverStateMap::iterator it = observers_.begin();
it != observers_.end(); ++it) {
it->second.requires_update = true;
}
MaybeDispatchEvent(event);
}
void StorageObserverList::MaybeDispatchEvent(
const StorageObserver::Event& event) {
notification_timer_.Stop();
base::TimeDelta min_delay = base::TimeDelta::Max();
bool all_observers_notified = true;
for (StorageObserverStateMap::iterator it = observers_.begin();
it != observers_.end(); ++it) {
if (!it->second.requires_update)
continue;
base::TimeTicks current_time = base::TimeTicks::Now();
base::TimeDelta delta = current_time - it->second.last_notification_time;
if (it->second.last_notification_time.is_null() ||
delta >= it->second.rate) {
it->second.requires_update = false;
it->second.last_notification_time = current_time;
if (it->second.origin == event.filter.origin) {
it->first->OnStorageEvent(event);
} else {
StorageObserver::Event dispatch_event(event);
dispatch_event.filter.origin = it->second.origin;
it->first->OnStorageEvent(dispatch_event);
}
} else {
all_observers_notified = false;
base::TimeDelta delay = it->second.rate - delta;
if (delay < min_delay)
min_delay = delay;
}
}
if (!all_observers_notified) {
pending_event_ = event;
notification_timer_.Start(
FROM_HERE,
min_delay,
this,
&StorageObserverList::DispatchPendingEvent);
}
}
void StorageObserverList::ScheduleUpdateForObserver(StorageObserver* observer) {
DCHECK(ContainsKey(observers_, observer));
observers_[observer].requires_update = true;
}
void StorageObserverList::DispatchPendingEvent() {
MaybeDispatchEvent(pending_event_);
}
HostStorageObservers::HostStorageObservers(QuotaManager* quota_manager)
: quota_manager_(quota_manager),
initialized_(false),
initializing_(false),
event_occurred_before_init_(false),
cached_usage_(0),
cached_quota_(0),
weak_factory_(this) {
}
HostStorageObservers::~HostStorageObservers() {}
void HostStorageObservers::AddObserver(
StorageObserver* observer,
const StorageObserver::MonitorParams& params) {
observers_.AddObserver(observer, params);
if (!params.dispatch_initial_state)
return;
if (initialized_) {
StorageObserver::Event event(params.filter,
std::max<int64>(cached_usage_, 0),
std::max<int64>(cached_quota_, 0));
observer->OnStorageEvent(event);
return;
}
observers_.ScheduleUpdateForObserver(observer);
StartInitialization(params.filter);
}
void HostStorageObservers::RemoveObserver(StorageObserver* observer) {
observers_.RemoveObserver(observer);
}
bool HostStorageObservers::ContainsObservers() const {
return observers_.ObserverCount() > 0;
}
void HostStorageObservers::NotifyUsageChange(
const StorageObserver::Filter& filter, int64 delta) {
if (initialized_) {
cached_usage_ += delta;
DispatchEvent(filter, true);
return;
}
event_occurred_before_init_ = true;
StartInitialization(filter);
}
void HostStorageObservers::StartInitialization(
const StorageObserver::Filter& filter) {
if (initialized_ || initializing_)
return;
initializing_ = true;
quota_manager_->GetUsageAndQuotaForWebApps(
filter.origin,
filter.storage_type,
base::Bind(&HostStorageObservers::GotHostUsageAndQuota,
weak_factory_.GetWeakPtr(),
filter));
}
void HostStorageObservers::GotHostUsageAndQuota(
const StorageObserver::Filter& filter,
QuotaStatusCode status,
int64 usage,
int64 quota) {
initializing_ = false;
if (status != kQuotaStatusOk)
return;
initialized_ = true;
cached_quota_ = quota;
cached_usage_ = usage;
DispatchEvent(filter, event_occurred_before_init_);
}
void HostStorageObservers::DispatchEvent(
const StorageObserver::Filter& filter, bool is_update) {
StorageObserver::Event event(filter,
std::max<int64>(cached_usage_, 0),
std::max<int64>(cached_quota_, 0));
if (is_update)
observers_.OnStorageChange(event);
else
observers_.MaybeDispatchEvent(event);
}
StorageTypeObservers::StorageTypeObservers(QuotaManager* quota_manager)
: quota_manager_(quota_manager) {
}
StorageTypeObservers::~StorageTypeObservers() {
STLDeleteValues(&host_observers_map_);
}
void StorageTypeObservers::AddObserver(
StorageObserver* observer, const StorageObserver::MonitorParams& params) {
std::string host = net::GetHostOrSpecFromURL(params.filter.origin);
if (host.empty())
return;
HostStorageObservers* host_observers = NULL;
HostObserversMap::iterator it = host_observers_map_.find(host);
if (it == host_observers_map_.end()) {
host_observers = new HostStorageObservers(quota_manager_);
host_observers_map_[host] = host_observers;
} else {
host_observers = it->second;
}
host_observers->AddObserver(observer, params);
}
void StorageTypeObservers::RemoveObserver(StorageObserver* observer) {
for (HostObserversMap::iterator it = host_observers_map_.begin();
it != host_observers_map_.end(); ) {
it->second->RemoveObserver(observer);
if (!it->second->ContainsObservers()) {
delete it->second;
host_observers_map_.erase(it++);
} else {
++it;
}
}
}
void StorageTypeObservers::RemoveObserverForFilter(
StorageObserver* observer, const StorageObserver::Filter& filter) {
std::string host = net::GetHostOrSpecFromURL(filter.origin);
HostObserversMap::iterator it = host_observers_map_.find(host);
if (it == host_observers_map_.end())
return;
it->second->RemoveObserver(observer);
if (!it->second->ContainsObservers()) {
delete it->second;
host_observers_map_.erase(it);
}
}
const HostStorageObservers* StorageTypeObservers::GetHostObservers(
const std::string& host) const {
HostObserversMap::const_iterator it = host_observers_map_.find(host);
if (it != host_observers_map_.end())
return it->second;
return NULL;
}
void StorageTypeObservers::NotifyUsageChange(
const StorageObserver::Filter& filter, int64 delta) {
std::string host = net::GetHostOrSpecFromURL(filter.origin);
HostObserversMap::iterator it = host_observers_map_.find(host);
if (it == host_observers_map_.end())
return;
it->second->NotifyUsageChange(filter, delta);
}
StorageMonitor::StorageMonitor(QuotaManager* quota_manager)
: quota_manager_(quota_manager) {
}
StorageMonitor::~StorageMonitor() {
STLDeleteValues(&storage_type_observers_map_);
}
void StorageMonitor::AddObserver(
StorageObserver* observer, const StorageObserver::MonitorParams& params) {
DCHECK(observer);
if (params.filter.storage_type == kStorageTypeUnknown ||
params.filter.storage_type == kStorageTypeQuotaNotManaged ||
params.filter.origin.is_empty()) {
NOTREACHED();
return;
}
StorageTypeObservers* type_observers = NULL;
StorageTypeObserversMap::iterator it =
storage_type_observers_map_.find(params.filter.storage_type);
if (it == storage_type_observers_map_.end()) {
type_observers = new StorageTypeObservers(quota_manager_);
storage_type_observers_map_[params.filter.storage_type] = type_observers;
} else {
type_observers = it->second;
}
type_observers->AddObserver(observer, params);
}
void StorageMonitor::RemoveObserver(StorageObserver* observer) {
for (StorageTypeObserversMap::iterator it =
storage_type_observers_map_.begin();
it != storage_type_observers_map_.end(); ++it) {
it->second->RemoveObserver(observer);
}
}
void StorageMonitor::RemoveObserverForFilter(
StorageObserver* observer, const StorageObserver::Filter& filter) {
StorageTypeObserversMap::iterator it =
storage_type_observers_map_.find(filter.storage_type);
if (it == storage_type_observers_map_.end())
return;
it->second->RemoveObserverForFilter(observer, filter);
}
const StorageTypeObservers* StorageMonitor::GetStorageTypeObservers(
StorageType storage_type) const {
StorageTypeObserversMap::const_iterator it =
storage_type_observers_map_.find(storage_type);
if (it != storage_type_observers_map_.end())
return it->second;
return NULL;
}
void StorageMonitor::NotifyUsageChange(
const StorageObserver::Filter& filter, int64 delta) {
if (filter.storage_type == kStorageTypeUnknown ||
filter.storage_type == kStorageTypeQuotaNotManaged ||
filter.origin.is_empty()) {
NOTREACHED();
return;
}
StorageTypeObserversMap::iterator it =
storage_type_observers_map_.find(filter.storage_type);
if (it == storage_type_observers_map_.end())
return;
it->second->NotifyUsageChange(filter, delta);
}
}