15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/files/file_path.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/task_runner_util.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/threading/sequenced_worker_pool.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/drive.pb.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/file_errors.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/file_system_interface.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/file_system_util.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/directory_entry.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing content::BrowserThread; 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace fileapi_internal { 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The summary of opening mode is: 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// - File::FLAG_OPEN: Open the existing file. Fail if not exists. 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// - File::FLAG_CREATE: Create the file if not exists. Fail if exists. 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// - File::FLAG_OPEN_ALWAYS: Open the existing file. Create a new file 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// if not exists. 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// - File::FLAG_CREATE_ALWAYS: Create a new file if not exists. If exists 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// open it with truncate. 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// - File::FLAG_OPEN_TRUNCATE: Open the existing file with truncate. 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Fail if not exists. 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochOpenMode GetOpenMode(int file_flag) { 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_flag & (base::File::FLAG_OPEN | base::File::FLAG_OPEN_TRUNCATED)) 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return OPEN_FILE; 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_flag & base::File::FLAG_CREATE) 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return CREATE_FILE; 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(file_flag & 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_CREATE_ALWAYS)); 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return OPEN_OR_CREATE_FILE; 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Runs |callback| with the File::Error converted from |error|. 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunStatusCallbackByFileError(const StatusCallback& callback, 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileError error) { 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(FileErrorToBaseFileError(error)); 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Runs |callback| with arguments converted from |error| and |entry|. 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunGetFileInfoCallback(const GetFileInfoCallback& callback, 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FileError error, 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<ResourceEntry> entry) { 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error != FILE_ERROR_OK) { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(FileErrorToBaseFileError(error), base::File::Info()); 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(entry); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info file_info; 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConvertResourceEntryToFileInfo(*entry, &file_info); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK, file_info); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Runs |callback| with entries. 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid RunReadDirectoryCallbackWithEntries( 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ReadDirectoryCallback& callback, 71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_ptr<ResourceEntryVector> resource_entries) { 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(resource_entries); 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<storage::DirectoryEntry> entries; 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Convert drive files to File API's directory entry. 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entries.reserve(resource_entries->size()); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < resource_entries->size(); ++i) { 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ResourceEntry& resource_entry = (*resource_entries)[i]; 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::DirectoryEntry entry; 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry.name = resource_entry.base_name(); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const PlatformFileInfoProto& file_info = resource_entry.file_info(); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry.is_directory = file_info.is_directory(); 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry.size = file_info.size(); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entry.last_modified_time = 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Time::FromInternalValue(file_info.last_modified()); 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch entries.push_back(entry); 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.Run(base::File::FILE_OK, entries, true /*has_more*/); 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Runs |callback| with |error|. 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid RunReadDirectoryCallbackOnCompletion(const ReadDirectoryCallback& callback, 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FileError error) { 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.Run(FileErrorToBaseFileError(error), 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<storage::DirectoryEntry>(), 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) false /*has_more*/); 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Runs |callback| with arguments based on |error|, |local_path| and |entry|. 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunCreateSnapshotFileCallback(const CreateSnapshotFileCallback& callback, 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileError error, 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::FilePath& local_path, 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<ResourceEntry> entry) { 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error != FILE_ERROR_OK) { 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback.Run(FileErrorToBaseFileError(error), 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::File::Info(), 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::FilePath(), 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::ScopedFile::ScopeOutPolicy()); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(entry); 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // When reading file, last modified time specified in file info will be 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // compared to the last modified time of the local version of the drive file. 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Since those two values don't generally match (last modification time on the 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // drive server vs. last modification time of the local, downloaded file), so 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // we have to opt out from this check. We do this by unsetting last_modified 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // value in the file info passed to the CreateSnapshot caller. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info file_info; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConvertResourceEntryToFileInfo(*entry, &file_info); 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_info.last_modified = base::Time(); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If the file is a hosted document, a temporary JSON file is created to 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // represent the document. The JSON file is not cached and its lifetime 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // is managed by ShareableFileReference. 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::ScopedFile::ScopeOutPolicy scope_out_policy = 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) entry->file_specific_info().is_hosted_document() 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ? storage::ScopedFile::DELETE_ON_SCOPE_OUT 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : storage::ScopedFile::DONT_DELETE_ON_SCOPE_OUT; 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK, file_info, local_path, scope_out_policy); 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Runs |callback| with arguments converted from |error| and |local_path|. 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid RunCreateWritableSnapshotFileCallback( 139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const CreateWritableSnapshotFileCallback& callback, 140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FileError error, 141a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::FilePath& local_path, 142a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::Closure& close_callback) { 143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(FileErrorToBaseFileError(error), local_path, close_callback); 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Runs |callback| with |file|. 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunOpenFileCallback(const OpenFileCallback& callback, 149a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::Closure& close_callback, 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File file) { 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(file.Pass(), close_callback); 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbase::File OpenFile(const base::FilePath& path, int flags) { 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base::File(path, flags); 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Part of OpenFile(). Called after FileSystem::OpenFile(). 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OpenFileAfterFileSystemOpenFile(int file_flags, 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const OpenFileCallback& callback, 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileError error, 162a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::FilePath& local_path, 163a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::Closure& close_callback) { 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error != FILE_ERROR_OK) { 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(base::File(FileErrorToBaseFileError(error)), base::Closure()); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Here, the file should be at |local_path|, but there may be timing issue. 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Because the file is managed by Drive file system, so, in order to avoid 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // unexpected file creation, CREATE, OPEN_ALWAYS and CREATE_ALWAYS are 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // translated into OPEN or OPEN_TRUNCATED, here. Keep OPEN and OPEN_TRUNCATED 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // as is. 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (file_flags & (base::File::FLAG_CREATE | 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_OPEN_ALWAYS)) { 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch file_flags &= ~(base::File::FLAG_CREATE | 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_OPEN_ALWAYS); 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch file_flags |= base::File::FLAG_OPEN; 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (file_flags & base::File::FLAG_CREATE_ALWAYS) { 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch file_flags &= ~base::File::FLAG_CREATE_ALWAYS; 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch file_flags |= base::File::FLAG_OPEN_TRUNCATED; 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Cache file prepared for modification is available. Open it locally. 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool posted = base::PostTaskAndReplyWithResult( 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BrowserThread::GetBlockingPool(), FROM_HERE, 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&OpenFile, local_path, file_flags), 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&RunOpenFileCallback, callback, close_callback)); 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(posted); 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)FileSystemInterface* GetFileSystemFromUrl(const storage::FileSystemURL& url) { 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* profile = util::ExtractProfileFromPath(url.path()); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return profile ? util::GetFileSystemByProfile(profile) : NULL; 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunFileSystemCallback( 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const FileSystemGetter& file_system_getter, 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Callback<void(FileSystemInterface*)>& callback, 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Closure& on_error_callback) { 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system = file_system_getter.Run(); 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!file_system) { 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!on_error_callback.is_null()) 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch on_error_callback.Run(); 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(file_system); 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GetFileInfo(const base::FilePath& file_path, 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const GetFileInfoCallback& callback, 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system->GetResourceEntry( 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_path, 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&RunGetFileInfoCallback, callback)); 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid Copy(const base::FilePath& src_file_path, 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::FilePath& dest_file_path, 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool preserve_last_modified, 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_system->Copy(src_file_path, dest_file_path, preserve_last_modified, 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid Move(const base::FilePath& src_file_path, 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::FilePath& dest_file_path, 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_system->Move(src_file_path, dest_file_path, 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CopyInForeignFile(const base::FilePath& src_foreign_file_path, 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::FilePath& dest_file_path, 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->TransferFileFromLocalToRemote( 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch src_foreign_file_path, dest_file_path, 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ReadDirectory(const base::FilePath& file_path, 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ReadDirectoryCallback& callback, 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_system->ReadDirectory( 262a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_path, 263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&RunReadDirectoryCallbackWithEntries, callback), 264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&RunReadDirectoryCallbackOnCompletion, callback)); 265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid Remove(const base::FilePath& file_path, 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_recursive, 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->Remove(file_path, is_recursive, 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CreateDirectory(const base::FilePath& file_path, 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_exclusive, 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_recursive, 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->CreateDirectory( 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_path, is_exclusive, is_recursive, 284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CreateFile(const base::FilePath& file_path, 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_exclusive, 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->CreateFile(file_path, is_exclusive, 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string(), // no mime type; guess from file_path 2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid Truncate(const base::FilePath& file_path, 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 length, 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->TruncateFile( 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_path, length, 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CreateSnapshotFile(const base::FilePath& file_path, 3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const CreateSnapshotFileCallback& callback, 3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system->GetFile(file_path, 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&RunCreateSnapshotFileCallback, callback)); 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid CreateWritableSnapshotFile( 316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& file_path, 317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const CreateWritableSnapshotFileCallback& callback, 318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FileSystemInterface* file_system) { 319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch file_system->OpenFile( 321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch file_path, 322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch OPEN_FILE, 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string(), // no mime type; we never create a new file here. 324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&RunCreateWritableSnapshotFileCallback, callback)); 325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OpenFile(const base::FilePath& file_path, 3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int file_flags, 3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const OpenFileCallback& callback, 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Returns an error if any unsupported flag is found. 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_flags & ~(base::File::FLAG_OPEN | 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_CREATE | 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_OPEN_ALWAYS | 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_CREATE_ALWAYS | 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_OPEN_TRUNCATED | 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_READ | 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_WRITE | 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_WRITE_ATTRIBUTES | 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FLAG_APPEND)) { 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::MessageLoopProxy::current()->PostTask( 3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FROM_HERE, 3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(callback, 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Passed(base::File(base::File::FILE_ERROR_FAILED)), 347a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch base::Closure())); 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->OpenFile( 3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_path, GetOpenMode(file_flags), 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string(), // no mime type; guess from file_path 3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&OpenFileAfterFileSystemOpenFile, file_flags, callback)); 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TouchFile(const base::FilePath& file_path, 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Time& last_access_time, 3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Time& last_modified_time, 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const StatusCallback& callback, 3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemInterface* file_system) { 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system->TouchFile(file_path, last_access_time, last_modified_time, 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RunStatusCallbackByFileError, callback)); 365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace fileapi_internal 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 370