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