Home | History | Annotate | Download | only in fileapi
      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