1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/storage_monitor.h" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <algorithm> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/stl_util.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/net_util.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/quota/quota_status_code.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// StorageObserverList: 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageObserverList::ObserverState::ObserverState() 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : requires_update(false) { 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageObserverList::StorageObserverList() {} 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageObserverList::~StorageObserverList() {} 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::AddObserver( 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::MonitorParams& params) { 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ObserverState& observer_state = observers_[observer]; 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observer_state.origin = params.filter.origin; 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observer_state.rate = params.rate; 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::RemoveObserver(StorageObserver* observer) { 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.erase(observer); 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint StorageObserverList::ObserverCount() const { 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return observers_.size(); 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::OnStorageChange(const StorageObserver::Event& event) { 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (StorageObserverStateMap::iterator it = observers_.begin(); 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != observers_.end(); ++it) { 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second.requires_update = true; 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MaybeDispatchEvent(event); 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::MaybeDispatchEvent( 51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Event& event) { 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch notification_timer_.Stop(); 53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta min_delay = base::TimeDelta::Max(); 54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool all_observers_notified = true; 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (StorageObserverStateMap::iterator it = observers_.begin(); 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != observers_.end(); ++it) { 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!it->second.requires_update) 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch continue; 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeTicks current_time = base::TimeTicks::Now(); 62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta delta = current_time - it->second.last_notification_time; 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it->second.last_notification_time.is_null() || 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delta >= it->second.rate) { 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second.requires_update = false; 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second.last_notification_time = current_time; 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it->second.origin == event.filter.origin) { 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->first->OnStorageEvent(event); 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // When the quota and usage of an origin is requested, QuotaManager 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // returns the quota and usage of the host. Multiple origins can map to 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // to the same host, so ensure the |origin| field in the dispatched 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // event matches the |origin| specified by the observer when it was 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // registered. 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver::Event dispatch_event(event); 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch dispatch_event.filter.origin = it->second.origin; 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->first->OnStorageEvent(dispatch_event); 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch all_observers_notified = false; 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta delay = it->second.rate - delta; 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (delay < min_delay) 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch min_delay = delay; 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // We need to respect the notification rate specified by observers. So if it 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // is too soon to dispatch an event to an observer, save the event and 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // dispatch it after a delay. If we simply drop the event, another one may 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // not arrive anytime soon and the observer will miss the most recent event. 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!all_observers_notified) { 93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pending_event_ = event; 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch notification_timer_.Start( 95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch min_delay, 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &StorageObserverList::DispatchPendingEvent); 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::ScheduleUpdateForObserver(StorageObserver* observer) { 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(ContainsKey(observers_, observer)); 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_[observer].requires_update = true; 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageObserverList::DispatchPendingEvent() { 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MaybeDispatchEvent(pending_event_); 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// HostStorageObservers: 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochHostStorageObservers::HostStorageObservers(QuotaManager* quota_manager) 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : quota_manager_(quota_manager), 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initialized_(false), 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initializing_(false), 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch event_occurred_before_init_(false), 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch usage_deltas_during_init_(0), 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached_usage_(0), 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached_quota_(0), 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_(this) { 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochHostStorageObservers::~HostStorageObservers() {} 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::AddObserver( 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::MonitorParams& params) { 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.AddObserver(observer, params); 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!params.dispatch_initial_state) 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (initialized_) { 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver::Event event(params.filter, 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::max<int64>(cached_usage_, 0), 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::max<int64>(cached_quota_, 0)); 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observer->OnStorageEvent(event); 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Ensure the observer receives the initial storage state once initialization 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // is complete. 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.ScheduleUpdateForObserver(observer); 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StartInitialization(params.filter); 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::RemoveObserver(StorageObserver* observer) { 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.RemoveObserver(observer); 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool HostStorageObservers::ContainsObservers() const { 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return observers_.ObserverCount() > 0; 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::NotifyUsageChange( 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter, int64 delta) { 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (initialized_) { 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached_usage_ += delta; 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DispatchEvent(filter, true); 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If a storage change occurs before initialization, ensure all observers will 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // receive an event once initialization is complete. 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch event_occurred_before_init_ = true; 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // During QuotaManager::GetUsageAndQuotaForWebApps(), cached data is read 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // synchronously, but other data may be retrieved asynchronously. A usage 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // change may occur between the function call and callback. These deltas need 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // to be added to the usage received by GotHostUsageAndQuota() to ensure 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |cached_usage_| is correctly initialized. 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (initializing_) { 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch usage_deltas_during_init_ += delta; 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StartInitialization(filter); 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::StartInitialization( 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter) { 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (initialized_ || initializing_) 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initializing_ = true; 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch quota_manager_->GetUsageAndQuotaForWebApps( 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch filter.origin, 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch filter.storage_type, 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&HostStorageObservers::GotHostUsageAndQuota, 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_.GetWeakPtr(), 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch filter)); 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::GotHostUsageAndQuota( 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter, 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch QuotaStatusCode status, 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 usage, 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 quota) { 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initializing_ = false; 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status != kQuotaStatusOk) 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initialized_ = true; 206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached_quota_ = quota; 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached_usage_ = usage + usage_deltas_during_init_; 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DispatchEvent(filter, event_occurred_before_init_); 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid HostStorageObservers::DispatchEvent( 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter, bool is_update) { 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver::Event event(filter, 214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::max<int64>(cached_usage_, 0), 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::max<int64>(cached_quota_, 0)); 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_update) 217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.OnStorageChange(event); 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.MaybeDispatchEvent(event); 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// StorageTypeObservers: 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageTypeObservers::StorageTypeObservers(QuotaManager* quota_manager) 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : quota_manager_(quota_manager) { 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageTypeObservers::~StorageTypeObservers() { 230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch STLDeleteValues(&host_observers_map_); 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageTypeObservers::AddObserver( 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::MonitorParams& params) { 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string host = net::GetHostOrSpecFromURL(params.filter.origin); 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (host.empty()) 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HostStorageObservers* host_observers = NULL; 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HostObserversMap::iterator it = host_observers_map_.find(host); 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == host_observers_map_.end()) { 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers = new HostStorageObservers(quota_manager_); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers_map_[host] = host_observers; 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers = it->second; 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers->AddObserver(observer, params); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageTypeObservers::RemoveObserver(StorageObserver* observer) { 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (HostObserversMap::iterator it = host_observers_map_.begin(); 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != host_observers_map_.end(); ) { 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->RemoveObserver(observer); 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!it->second->ContainsObservers()) { 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete it->second; 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers_map_.erase(it++); 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++it; 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageTypeObservers::RemoveObserverForFilter( 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::Filter& filter) { 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string host = net::GetHostOrSpecFromURL(filter.origin); 267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HostObserversMap::iterator it = host_observers_map_.find(host); 268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == host_observers_map_.end()) 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->RemoveObserver(observer); 272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!it->second->ContainsObservers()) { 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete it->second; 274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_observers_map_.erase(it); 275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst HostStorageObservers* StorageTypeObservers::GetHostObservers( 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& host) const { 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HostObserversMap::const_iterator it = host_observers_map_.find(host); 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it != host_observers_map_.end()) 282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return it->second; 283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageTypeObservers::NotifyUsageChange( 288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter, int64 delta) { 289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string host = net::GetHostOrSpecFromURL(filter.origin); 290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HostObserversMap::iterator it = host_observers_map_.find(host); 291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == host_observers_map_.end()) 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->NotifyUsageChange(filter, delta); 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// StorageMonitor: 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageMonitor::StorageMonitor(QuotaManager* quota_manager) 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : quota_manager_(quota_manager) { 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochStorageMonitor::~StorageMonitor() { 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch STLDeleteValues(&storage_type_observers_map_); 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageMonitor::AddObserver( 309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::MonitorParams& params) { 310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Check preconditions. 313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (params.filter.storage_type == kStorageTypeUnknown || 314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch params.filter.storage_type == kStorageTypeQuotaNotManaged || 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch params.filter.origin.is_empty()) { 316c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 319c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageTypeObservers* type_observers = NULL; 321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageTypeObserversMap::iterator it = 322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_.find(params.filter.storage_type); 323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == storage_type_observers_map_.end()) { 324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch type_observers = new StorageTypeObservers(quota_manager_); 325c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_[params.filter.storage_type] = type_observers; 326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 327c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch type_observers = it->second; 328c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 329c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 330c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch type_observers->AddObserver(observer, params); 331c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageMonitor::RemoveObserver(StorageObserver* observer) { 334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (StorageTypeObserversMap::iterator it = 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_.begin(); 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != storage_type_observers_map_.end(); ++it) { 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->RemoveObserver(observer); 338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageMonitor::RemoveObserverForFilter( 342c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::Filter& filter) { 343c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageTypeObserversMap::iterator it = 344c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_.find(filter.storage_type); 345c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == storage_type_observers_map_.end()) 346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 347c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->RemoveObserverForFilter(observer, filter); 349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst StorageTypeObservers* StorageMonitor::GetStorageTypeObservers( 352c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageType storage_type) const { 353c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageTypeObserversMap::const_iterator it = 354c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_.find(storage_type); 355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it != storage_type_observers_map_.end()) 356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return it->second; 357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid StorageMonitor::NotifyUsageChange( 362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const StorageObserver::Filter& filter, int64 delta) { 363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Check preconditions. 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (filter.storage_type == kStorageTypeUnknown || 365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch filter.storage_type == kStorageTypeQuotaNotManaged || 366c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch filter.origin.is_empty()) { 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 370c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 371c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageTypeObserversMap::iterator it = 372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_type_observers_map_.find(filter.storage_type); 373c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it == storage_type_observers_map_.end()) 374c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 375c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->second->NotifyUsageChange(filter, delta); 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 37903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 380