Home | History | Annotate | Download | only in fileapi
      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.
      4 
      5 #include "webkit/browser/fileapi/sandbox_quota_observer.h"
      6 
      7 #include "base/sequenced_task_runner.h"
      8 #include "webkit/browser/fileapi/file_system_url.h"
      9 #include "webkit/browser/fileapi/file_system_usage_cache.h"
     10 #include "webkit/browser/fileapi/sandbox_file_system_backend_delegate.h"
     11 #include "webkit/browser/fileapi/timed_task_helper.h"
     12 #include "webkit/browser/quota/quota_client.h"
     13 #include "webkit/browser/quota/quota_manager_proxy.h"
     14 #include "webkit/common/fileapi/file_system_util.h"
     15 
     16 namespace fileapi {
     17 
     18 SandboxQuotaObserver::SandboxQuotaObserver(
     19     quota::QuotaManagerProxy* quota_manager_proxy,
     20     base::SequencedTaskRunner* update_notify_runner,
     21     ObfuscatedFileUtil* sandbox_file_util,
     22     FileSystemUsageCache* file_system_usage_cache)
     23     : quota_manager_proxy_(quota_manager_proxy),
     24       update_notify_runner_(update_notify_runner),
     25       sandbox_file_util_(sandbox_file_util),
     26       file_system_usage_cache_(file_system_usage_cache) {}
     27 
     28 SandboxQuotaObserver::~SandboxQuotaObserver() {}
     29 
     30 void SandboxQuotaObserver::OnStartUpdate(const FileSystemURL& url) {
     31   DCHECK(update_notify_runner_->RunsTasksOnCurrentThread());
     32   base::FilePath usage_file_path = GetUsageCachePath(url);
     33   if (usage_file_path.empty())
     34     return;
     35   file_system_usage_cache_->IncrementDirty(usage_file_path);
     36 }
     37 
     38 void SandboxQuotaObserver::OnUpdate(const FileSystemURL& url,
     39                                     int64 delta) {
     40   DCHECK(update_notify_runner_->RunsTasksOnCurrentThread());
     41 
     42   if (quota_manager_proxy_.get()) {
     43     quota_manager_proxy_->NotifyStorageModified(
     44         quota::QuotaClient::kFileSystem,
     45         url.origin(),
     46         FileSystemTypeToQuotaStorageType(url.type()),
     47         delta);
     48   }
     49 
     50   base::FilePath usage_file_path = GetUsageCachePath(url);
     51   if (usage_file_path.empty())
     52     return;
     53 
     54   pending_update_notification_[usage_file_path] += delta;
     55   if (!delayed_cache_update_helper_) {
     56     delayed_cache_update_helper_.reset(
     57         new TimedTaskHelper(update_notify_runner_.get()));
     58     delayed_cache_update_helper_->Start(
     59         FROM_HERE,
     60         base::TimeDelta(),  // No delay.
     61         base::Bind(&SandboxQuotaObserver::ApplyPendingUsageUpdate,
     62                    base::Unretained(this)));
     63   }
     64 }
     65 
     66 void SandboxQuotaObserver::OnEndUpdate(const FileSystemURL& url) {
     67   DCHECK(update_notify_runner_->RunsTasksOnCurrentThread());
     68 
     69   base::FilePath usage_file_path = GetUsageCachePath(url);
     70   if (usage_file_path.empty())
     71     return;
     72 
     73   PendingUpdateNotificationMap::iterator found =
     74       pending_update_notification_.find(usage_file_path);
     75   if (found != pending_update_notification_.end()) {
     76     UpdateUsageCacheFile(found->first, found->second);
     77     pending_update_notification_.erase(found);
     78   }
     79 
     80   file_system_usage_cache_->DecrementDirty(usage_file_path);
     81 }
     82 
     83 void SandboxQuotaObserver::OnAccess(const FileSystemURL& url) {
     84   if (quota_manager_proxy_.get()) {
     85     quota_manager_proxy_->NotifyStorageAccessed(
     86         quota::QuotaClient::kFileSystem,
     87         url.origin(),
     88         FileSystemTypeToQuotaStorageType(url.type()));
     89   }
     90 }
     91 
     92 void SandboxQuotaObserver::SetUsageCacheEnabled(
     93     const GURL& origin,
     94     FileSystemType type,
     95     bool enabled) {
     96   if (quota_manager_proxy_.get()) {
     97     quota_manager_proxy_->SetUsageCacheEnabled(
     98         quota::QuotaClient::kFileSystem,
     99         origin,
    100         FileSystemTypeToQuotaStorageType(type),
    101         enabled);
    102   }
    103 }
    104 
    105 base::FilePath SandboxQuotaObserver::GetUsageCachePath(
    106     const FileSystemURL& url) {
    107   DCHECK(sandbox_file_util_);
    108   base::File::Error error = base::File::FILE_OK;
    109   base::FilePath path =
    110       SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
    111           sandbox_file_util_, url.origin(), url.type(), &error);
    112   if (error != base::File::FILE_OK) {
    113     LOG(WARNING) << "Could not get usage cache path for: "
    114                  << url.DebugString();
    115     return base::FilePath();
    116   }
    117   return path;
    118 }
    119 
    120 void SandboxQuotaObserver::ApplyPendingUsageUpdate() {
    121   delayed_cache_update_helper_.reset();
    122   for (PendingUpdateNotificationMap::iterator itr =
    123            pending_update_notification_.begin();
    124        itr != pending_update_notification_.end();
    125        ++itr) {
    126     UpdateUsageCacheFile(itr->first, itr->second);
    127   }
    128   pending_update_notification_.clear();
    129 }
    130 
    131 void SandboxQuotaObserver::UpdateUsageCacheFile(
    132     const base::FilePath& usage_file_path,
    133     int64 delta) {
    134   DCHECK(!usage_file_path.empty());
    135   if (!usage_file_path.empty() && delta != 0)
    136     file_system_usage_cache_->AtomicUpdateUsageByDelta(usage_file_path, delta);
    137 }
    138 
    139 }  // namespace fileapi
    140