| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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. | |
| 4 | |
| 5 #ifndef WEBKIT_BROWSER_QUOTA_QUOTA_MANAGER_H_ | |
| 6 #define WEBKIT_BROWSER_QUOTA_QUOTA_MANAGER_H_ | |
| 7 | |
| 8 #include <deque> | |
| 9 #include <list> | |
| 10 #include <map> | |
| 11 #include <set> | |
| 12 #include <string> | |
| 13 #include <utility> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "base/basictypes.h" | |
| 17 #include "base/callback.h" | |
| 18 #include "base/files/file_path.h" | |
| 19 #include "base/memory/ref_counted.h" | |
| 20 #include "base/memory/scoped_ptr.h" | |
| 21 #include "base/memory/weak_ptr.h" | |
| 22 #include "base/sequenced_task_runner_helpers.h" | |
| 23 #include "webkit/browser/quota/quota_callbacks.h" | |
| 24 #include "webkit/browser/quota/quota_client.h" | |
| 25 #include "webkit/browser/quota/quota_database.h" | |
| 26 #include "webkit/browser/quota/quota_task.h" | |
| 27 #include "webkit/browser/quota/special_storage_policy.h" | |
| 28 #include "webkit/browser/quota/storage_observer.h" | |
| 29 #include "webkit/browser/webkit_storage_browser_export.h" | |
| 30 | |
| 31 namespace base { | |
| 32 class FilePath; | |
| 33 class SequencedTaskRunner; | |
| 34 class SingleThreadTaskRunner; | |
| 35 } | |
| 36 | |
| 37 namespace quota_internals { | |
| 38 class QuotaInternalsProxy; | |
| 39 } | |
| 40 | |
| 41 namespace content { | |
| 42 class MockQuotaManager; | |
| 43 class MockStorageClient; | |
| 44 class QuotaManagerTest; | |
| 45 class StorageMonitorTest; | |
| 46 | |
| 47 } | |
| 48 | |
| 49 namespace quota { | |
| 50 | |
| 51 class QuotaDatabase; | |
| 52 class QuotaManagerProxy; | |
| 53 class QuotaTemporaryStorageEvictor; | |
| 54 class StorageMonitor; | |
| 55 class UsageTracker; | |
| 56 | |
| 57 struct QuotaManagerDeleter; | |
| 58 | |
| 59 struct WEBKIT_STORAGE_BROWSER_EXPORT UsageAndQuota { | |
| 60 int64 usage; | |
| 61 int64 global_limited_usage; | |
| 62 int64 quota; | |
| 63 int64 available_disk_space; | |
| 64 | |
| 65 UsageAndQuota(); | |
| 66 UsageAndQuota(int64 usage, | |
| 67 int64 global_limited_usage, | |
| 68 int64 quota, | |
| 69 int64 available_disk_space); | |
| 70 }; | |
| 71 | |
| 72 // An interface called by QuotaTemporaryStorageEvictor. | |
| 73 class WEBKIT_STORAGE_BROWSER_EXPORT QuotaEvictionHandler { | |
| 74 public: | |
| 75 typedef base::Callback<void(const GURL&)> GetLRUOriginCallback; | |
| 76 typedef StatusCallback EvictOriginDataCallback; | |
| 77 typedef base::Callback<void(QuotaStatusCode status, | |
| 78 const UsageAndQuota& usage_and_quota)> | |
| 79 UsageAndQuotaCallback; | |
| 80 | |
| 81 // Returns the least recently used origin. It might return empty | |
| 82 // GURL when there are no evictable origins. | |
| 83 virtual void GetLRUOrigin( | |
| 84 StorageType type, | |
| 85 const GetLRUOriginCallback& callback) = 0; | |
| 86 | |
| 87 virtual void EvictOriginData( | |
| 88 const GURL& origin, | |
| 89 StorageType type, | |
| 90 const EvictOriginDataCallback& callback) = 0; | |
| 91 | |
| 92 virtual void GetUsageAndQuotaForEviction( | |
| 93 const UsageAndQuotaCallback& callback) = 0; | |
| 94 | |
| 95 protected: | |
| 96 virtual ~QuotaEvictionHandler() {} | |
| 97 }; | |
| 98 | |
| 99 struct UsageInfo { | |
| 100 UsageInfo(const std::string& host, StorageType type, int64 usage) | |
| 101 : host(host), | |
| 102 type(type), | |
| 103 usage(usage) {} | |
| 104 std::string host; | |
| 105 StorageType type; | |
| 106 int64 usage; | |
| 107 }; | |
| 108 | |
| 109 // The quota manager class. This class is instantiated per profile and | |
| 110 // held by the profile. With the exception of the constructor and the | |
| 111 // proxy() method, all methods should only be called on the IO thread. | |
| 112 class WEBKIT_STORAGE_BROWSER_EXPORT QuotaManager | |
| 113 : public QuotaTaskObserver, | |
| 114 public QuotaEvictionHandler, | |
| 115 public base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter> { | |
| 116 public: | |
| 117 typedef base::Callback<void(QuotaStatusCode, | |
| 118 int64 /* usage */, | |
| 119 int64 /* quota */)> | |
| 120 GetUsageAndQuotaCallback; | |
| 121 | |
| 122 static const int64 kIncognitoDefaultQuotaLimit; | |
| 123 static const int64 kNoLimit; | |
| 124 | |
| 125 QuotaManager(bool is_incognito, | |
| 126 const base::FilePath& profile_path, | |
| 127 base::SingleThreadTaskRunner* io_thread, | |
| 128 base::SequencedTaskRunner* db_thread, | |
| 129 SpecialStoragePolicy* special_storage_policy); | |
| 130 | |
| 131 // Returns a proxy object that can be used on any thread. | |
| 132 QuotaManagerProxy* proxy() { return proxy_.get(); } | |
| 133 | |
| 134 // Called by clients or webapps. Returns usage per host. | |
| 135 void GetUsageInfo(const GetUsageInfoCallback& callback); | |
| 136 | |
| 137 // Called by Web Apps. | |
| 138 // This method is declared as virtual to allow test code to override it. | |
| 139 virtual void GetUsageAndQuotaForWebApps( | |
| 140 const GURL& origin, | |
| 141 StorageType type, | |
| 142 const GetUsageAndQuotaCallback& callback); | |
| 143 | |
| 144 // Called by StorageClients. | |
| 145 // This method is declared as virtual to allow test code to override it. | |
| 146 // | |
| 147 // For UnlimitedStorage origins, this version skips usage and quota handling | |
| 148 // to avoid extra query cost. | |
| 149 // Do not call this method for apps/user-facing code. | |
| 150 virtual void GetUsageAndQuota( | |
| 151 const GURL& origin, | |
| 152 StorageType type, | |
| 153 const GetUsageAndQuotaCallback& callback); | |
| 154 | |
| 155 // Called by clients via proxy. | |
| 156 // Client storage should call this method when storage is accessed. | |
| 157 // Used to maintain LRU ordering. | |
| 158 void NotifyStorageAccessed(QuotaClient::ID client_id, | |
| 159 const GURL& origin, | |
| 160 StorageType type); | |
| 161 | |
| 162 // Called by clients via proxy. | |
| 163 // Client storage must call this method whenever they have made any | |
| 164 // modifications that change the amount of data stored in their storage. | |
| 165 void NotifyStorageModified(QuotaClient::ID client_id, | |
| 166 const GURL& origin, | |
| 167 StorageType type, | |
| 168 int64 delta); | |
| 169 | |
| 170 // Used to avoid evicting origins with open pages. | |
| 171 // A call to NotifyOriginInUse must be balanced by a later call | |
| 172 // to NotifyOriginNoLongerInUse. | |
| 173 void NotifyOriginInUse(const GURL& origin); | |
| 174 void NotifyOriginNoLongerInUse(const GURL& origin); | |
| 175 bool IsOriginInUse(const GURL& origin) const { | |
| 176 return origins_in_use_.find(origin) != origins_in_use_.end(); | |
| 177 } | |
| 178 | |
| 179 void SetUsageCacheEnabled(QuotaClient::ID client_id, | |
| 180 const GURL& origin, | |
| 181 StorageType type, | |
| 182 bool enabled); | |
| 183 | |
| 184 // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a | |
| 185 // particular StorageType associated with either a specific origin or set of | |
| 186 // origins. Each method additionally requires a |quota_client_mask| which | |
| 187 // specifies the types of QuotaClients to delete from the origin. This is | |
| 188 // specified by the caller as a bitmask built from QuotaClient::IDs. Setting | |
| 189 // the mask to QuotaClient::kAllClientsMask will remove all clients from the | |
| 190 // origin, regardless of type. | |
| 191 virtual void DeleteOriginData(const GURL& origin, | |
| 192 StorageType type, | |
| 193 int quota_client_mask, | |
| 194 const StatusCallback& callback); | |
| 195 void DeleteHostData(const std::string& host, | |
| 196 StorageType type, | |
| 197 int quota_client_mask, | |
| 198 const StatusCallback& callback); | |
| 199 | |
| 200 // Called by UI and internal modules. | |
| 201 void GetAvailableSpace(const AvailableSpaceCallback& callback); | |
| 202 void GetTemporaryGlobalQuota(const QuotaCallback& callback); | |
| 203 | |
| 204 // Ok to call with NULL callback. | |
| 205 void SetTemporaryGlobalOverrideQuota(int64 new_quota, | |
| 206 const QuotaCallback& callback); | |
| 207 | |
| 208 void GetPersistentHostQuota(const std::string& host, | |
| 209 const QuotaCallback& callback); | |
| 210 void SetPersistentHostQuota(const std::string& host, | |
| 211 int64 new_quota, | |
| 212 const QuotaCallback& callback); | |
| 213 void GetGlobalUsage(StorageType type, const GlobalUsageCallback& callback); | |
| 214 void GetHostUsage(const std::string& host, StorageType type, | |
| 215 const UsageCallback& callback); | |
| 216 void GetHostUsage(const std::string& host, StorageType type, | |
| 217 QuotaClient::ID client_id, | |
| 218 const UsageCallback& callback); | |
| 219 | |
| 220 bool IsTrackingHostUsage(StorageType type, QuotaClient::ID client_id) const; | |
| 221 | |
| 222 void GetStatistics(std::map<std::string, std::string>* statistics); | |
| 223 | |
| 224 bool IsStorageUnlimited(const GURL& origin, StorageType type) const; | |
| 225 | |
| 226 bool CanQueryDiskSize(const GURL& origin) const { | |
| 227 return special_storage_policy_.get() && | |
| 228 special_storage_policy_->CanQueryDiskSize(origin); | |
| 229 } | |
| 230 | |
| 231 virtual void GetOriginsModifiedSince(StorageType type, | |
| 232 base::Time modified_since, | |
| 233 const GetOriginsCallback& callback); | |
| 234 | |
| 235 bool ResetUsageTracker(StorageType type); | |
| 236 | |
| 237 // Used to register/deregister observers that wish to monitor storage events. | |
| 238 void AddStorageObserver(StorageObserver* observer, | |
| 239 const StorageObserver::MonitorParams& params); | |
| 240 void RemoveStorageObserver(StorageObserver* observer); | |
| 241 void RemoveStorageObserverForFilter(StorageObserver* observer, | |
| 242 const StorageObserver::Filter& filter); | |
| 243 | |
| 244 // Determines the portion of the temp pool that can be | |
| 245 // utilized by a single host (ie. 5 for 20%). | |
| 246 static const int kPerHostTemporaryPortion; | |
| 247 | |
| 248 static const int64 kPerHostPersistentQuotaLimit; | |
| 249 | |
| 250 static const char kDatabaseName[]; | |
| 251 | |
| 252 static const int kThresholdOfErrorsToBeBlacklisted; | |
| 253 | |
| 254 static const int kEvictionIntervalInMilliSeconds; | |
| 255 | |
| 256 // These are kept non-const so that test code can change the value. | |
| 257 // TODO(kinuko): Make this a real const value and add a proper way to set | |
| 258 // the quota for syncable storage. (http://crbug.com/155488) | |
| 259 static int64 kMinimumPreserveForSystem; | |
| 260 static int64 kSyncableStorageDefaultHostQuota; | |
| 261 | |
| 262 protected: | |
| 263 virtual ~QuotaManager(); | |
| 264 | |
| 265 private: | |
| 266 friend class base::DeleteHelper<QuotaManager>; | |
| 267 friend class base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter>; | |
| 268 friend class content::QuotaManagerTest; | |
| 269 friend class content::StorageMonitorTest; | |
| 270 friend class content::MockQuotaManager; | |
| 271 friend class content::MockStorageClient; | |
| 272 friend class quota_internals::QuotaInternalsProxy; | |
| 273 friend class QuotaManagerProxy; | |
| 274 friend class QuotaTemporaryStorageEvictor; | |
| 275 friend struct QuotaManagerDeleter; | |
| 276 | |
| 277 class GetUsageInfoTask; | |
| 278 | |
| 279 class OriginDataDeleter; | |
| 280 class HostDataDeleter; | |
| 281 | |
| 282 class GetModifiedSinceHelper; | |
| 283 class DumpQuotaTableHelper; | |
| 284 class DumpOriginInfoTableHelper; | |
| 285 | |
| 286 typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry; | |
| 287 typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry; | |
| 288 typedef std::vector<QuotaTableEntry> QuotaTableEntries; | |
| 289 typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries; | |
| 290 | |
| 291 // Function pointer type used to store the function which returns the | |
| 292 // available disk space for the disk containing the given FilePath. | |
| 293 typedef int64 (*GetAvailableDiskSpaceFn)(const base::FilePath&); | |
| 294 | |
| 295 typedef base::Callback<void(const QuotaTableEntries&)> | |
| 296 DumpQuotaTableCallback; | |
| 297 typedef base::Callback<void(const OriginInfoTableEntries&)> | |
| 298 DumpOriginInfoTableCallback; | |
| 299 | |
| 300 struct EvictionContext { | |
| 301 EvictionContext(); | |
| 302 virtual ~EvictionContext(); | |
| 303 GURL evicted_origin; | |
| 304 StorageType evicted_type; | |
| 305 | |
| 306 EvictOriginDataCallback evict_origin_data_callback; | |
| 307 }; | |
| 308 | |
| 309 typedef QuotaEvictionHandler::UsageAndQuotaCallback | |
| 310 UsageAndQuotaDispatcherCallback; | |
| 311 | |
| 312 // This initialization method is lazily called on the IO thread | |
| 313 // when the first quota manager API is called. | |
| 314 // Initialize must be called after all quota clients are added to the | |
| 315 // manager by RegisterStorage. | |
| 316 void LazyInitialize(); | |
| 317 | |
| 318 // Called by clients via proxy. | |
| 319 // Registers a quota client to the manager. | |
| 320 // The client must remain valid until OnQuotaManagerDestored is called. | |
| 321 void RegisterClient(QuotaClient* client); | |
| 322 | |
| 323 UsageTracker* GetUsageTracker(StorageType type) const; | |
| 324 | |
| 325 // Extract cached origins list from the usage tracker. | |
| 326 // (Might return empty list if no origin is tracked by the tracker.) | |
| 327 void GetCachedOrigins(StorageType type, std::set<GURL>* origins); | |
| 328 | |
| 329 // These internal methods are separately defined mainly for testing. | |
| 330 void NotifyStorageAccessedInternal( | |
| 331 QuotaClient::ID client_id, | |
| 332 const GURL& origin, | |
| 333 StorageType type, | |
| 334 base::Time accessed_time); | |
| 335 void NotifyStorageModifiedInternal( | |
| 336 QuotaClient::ID client_id, | |
| 337 const GURL& origin, | |
| 338 StorageType type, | |
| 339 int64 delta, | |
| 340 base::Time modified_time); | |
| 341 | |
| 342 void DumpQuotaTable(const DumpQuotaTableCallback& callback); | |
| 343 void DumpOriginInfoTable(const DumpOriginInfoTableCallback& callback); | |
| 344 | |
| 345 // Methods for eviction logic. | |
| 346 void StartEviction(); | |
| 347 void DeleteOriginFromDatabase(const GURL& origin, StorageType type); | |
| 348 | |
| 349 void DidOriginDataEvicted(QuotaStatusCode status); | |
| 350 | |
| 351 void ReportHistogram(); | |
| 352 void DidGetTemporaryGlobalUsageForHistogram(int64 usage, | |
| 353 int64 unlimited_usage); | |
| 354 void DidGetPersistentGlobalUsageForHistogram(int64 usage, | |
| 355 int64 unlimited_usage); | |
| 356 | |
| 357 // QuotaEvictionHandler. | |
| 358 virtual void GetLRUOrigin( | |
| 359 StorageType type, | |
| 360 const GetLRUOriginCallback& callback) OVERRIDE; | |
| 361 virtual void EvictOriginData( | |
| 362 const GURL& origin, | |
| 363 StorageType type, | |
| 364 const EvictOriginDataCallback& callback) OVERRIDE; | |
| 365 virtual void GetUsageAndQuotaForEviction( | |
| 366 const UsageAndQuotaCallback& callback) OVERRIDE; | |
| 367 | |
| 368 void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback& callback, | |
| 369 const int64* new_quota, | |
| 370 bool success); | |
| 371 void DidGetPersistentHostQuota(const std::string& host, | |
| 372 const int64* quota, | |
| 373 bool success); | |
| 374 void DidSetPersistentHostQuota(const std::string& host, | |
| 375 const QuotaCallback& callback, | |
| 376 const int64* new_quota, | |
| 377 bool success); | |
| 378 void DidInitialize(int64* temporary_quota_override, | |
| 379 int64* desired_available_space, | |
| 380 bool success); | |
| 381 void DidGetLRUOrigin(const GURL* origin, | |
| 382 bool success); | |
| 383 void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status, | |
| 384 int64 quota_unused); | |
| 385 void DidInitializeTemporaryOriginsInfo(bool success); | |
| 386 void DidGetAvailableSpace(int64 space); | |
| 387 void DidDatabaseWork(bool success); | |
| 388 | |
| 389 void DeleteOnCorrectThread() const; | |
| 390 | |
| 391 void PostTaskAndReplyWithResultForDBThread( | |
| 392 const tracked_objects::Location& from_here, | |
| 393 const base::Callback<bool(QuotaDatabase*)>& task, | |
| 394 const base::Callback<void(bool)>& reply); | |
| 395 | |
| 396 const bool is_incognito_; | |
| 397 const base::FilePath profile_path_; | |
| 398 | |
| 399 scoped_refptr<QuotaManagerProxy> proxy_; | |
| 400 bool db_disabled_; | |
| 401 bool eviction_disabled_; | |
| 402 scoped_refptr<base::SingleThreadTaskRunner> io_thread_; | |
| 403 scoped_refptr<base::SequencedTaskRunner> db_thread_; | |
| 404 mutable scoped_ptr<QuotaDatabase> database_; | |
| 405 | |
| 406 GetLRUOriginCallback lru_origin_callback_; | |
| 407 std::set<GURL> access_notified_origins_; | |
| 408 | |
| 409 QuotaClientList clients_; | |
| 410 | |
| 411 scoped_ptr<UsageTracker> temporary_usage_tracker_; | |
| 412 scoped_ptr<UsageTracker> persistent_usage_tracker_; | |
| 413 scoped_ptr<UsageTracker> syncable_usage_tracker_; | |
| 414 // TODO(michaeln): Need a way to clear the cache, drop and | |
| 415 // reinstantiate the trackers when they're not handling requests. | |
| 416 | |
| 417 scoped_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_; | |
| 418 EvictionContext eviction_context_; | |
| 419 | |
| 420 ClosureQueue db_initialization_callbacks_; | |
| 421 AvailableSpaceCallbackQueue available_space_callbacks_; | |
| 422 GlobalQuotaCallbackQueue temporary_global_quota_callbacks_; | |
| 423 HostQuotaCallbackMap persistent_host_quota_callbacks_; | |
| 424 | |
| 425 bool temporary_quota_initialized_; | |
| 426 int64 temporary_quota_override_; | |
| 427 | |
| 428 int64 desired_available_space_; | |
| 429 | |
| 430 // Map from origin to count. | |
| 431 std::map<GURL, int> origins_in_use_; | |
| 432 // Map from origin to error count. | |
| 433 std::map<GURL, int> origins_in_error_; | |
| 434 | |
| 435 scoped_refptr<SpecialStoragePolicy> special_storage_policy_; | |
| 436 | |
| 437 base::RepeatingTimer<QuotaManager> histogram_timer_; | |
| 438 | |
| 439 // Pointer to the function used to get the available disk space. This is | |
| 440 // overwritten by QuotaManagerTest in order to attain a deterministic reported | |
| 441 // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace. | |
| 442 GetAvailableDiskSpaceFn get_disk_space_fn_; | |
| 443 | |
| 444 scoped_ptr<StorageMonitor> storage_monitor_; | |
| 445 | |
| 446 base::WeakPtrFactory<QuotaManager> weak_factory_; | |
| 447 | |
| 448 DISALLOW_COPY_AND_ASSIGN(QuotaManager); | |
| 449 }; | |
| 450 | |
| 451 struct QuotaManagerDeleter { | |
| 452 static void Destruct(const QuotaManager* manager) { | |
| 453 manager->DeleteOnCorrectThread(); | |
| 454 } | |
| 455 }; | |
| 456 | |
| 457 } // namespace quota | |
| 458 | |
| 459 #endif // WEBKIT_BROWSER_QUOTA_QUOTA_MANAGER_H_ | |
| OLD | NEW |