root/webkit/browser/fileapi/plugin_private_file_system_backend.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. FileSystemIDToPluginMap
  2. FileSystemIDToPluginMap
  3. GetPluginIDForURL
  4. RegisterFileSystem
  5. RemoveFileSystem
  6. OpenFileSystemOnFileTaskRunner
  7. weak_factory_
  8. OpenPrivateFileSystem
  9. CanHandleType
  10. Initialize
  11. ResolveURL
  12. GetAsyncFileUtil
  13. GetCopyOrMoveFileValidatorFactory
  14. CreateFileSystemOperation
  15. SupportsStreaming
  16. CreateFileStreamReader
  17. CreateFileStreamWriter
  18. GetQuotaUtil
  19. DeleteOriginDataOnFileTaskRunner
  20. GetOriginsForTypeOnFileTaskRunner
  21. GetOriginsForHostOnFileTaskRunner
  22. GetOriginUsageOnFileTaskRunner
  23. CreateQuotaReservationOnFileTaskRunner
  24. AddFileUpdateObserver
  25. AddFileChangeObserver
  26. AddFileAccessObserver
  27. GetUpdateObservers
  28. GetChangeObservers
  29. GetAccessObservers
  30. obfuscated_file_util

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/browser/fileapi/plugin_private_file_system_backend.h"

#include <map>

#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "base/task_runner_util.h"
#include "net/base/net_util.h"
#include "webkit/browser/blob/file_stream_reader.h"
#include "webkit/browser/fileapi/async_file_util_adapter.h"
#include "webkit/browser/fileapi/file_stream_writer.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_options.h"
#include "webkit/browser/fileapi/isolated_context.h"
#include "webkit/browser/fileapi/obfuscated_file_util.h"
#include "webkit/browser/fileapi/quota/quota_reservation.h"
#include "webkit/common/fileapi/file_system_util.h"

namespace fileapi {

class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap {
 public:
  explicit FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner)
      : task_runner_(task_runner) {}
  ~FileSystemIDToPluginMap() {}

  std::string GetPluginIDForURL(const FileSystemURL& url) {
    DCHECK(task_runner_->RunsTasksOnCurrentThread());
    Map::iterator found = map_.find(url.filesystem_id());
    if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) {
      NOTREACHED() << "Unsupported url is given: " << url.DebugString();
      return std::string();
    }
    return found->second;
  }

  void RegisterFileSystem(const std::string& filesystem_id,
                          const std::string& plugin_id) {
    DCHECK(task_runner_->RunsTasksOnCurrentThread());
    DCHECK(!filesystem_id.empty());
    DCHECK(!ContainsKey(map_, filesystem_id)) << filesystem_id;
    map_[filesystem_id] = plugin_id;
  }

  void RemoveFileSystem(const std::string& filesystem_id) {
    DCHECK(task_runner_->RunsTasksOnCurrentThread());
    map_.erase(filesystem_id);
  }

 private:
  typedef std::map<std::string, std::string> Map;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  Map map_;
};

namespace {

const base::FilePath::CharType* kFileSystemDirectory =
    SandboxFileSystemBackendDelegate::kFileSystemDirectory;
const base::FilePath::CharType* kPluginPrivateDirectory =
    FILE_PATH_LITERAL("Plugins");

base::File::Error OpenFileSystemOnFileTaskRunner(
    ObfuscatedFileUtil* file_util,
    PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map,
    const GURL& origin_url,
    const std::string& filesystem_id,
    const std::string& plugin_id,
    OpenFileSystemMode mode) {
  base::File::Error error = base::File::FILE_ERROR_FAILED;
  const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
  file_util->GetDirectoryForOriginAndType(
      origin_url, plugin_id, create, &error);
  if (error == base::File::FILE_OK)
    plugin_map->RegisterFileSystem(filesystem_id, plugin_id);
  return error;
}

}  // namespace

PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend(
    base::SequencedTaskRunner* file_task_runner,
    const base::FilePath& profile_path,
    quota::SpecialStoragePolicy* special_storage_policy,
    const FileSystemOptions& file_system_options)
    : file_task_runner_(file_task_runner),
      file_system_options_(file_system_options),
      base_path_(profile_path.Append(
          kFileSystemDirectory).Append(kPluginPrivateDirectory)),
      plugin_map_(new FileSystemIDToPluginMap(file_task_runner)),
      weak_factory_(this) {
  file_util_.reset(
      new AsyncFileUtilAdapter(new ObfuscatedFileUtil(
          special_storage_policy,
          base_path_, file_system_options.env_override(),
          file_task_runner,
          base::Bind(&FileSystemIDToPluginMap::GetPluginIDForURL,
                     base::Owned(plugin_map_)),
          std::set<std::string>(),
          NULL)));
}

PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() {
  if (!file_task_runner_->RunsTasksOnCurrentThread()) {
    AsyncFileUtil* file_util = file_util_.release();
    if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util))
      delete file_util;
  }
}

void PluginPrivateFileSystemBackend::OpenPrivateFileSystem(
    const GURL& origin_url,
    FileSystemType type,
    const std::string& filesystem_id,
    const std::string& plugin_id,
    OpenFileSystemMode mode,
    const StatusCallback& callback) {
  if (!CanHandleType(type) || file_system_options_.is_incognito()) {
    base::MessageLoopProxy::current()->PostTask(
        FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_SECURITY));
    return;
  }

  PostTaskAndReplyWithResult(
      file_task_runner_.get(),
      FROM_HERE,
      base::Bind(&OpenFileSystemOnFileTaskRunner,
                 obfuscated_file_util(), plugin_map_,
                 origin_url, filesystem_id, plugin_id, mode),
      callback);
}

bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const {
  return type == kFileSystemTypePluginPrivate;
}

void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) {
}

void PluginPrivateFileSystemBackend::ResolveURL(
    const FileSystemURL& url,
    OpenFileSystemMode mode,
    const OpenFileSystemCallback& callback) {
  // We never allow opening a new plugin-private filesystem via usual
  // ResolveURL.
  base::MessageLoopProxy::current()->PostTask(
      FROM_HERE,
      base::Bind(callback, GURL(), std::string(),
                 base::File::FILE_ERROR_SECURITY));
}

AsyncFileUtil*
PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
  return file_util_.get();
}

CopyOrMoveFileValidatorFactory*
PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
    FileSystemType type,
    base::File::Error* error_code) {
  DCHECK(error_code);
  *error_code = base::File::FILE_OK;
  return NULL;
}

FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation(
    const FileSystemURL& url,
    FileSystemContext* context,
    base::File::Error* error_code) const {
  scoped_ptr<FileSystemOperationContext> operation_context(
      new FileSystemOperationContext(context));
  return FileSystemOperation::Create(url, context, operation_context.Pass());
}

bool PluginPrivateFileSystemBackend::SupportsStreaming(
    const fileapi::FileSystemURL& url) const {
  return false;
}

scoped_ptr<webkit_blob::FileStreamReader>
PluginPrivateFileSystemBackend::CreateFileStreamReader(
    const FileSystemURL& url,
    int64 offset,
    const base::Time& expected_modification_time,
    FileSystemContext* context) const {
  return scoped_ptr<webkit_blob::FileStreamReader>();
}

scoped_ptr<FileStreamWriter>
PluginPrivateFileSystemBackend::CreateFileStreamWriter(
    const FileSystemURL& url,
    int64 offset,
    FileSystemContext* context) const {
  return scoped_ptr<FileStreamWriter>();
}

FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
  return this;
}

base::File::Error
PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner(
    FileSystemContext* context,
    quota::QuotaManagerProxy* proxy,
    const GURL& origin_url,
    FileSystemType type) {
  if (!CanHandleType(type))
    return base::File::FILE_ERROR_SECURITY;
  bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
      origin_url, std::string());
  if (result)
    return base::File::FILE_OK;
  return base::File::FILE_ERROR_FAILED;
}

void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner(
    FileSystemType type,
    std::set<GURL>* origins) {
  if (!CanHandleType(type))
    return;
  scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
      obfuscated_file_util()->CreateOriginEnumerator());
  GURL origin;
  while (!(origin = enumerator->Next()).is_empty())
    origins->insert(origin);
}

void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner(
    FileSystemType type,
    const std::string& host,
    std::set<GURL>* origins) {
  if (!CanHandleType(type))
    return;
  scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
      obfuscated_file_util()->CreateOriginEnumerator());
  GURL origin;
  while (!(origin = enumerator->Next()).is_empty()) {
    if (host == net::GetHostOrSpecFromURL(origin))
      origins->insert(origin);
  }
}

int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner(
    FileSystemContext* context,
    const GURL& origin_url,
    FileSystemType type) {
  // We don't track usage on this filesystem.
  return 0;
}

scoped_refptr<QuotaReservation>
PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner(
    const GURL& origin_url,
    FileSystemType type) {
  // We don't track usage on this filesystem.
  NOTREACHED();
  return scoped_refptr<QuotaReservation>();
}

void PluginPrivateFileSystemBackend::AddFileUpdateObserver(
    FileSystemType type,
    FileUpdateObserver* observer,
    base::SequencedTaskRunner* task_runner) {}

void PluginPrivateFileSystemBackend::AddFileChangeObserver(
    FileSystemType type,
    FileChangeObserver* observer,
    base::SequencedTaskRunner* task_runner) {}

void PluginPrivateFileSystemBackend::AddFileAccessObserver(
    FileSystemType type,
    FileAccessObserver* observer,
    base::SequencedTaskRunner* task_runner) {}

const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
    FileSystemType type) const {
  return NULL;
}

const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
    FileSystemType type) const {
  return NULL;
}

const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
    FileSystemType type) const {
  return NULL;
}

ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
  return static_cast<ObfuscatedFileUtil*>(
      static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
}

}  // namespace fileapi

/* [<][>][^][v][top][bottom][index][help] */