15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath::StringType GetRegisterNameForPath(const base::FilePath& path) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If it's not a root path simply return a base name.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.DirName() != path)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return path.BaseName().value();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(FILE_PATH_USES_DRIVE_LETTERS)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType name;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0;
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       i < path.value().size() && !base::FilePath::IsSeparator(path.value()[i]);
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       ++i) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (path.value()[i] == L':') {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name.append(L"_drive");
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name.append(1, path.value()[i]);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return name;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FILE_PATH_LITERAL("<root>");
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSinglePathIsolatedFileSystem(FileSystemType type) {
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK_NE(kFileSystemTypeUnknown, type);
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // As of writing dragged file system is the only filesystem which could have
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // multiple top-level paths.
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return type != kFileSystemTypeDragged;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::FileInfoSet::FileInfoSet() {}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::FileInfoSet::~FileInfoSet() {}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::FileInfoSet::AddPath(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path, std::string* registered_name) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The given path should not contain any '..' and should be absolute.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.ReferencesParent() || !path.IsAbsolute())
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType name = GetRegisterNameForPath(path);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string utf8name = base::FilePath(name).AsUTF8Unsafe();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath normalized_path = path.NormalizePathSeparators();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool inserted =
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileset_.insert(MountPointInfo(utf8name, normalized_path)).second;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!inserted) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int suffix = 1;
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string basepart =
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::FilePath(name).RemoveExtension().AsUTF8Unsafe();
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string ext =
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::FilePath(base::FilePath(name).Extension()).AsUTF8Unsafe();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!inserted) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ext.empty())
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        utf8name.append(ext);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inserted =
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          fileset_.insert(MountPointInfo(utf8name, normalized_path)).second;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (registered_name)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *registered_name = utf8name;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::FileInfoSet::AddPathWithName(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path, const std::string& name) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The given path should not contain any '..' and should be absolute.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.ReferencesParent() || !path.IsAbsolute())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return fileset_.insert(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MountPointInfo(name, path.NormalizePathSeparators())).second;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//--------------------------------------------------------------------------
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IsolatedContext::Instance {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  enum PathType {
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PLATFORM_PATH,
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    VIRTUAL_PATH
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For a single-path isolated file system, which could be registered by
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // IsolatedContext::RegisterFileSystemForPath() or
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // IsolatedContext::RegisterFileSystemForVirtualPath().
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most of isolated file system contexts should be of this type.
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  Instance(FileSystemType type,
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)           const std::string& filesystem_id,
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)           const MountPointInfo& file_info,
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           PathType path_type);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For a multi-paths isolated file system.  As of writing only file system
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // type which could have multi-paths is Dragged file system, and
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // could be registered by IsolatedContext::RegisterDraggedFileSystem().
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Instance(FileSystemType type, const std::set<MountPointInfo>& files);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Instance();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemType type() const { return type_; }
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const std::string& filesystem_id() const { return filesystem_id_; }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const MountPointInfo& file_info() const { return file_info_; }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::set<MountPointInfo>& files() const { return files_; }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ref_counts() const { return ref_counts_; }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddRef() { ++ref_counts_; }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveRef() { --ref_counts_; }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ResolvePathForName(const std::string& name, base::FilePath* path) const;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the instance is a single-path instance.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSinglePathInstance() const;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemType type_;
1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const std::string filesystem_id_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For single-path instance.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const MountPointInfo file_info_;
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const PathType path_type_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For multiple-path instance (e.g. dragged file system).
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::set<MountPointInfo> files_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reference counts. Note that an isolated filesystem is created with ref==0
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and will get deleted when the ref count reaches <=0.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ref_counts_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Instance);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::Instance::Instance(FileSystemType type,
1546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                    const std::string& filesystem_id,
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    const MountPointInfo& file_info,
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                    Instance::PathType path_type)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(type),
1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      filesystem_id_(filesystem_id),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_info_(file_info),
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      path_type_(path_type),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ref_counts_(0) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsSinglePathIsolatedFileSystem(type_));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::Instance::Instance(FileSystemType type,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::set<MountPointInfo>& files)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(type),
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      path_type_(PLATFORM_PATH),
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      files_(files),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ref_counts_(0) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsSinglePathIsolatedFileSystem(type_));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::Instance::~Instance() {}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   base::FilePath* path) const {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSinglePathIsolatedFileSystem(type_)) {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    switch (path_type_) {
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      case PLATFORM_PATH:
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        *path = file_info_.path;
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        break;
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      case VIRTUAL_PATH:
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        *path = base::FilePath();
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        break;
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      default:
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NOTREACHED();
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_info_.name == name;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<MountPointInfo>::const_iterator found = files_.find(
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MountPointInfo(name, base::FilePath()));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == files_.end())
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *path = found->path;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::Instance::IsSinglePathInstance() const {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsSinglePathIsolatedFileSystem(type_);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//--------------------------------------------------------------------------
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext* IsolatedContext::GetInstance() {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_isolated_context.Pointer();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::IsIsolatedType(FileSystemType type) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return type == kFileSystemTypeIsolated || type == kFileSystemTypeExternal;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IsolatedContext::RegisterDraggedFileSystem(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileInfoSet& files) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string filesystem_id = GetNewFileSystemId();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_map_[filesystem_id] = new Instance(
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFileSystemTypeDragged, files.fileset());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return filesystem_id;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IsolatedContext::RegisterFileSystemForPath(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileSystemType type,
2276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& filesystem_id,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path_in,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* register_name) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path(path_in.NormalizePathSeparators());
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (path.ReferencesParent() || !path.IsAbsolute())
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (register_name && !register_name->empty()) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = *register_name;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    name = base::FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (register_name)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      register_name->assign(name);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
2436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string new_id = GetNewFileSystemId();
2446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  instance_map_[new_id] = new Instance(type, filesystem_id,
2456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       MountPointInfo(name, path),
2466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       Instance::PLATFORM_PATH);
2476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  path_to_id_map_[path].insert(new_id);
2486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return new_id;
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string IsolatedContext::RegisterFileSystemForVirtualPath(
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    FileSystemType type,
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& register_name,
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::FilePath& cracked_path_prefix) {
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::AutoLock locker(lock_);
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath path(cracked_path_prefix.NormalizePathSeparators());
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (path.ReferencesParent())
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string();
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string filesystem_id = GetNewFileSystemId();
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  instance_map_[filesystem_id] = new Instance(
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      type,
2626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      std::string(),  // filesystem_id
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      MountPointInfo(register_name, cracked_path_prefix),
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      Instance::VIRTUAL_PATH);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path_to_id_map_[path].insert(filesystem_id);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return filesystem_id;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsolatedContext::HandlesFileSystemMountType(FileSystemType type) const {
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type == kFileSystemTypeIsolated;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock locker(lock_);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return UnregisterFileSystem(filesystem_id);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsolatedContext::GetRegisteredPath(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& filesystem_id, base::FilePath* path) const {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(path);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (found == instance_map_.end() || !found->second->IsSinglePathInstance())
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *path = found->second->file_info().path;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool IsolatedContext::CrackVirtualPath(
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::FilePath& virtual_path,
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string* id_or_name,
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FileSystemType* type,
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::string* cracked_id,
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::FilePath* path,
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FileSystemMountOption* mount_option) const {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(id_or_name);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(path);
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should not contain any '..' references.
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (virtual_path.ReferencesParent())
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the default mount option.
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  *mount_option = FileSystemMountOption();
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The virtual_path should comprise <id_or_name> and <relative_path> parts.
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath::StringType> components;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual_path.GetComponents(&components);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (components.size() < 1)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath::StringType>::iterator component_iter =
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      components.begin();
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string fsid = base::FilePath(*component_iter++).MaybeAsASCII();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (fsid.empty())
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath cracked_path;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::AutoLock locker(lock_);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (found_instance == instance_map_.end())
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *id_or_name = fsid;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Instance* instance = found_instance->second;
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (type)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *type = instance->type();
3276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (cracked_id)
3286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      *cracked_id = instance->filesystem_id();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (component_iter == components.end()) {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The virtual root case.
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      path->clear();
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // *component_iter should be a name of the registered path.
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string name = base::FilePath(*component_iter++).AsUTF8Unsafe();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!instance->ResolvePathForName(name, &cracked_path))
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (; component_iter != components.end(); ++component_iter)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cracked_path = cracked_path.Append(*component_iter);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *path = cracked_path;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL IsolatedContext::CrackURL(const GURL& url) const {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL filesystem_url = FileSystemURL(url);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!filesystem_url.is_valid())
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FileSystemURL();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(filesystem_url);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL IsolatedContext::CreateCrackedFileSystemURL(
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemType type,
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) const {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CrackFileSystemURL(FileSystemURL(origin, type, path));
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IsolatedContext::RevokeFileSystemByPath(const base::FilePath& path_in) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path(path_in.NormalizePathSeparators());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathToID::iterator ids_iter = path_to_id_map_.find(path);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ids_iter == path_to_id_map_.end())
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string>& ids = ids_iter->second;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::set<std::string>::iterator iter = ids.begin();
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != ids.end(); ++iter) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDToInstance::iterator found = instance_map_.find(*iter);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (found != instance_map_.end()) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete found->second;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_map_.erase(found);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path_to_id_map_.erase(ids_iter);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IsolatedContext::AddReference(const std::string& filesystem_id) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(instance_map_.find(filesystem_id) != instance_map_.end());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_map_[filesystem_id]->AddRef();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This could get called for non-existent filesystem if it has been
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already deleted by RevokeFileSystemByPath.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDToInstance::iterator found = instance_map_.find(filesystem_id);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == instance_map_.end())
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Instance* instance = found->second;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(instance->ref_counts(), 0);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance->RemoveRef();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (instance->ref_counts() == 0) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool deleted = UnregisterFileSystem(filesystem_id);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(deleted);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::GetDraggedFileInfo(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& filesystem_id,
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<MountPointInfo>* files) const {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(files);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == instance_map_.end() ||
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found->second->type() != kFileSystemTypeDragged)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  files->assign(found->second->files().begin(),
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                found->second->files().end());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath IsolatedContext::CreateVirtualRootPath(
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& filesystem_id) const {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath().AppendASCII(filesystem_id);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::IsolatedContext() {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IsolatedContext::~IsolatedContext() {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(instance_map_.begin(),
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       instance_map_.end());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL IsolatedContext::CrackFileSystemURL(
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url) const {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HandlesFileSystemMountType(url.type()))
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FileSystemURL();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string mount_name;
4356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string cracked_mount_name;
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemType cracked_type;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath cracked_path;
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemMountOption cracked_mount_option;
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!CrackVirtualPath(url.path(), &mount_name, &cracked_type,
4406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        &cracked_mount_name, &cracked_path,
4416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        &cracked_mount_option)) {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FileSystemURL();
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FileSystemURL(
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url.origin(), url.mount_type(), url.virtual_path(),
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !url.filesystem_id().empty() ? url.filesystem_id() : mount_name,
4486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      cracked_type, cracked_path,
4496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      cracked_mount_name.empty() ? mount_name : cracked_mount_name,
4506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      cracked_mount_option);
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsolatedContext::UnregisterFileSystem(const std::string& filesystem_id) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDToInstance::iterator found = instance_map_.find(filesystem_id);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found == instance_map_.end())
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Instance* instance = found->second;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance->IsSinglePathInstance()) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathToID::iterator ids_iter = path_to_id_map_.find(
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance->file_info().path);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ids_iter != path_to_id_map_.end());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids_iter->second.erase(filesystem_id);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ids_iter->second.empty())
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path_to_id_map_.erase(ids_iter);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete found->second;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_map_.erase(found);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IsolatedContext::GetNewFileSystemId() const {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns an arbitrary random string which must be unique in the map.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 random_data[4];
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::RandBytes(random_data, sizeof(random_data));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id = base::HexEncode(random_data, sizeof(random_data));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (instance_map_.find(id) != instance_map_.end());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
485