1 // Copyright 2014 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 "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h" 6 7 #include "base/bind.h" 8 #include "base/files/file_path.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "chrome/browser/chromeos/drive/file_system_interface.h" 11 #include "chrome/browser/chromeos/drive/file_system_util.h" 12 #include "chrome/browser/chromeos/drive/fileapi/async_file_util.h" 13 #include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h" 14 #include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h" 15 #include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.h" 16 #include "chrome/browser/drive/drive_api_util.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "storage/browser/blob/file_stream_reader.h" 19 #include "storage/browser/fileapi/async_file_util.h" 20 #include "storage/browser/fileapi/file_system_context.h" 21 #include "storage/browser/fileapi/file_system_url.h" 22 23 using content::BrowserThread; 24 25 namespace drive { 26 namespace { 27 28 // Called on the UI thread after GetRedirectURLForContentsOnUIThread. Obtains 29 // the browser URL from |entry|. |callback| will be called on the IO thread. 30 void GetRedirectURLForContentsOnUIThreadWithResourceEntry( 31 const storage::URLCallback& callback, 32 FileError error, 33 scoped_ptr<ResourceEntry> entry) { 34 DCHECK_CURRENTLY_ON(BrowserThread::UI); 35 GURL url; 36 if (error == FILE_ERROR_OK && entry->has_file_specific_info() && 37 entry->file_specific_info().is_hosted_document()) { 38 url = GURL(entry->file_specific_info().alternate_url()); 39 } 40 BrowserThread::PostTask( 41 BrowserThread::IO, FROM_HERE, base::Bind(callback, url)); 42 } 43 44 // Called on the UI thread after 45 // FileSystemBackendDelegate::GetRedirectURLForContents. Requestes to obtain 46 // ResourceEntry for the |url|. 47 void GetRedirectURLForContentsOnUIThread( 48 const storage::FileSystemURL& url, 49 const storage::URLCallback& callback) { 50 DCHECK_CURRENTLY_ON(BrowserThread::UI); 51 FileSystemInterface* const file_system = 52 fileapi_internal::GetFileSystemFromUrl(url); 53 if (!file_system) { 54 BrowserThread::PostTask( 55 BrowserThread::IO, FROM_HERE, base::Bind(callback, GURL())); 56 return; 57 } 58 const base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url); 59 if (file_path.empty()) { 60 BrowserThread::PostTask( 61 BrowserThread::IO, FROM_HERE, base::Bind(callback, GURL())); 62 return; 63 } 64 65 file_system->GetResourceEntry( 66 file_path, 67 base::Bind(&GetRedirectURLForContentsOnUIThreadWithResourceEntry, 68 callback)); 69 } 70 71 } // namespace 72 73 FileSystemBackendDelegate::FileSystemBackendDelegate() 74 : async_file_util_(new internal::AsyncFileUtil) { 75 } 76 77 FileSystemBackendDelegate::~FileSystemBackendDelegate() { 78 } 79 80 storage::AsyncFileUtil* FileSystemBackendDelegate::GetAsyncFileUtil( 81 storage::FileSystemType type) { 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 83 DCHECK_EQ(storage::kFileSystemTypeDrive, type); 84 return async_file_util_.get(); 85 } 86 87 scoped_ptr<storage::FileStreamReader> 88 FileSystemBackendDelegate::CreateFileStreamReader( 89 const storage::FileSystemURL& url, 90 int64 offset, 91 int64 max_bytes_to_read, 92 const base::Time& expected_modification_time, 93 storage::FileSystemContext* context) { 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 95 DCHECK_EQ(storage::kFileSystemTypeDrive, url.type()); 96 97 base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url); 98 if (file_path.empty()) 99 return scoped_ptr<storage::FileStreamReader>(); 100 101 return scoped_ptr<storage::FileStreamReader>( 102 new internal::WebkitFileStreamReaderImpl( 103 base::Bind(&fileapi_internal::GetFileSystemFromUrl, url), 104 context->default_file_task_runner(), 105 file_path, 106 offset, 107 expected_modification_time)); 108 } 109 110 scoped_ptr<storage::FileStreamWriter> 111 FileSystemBackendDelegate::CreateFileStreamWriter( 112 const storage::FileSystemURL& url, 113 int64 offset, 114 storage::FileSystemContext* context) { 115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 116 DCHECK_EQ(storage::kFileSystemTypeDrive, url.type()); 117 118 base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url); 119 // Hosted documents don't support stream writer. 120 if (file_path.empty() || util::HasHostedDocumentExtension(file_path)) 121 return scoped_ptr<storage::FileStreamWriter>(); 122 123 return scoped_ptr<storage::FileStreamWriter>( 124 new internal::WebkitFileStreamWriterImpl( 125 base::Bind(&fileapi_internal::GetFileSystemFromUrl, url), 126 context->default_file_task_runner(), 127 file_path, 128 offset)); 129 } 130 131 storage::WatcherManager* FileSystemBackendDelegate::GetWatcherManager( 132 const storage::FileSystemURL& url) { 133 NOTIMPLEMENTED(); 134 return NULL; 135 } 136 137 void FileSystemBackendDelegate::GetRedirectURLForContents( 138 const storage::FileSystemURL& url, 139 const storage::URLCallback& callback) { 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); 141 BrowserThread::PostTask( 142 BrowserThread::UI, 143 FROM_HERE, 144 base::Bind(&GetRedirectURLForContentsOnUIThread, url, callback)); 145 } 146 147 } // namespace drive 148