Home | History | Annotate | Download | only in linux
      1 // Copyright 2013 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/media_galleries/linux/mtp_device_task_helper.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/media_galleries/linux/mtp_device_object_enumerator.h"
      9 #include "chrome/browser/media_galleries/linux/mtp_read_file_worker.h"
     10 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
     11 #include "chrome/browser/storage_monitor/storage_monitor.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h"
     14 #include "third_party/cros_system_api/dbus/service_constants.h"
     15 #include "webkit/browser/fileapi/async_file_util.h"
     16 #include "webkit/common/fileapi/file_system_util.h"
     17 
     18 namespace chrome {
     19 
     20 namespace {
     21 
     22 // Does nothing.
     23 // This method is used to handle the results of
     24 // MediaTransferProtocolManager::CloseStorage method call.
     25 void DoNothing(bool error) {
     26 }
     27 
     28 device::MediaTransferProtocolManager* GetMediaTransferProtocolManager() {
     29   return StorageMonitor::GetInstance()->media_transfer_protocol_manager();
     30 }
     31 
     32 }  // namespace
     33 
     34 MTPDeviceTaskHelper::MTPDeviceTaskHelper()
     35     : weak_ptr_factory_(this) {
     36   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     37 }
     38 
     39 MTPDeviceTaskHelper::~MTPDeviceTaskHelper() {
     40   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     41 }
     42 
     43 void MTPDeviceTaskHelper::OpenStorage(const std::string& storage_name,
     44                                       const OpenStorageCallback& callback) {
     45   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     46   DCHECK(!storage_name.empty());
     47   if (!device_handle_.empty()) {
     48     content::BrowserThread::PostTask(content::BrowserThread::IO,
     49                                      FROM_HERE,
     50                                      base::Bind(callback, true));
     51     return;
     52   }
     53   GetMediaTransferProtocolManager()->OpenStorage(
     54       storage_name, mtpd::kReadOnlyMode,
     55       base::Bind(&MTPDeviceTaskHelper::OnDidOpenStorage,
     56                  weak_ptr_factory_.GetWeakPtr(),
     57                  callback));
     58 }
     59 
     60 void MTPDeviceTaskHelper::GetFileInfoByPath(
     61     const std::string& file_path,
     62     const GetFileInfoSuccessCallback& success_callback,
     63     const ErrorCallback& error_callback) {
     64   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     65   if (device_handle_.empty())
     66     return HandleDeviceError(error_callback, base::PLATFORM_FILE_ERROR_FAILED);
     67 
     68   GetMediaTransferProtocolManager()->GetFileInfoByPath(
     69       device_handle_, file_path,
     70       base::Bind(&MTPDeviceTaskHelper::OnGetFileInfo,
     71                  weak_ptr_factory_.GetWeakPtr(),
     72                  success_callback,
     73                  error_callback));
     74 }
     75 
     76 void MTPDeviceTaskHelper::ReadDirectoryByPath(
     77     const std::string& dir_path,
     78     const ReadDirectorySuccessCallback& success_callback,
     79     const ErrorCallback& error_callback) {
     80   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     81   if (device_handle_.empty())
     82     return HandleDeviceError(error_callback, base::PLATFORM_FILE_ERROR_FAILED);
     83 
     84   GetMediaTransferProtocolManager()->ReadDirectoryByPath(
     85       device_handle_, dir_path,
     86       base::Bind(&MTPDeviceTaskHelper::OnDidReadDirectoryByPath,
     87                  weak_ptr_factory_.GetWeakPtr(),
     88                  success_callback,
     89                  error_callback));
     90 }
     91 
     92 void MTPDeviceTaskHelper::WriteDataIntoSnapshotFile(
     93     const SnapshotRequestInfo& request_info,
     94     const base::PlatformFileInfo& snapshot_file_info) {
     95   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     96   if (device_handle_.empty()) {
     97     return HandleDeviceError(request_info.error_callback,
     98                              base::PLATFORM_FILE_ERROR_FAILED);
     99   }
    100 
    101   if (!read_file_worker_)
    102     read_file_worker_.reset(new MTPReadFileWorker(device_handle_));
    103   read_file_worker_->WriteDataIntoSnapshotFile(request_info,
    104                                                snapshot_file_info);
    105 }
    106 
    107 void MTPDeviceTaskHelper::CloseStorage() const {
    108   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    109   if (device_handle_.empty())
    110     return;
    111   GetMediaTransferProtocolManager()->CloseStorage(device_handle_,
    112                                                   base::Bind(&DoNothing));
    113 }
    114 
    115 void MTPDeviceTaskHelper::OnDidOpenStorage(
    116     const OpenStorageCallback& completion_callback,
    117     const std::string& device_handle,
    118     bool error) {
    119   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    120   device_handle_ = device_handle;
    121   content::BrowserThread::PostTask(content::BrowserThread::IO,
    122                                    FROM_HERE,
    123                                    base::Bind(completion_callback, !error));
    124 }
    125 
    126 void MTPDeviceTaskHelper::OnGetFileInfo(
    127     const GetFileInfoSuccessCallback& success_callback,
    128     const ErrorCallback& error_callback,
    129     const MtpFileEntry& file_entry,
    130     bool error) const {
    131   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    132   if (error) {
    133     return HandleDeviceError(error_callback,
    134                              base::PLATFORM_FILE_ERROR_NOT_FOUND);
    135   }
    136 
    137   base::PlatformFileInfo file_entry_info;
    138   file_entry_info.size = file_entry.file_size();
    139   file_entry_info.is_directory =
    140       file_entry.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
    141   file_entry_info.is_symbolic_link = false;
    142   file_entry_info.last_modified =
    143       base::Time::FromTimeT(file_entry.modification_time());
    144   file_entry_info.last_accessed = file_entry_info.last_modified;
    145   file_entry_info.creation_time = base::Time();
    146   content::BrowserThread::PostTask(content::BrowserThread::IO,
    147                                    FROM_HERE,
    148                                    base::Bind(success_callback,
    149                                               file_entry_info));
    150 }
    151 
    152 void MTPDeviceTaskHelper::OnDidReadDirectoryByPath(
    153     const ReadDirectorySuccessCallback& success_callback,
    154     const ErrorCallback& error_callback,
    155     const std::vector<MtpFileEntry>& file_entries,
    156     bool error) const {
    157   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    158   if (error)
    159     return HandleDeviceError(error_callback, base::PLATFORM_FILE_ERROR_FAILED);
    160 
    161   fileapi::AsyncFileUtil::EntryList entries;
    162   base::FilePath current;
    163   MTPDeviceObjectEnumerator file_enum(file_entries);
    164   while (!(current = file_enum.Next()).empty()) {
    165     fileapi::DirectoryEntry entry;
    166     entry.name = fileapi::VirtualPath::BaseName(current).value();
    167     entry.is_directory = file_enum.IsDirectory();
    168     entry.size = file_enum.Size();
    169     entry.last_modified_time = file_enum.LastModifiedTime();
    170     entries.push_back(entry);
    171   }
    172   content::BrowserThread::PostTask(content::BrowserThread::IO,
    173                                    FROM_HERE,
    174                                    base::Bind(success_callback, entries));
    175 }
    176 
    177 void MTPDeviceTaskHelper::HandleDeviceError(
    178     const ErrorCallback& error_callback,
    179     base::PlatformFileError error) const {
    180   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    181   content::BrowserThread::PostTask(content::BrowserThread::IO,
    182                                    FROM_HERE,
    183                                    base::Bind(error_callback, error));
    184 }
    185 
    186 }  // namespace chrome
    187