Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Unified Diff: chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc

Issue 2358493002: Remove MTP support on Linux. (Closed)
Patch Set: move files Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
deleted file mode 100644
index 1c6b4b5ae3486c6553078b8d931860a01f0d47d8..0000000000000000000000000000000000000000
--- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
+++ /dev/null
@@ -1,1899 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-
-#include <algorithm>
-#include <limits>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.h"
-#include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
-#include "net/base/io_buffer.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
-
-namespace {
-
-// File path separator constant.
-const char kRootPath[] = "/";
-
-// Returns the device relative file path given |file_path|.
-// E.g.: If the |file_path| is "/usb:2,2:12345/DCIM" and |registered_dev_path|
-// is "/usb:2,2:12345", this function returns the device relative path which is
-// "DCIM".
-// In the special case when |registered_dev_path| and |file_path| are the same,
-// return |kRootPath|.
-std::string GetDeviceRelativePath(const base::FilePath& registered_dev_path,
- const base::FilePath& file_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!registered_dev_path.empty());
- DCHECK(!file_path.empty());
- std::string result;
- if (registered_dev_path == file_path) {
- result = kRootPath;
- } else {
- base::FilePath relative_path;
- if (registered_dev_path.AppendRelativePath(file_path, &relative_path)) {
- DCHECK(!relative_path.empty());
- result = relative_path.value();
- }
- }
- return result;
-}
-
-// Returns the MTPDeviceTaskHelper object associated with the MTP device
-// storage.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// Returns NULL if the |storage_name| is no longer valid (e.g. because the
-// corresponding storage device is detached, etc).
-MTPDeviceTaskHelper* GetDeviceTaskHelperForStorage(
- const std::string& storage_name,
- const bool read_only) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- return MTPDeviceTaskHelperMapService::GetInstance()->GetDeviceTaskHelper(
- storage_name,
- read_only);
-}
-
-// Opens the storage device for communication.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |reply_callback| is called when the OpenStorage request completes.
-// |reply_callback| runs on the IO thread.
-void OpenStorageOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const MTPDeviceTaskHelper::OpenStorageCallback& reply_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper) {
- task_helper =
- MTPDeviceTaskHelperMapService::GetInstance()->CreateDeviceTaskHelper(
- storage_name, read_only);
- }
- task_helper->OpenStorage(storage_name, read_only, reply_callback);
-}
-
-// Creates |directory_name| on |parent_id|.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |parent_id| is an object id of the parent directory.
-// |directory_name| is name of the new directory.
-// |success_callback| is called when the directory is created successfully.
-// |error_callback| is called when it fails to create a directory.
-// |success_callback| and |error_callback| runs on the IO thread.
-void CreateDirectoryOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const uint32_t parent_id,
- const std::string& directory_name,
- const MTPDeviceTaskHelper::CreateDirectorySuccessCallback& success_callback,
- const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->CreateDirectory(parent_id, directory_name, success_callback,
- error_callback);
-}
-
-// Enumerates the |dir_id| directory file entries.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |directory_id| is an id of a directory to read.
-// |max_size| is a maximum size to read. Set 0 not to specify the maximum size.
-// |success_callback| is called when the ReadDirectory request succeeds.
-// |error_callback| is called when the ReadDirectory request fails.
-// |success_callback| and |error_callback| runs on the IO thread.
-void ReadDirectoryOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const uint32_t directory_id,
- const size_t max_size,
- const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback,
- const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->ReadDirectory(directory_id, max_size, success_callback,
- error_callback);
-}
-
-// Gets the |file_path| details.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |success_callback| is called when the GetFileInfo request succeeds.
-// |error_callback| is called when the GetFileInfo request fails.
-// |success_callback| and |error_callback| runs on the IO thread.
-void GetFileInfoOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- uint32_t file_id,
- const MTPDeviceTaskHelper::GetFileInfoSuccessCallback& success_callback,
- const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->GetFileInfo(file_id, success_callback, error_callback);
-}
-
-// Copies the contents of |device_file_path| to |snapshot_file_path|.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |device_file_path| specifies the media device file path.
-// |snapshot_file_path| specifies the platform path of the snapshot file.
-// |file_size| specifies the number of bytes that will be written to the
-// snapshot file.
-// |success_callback| is called when the copy operation succeeds.
-// |error_callback| is called when the copy operation fails.
-// |success_callback| and |error_callback| runs on the IO thread.
-void WriteDataIntoSnapshotFileOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const SnapshotRequestInfo& request_info,
- const base::File::Info& snapshot_file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->WriteDataIntoSnapshotFile(request_info, snapshot_file_info);
-}
-
-// Copies the contents of |device_file_path| to |snapshot_file_path|.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |request| is a struct containing details about the byte read request.
-void ReadBytesOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const MTPDeviceAsyncDelegate::ReadBytesRequest& request) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->ReadBytes(request);
-}
-
-// Renames |object_id| to |new_name|.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |object_id| is an id of object to be renamed.
-// |new_name| is new name of the object.
-// |success_callback| is called when the object is renamed successfully.
-// |error_callback| is called when it fails to rename the object.
-// |success_callback| and |error_callback| runs on the IO thread.
-void RenameObjectOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const uint32_t object_id,
- const std::string& new_name,
- const MTPDeviceTaskHelper::RenameObjectSuccessCallback& success_callback,
- const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->RenameObject(object_id, new_name, success_callback,
- error_callback);
-}
-
-// Copies the file |source_file_descriptor| to |file_name| in |parent_id|.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |source_file_descriptor| file descriptor of source file.
-// |parent_id| object id of a target directory.
-// |file_name| file name of a target file.
-// |success_callback| is called when the file is copied successfully.
-// |error_callback| is called when it fails to copy file.
-// Since this method does not close the file descriptor, callbacks are
-// responsible for closing it.
-void CopyFileFromLocalOnUIThread(
- const std::string& storage_name,
- const bool read_only,
- const int source_file_descriptor,
- const uint32_t parent_id,
- const std::string& file_name,
- const MTPDeviceTaskHelper::CopyFileFromLocalSuccessCallback&
- success_callback,
- const MTPDeviceTaskHelper::ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->CopyFileFromLocal(storage_name, source_file_descriptor,
- parent_id, file_name, success_callback,
- error_callback);
-}
-
-// Deletes |object_id|.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-//
-// |storage_name| specifies the name of the storage device.
-// |read_only| specifies the mode of the storage device.
-// |object_id| is the object to be deleted.
-// |success_callback| is called when the object is deleted successfully.
-// |error_callback| is called when it fails to delete the object.
-// |success_callback| and |error_callback| runs on the IO thread.
-void DeleteObjectOnUIThread(
- const std::string storage_name,
- const bool read_only,
- const uint32_t object_id,
- const MTPDeviceTaskHelper::DeleteObjectSuccessCallback success_callback,
- const MTPDeviceTaskHelper::ErrorCallback error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->DeleteObject(object_id, success_callback, error_callback);
-}
-
-// Closes the device storage specified by the |storage_name| and destroys the
-// MTPDeviceTaskHelper object associated with the device storage.
-//
-// Called on the UI thread to dispatch the request to the
-// MediaTransferProtocolManager.
-void CloseStorageAndDestroyTaskHelperOnUIThread(
- const std::string& storage_name,
- const bool read_only) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- MTPDeviceTaskHelper* task_helper =
- GetDeviceTaskHelperForStorage(storage_name, read_only);
- if (!task_helper)
- return;
- task_helper->CloseStorage();
- MTPDeviceTaskHelperMapService::GetInstance()->DestroyDeviceTaskHelper(
- storage_name, read_only);
-}
-
-// Opens |file_path| with |flags|. Returns the result as a pair.
-// first is file descriptor.
-// second is base::File::Error. This value is set as following.
-// - When it succeeds to open a file descriptor, base::File::FILE_OK is set.
-// - When |file_path| is a directory, base::File::FILE_ERROR_NOT_A_FILE is set.
-// - When |file_path| does not exist, base::File::FILE_ERROR_NOT_FOUND is set.
-// - For other error cases, base::File::FILE_ERROR_FAILED is set.
-std::pair<int, base::File::Error> OpenFileDescriptor(const char* file_path,
- const int flags) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
-
- if (base::DirectoryExists(base::FilePath(file_path)))
- return std::make_pair(-1, base::File::FILE_ERROR_NOT_A_FILE);
- int file_descriptor = open(file_path, flags);
- if (file_descriptor >= 0)
- return std::make_pair(file_descriptor, base::File::FILE_OK);
- if (errno == ENOENT)
- return std::make_pair(file_descriptor, base::File::FILE_ERROR_NOT_FOUND);
- return std::make_pair(file_descriptor, base::File::FILE_ERROR_FAILED);
-}
-
-// Closes |file_descriptor| on file thread.
-void CloseFileDescriptor(const int file_descriptor) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
-
- IGNORE_EINTR(close(file_descriptor));
-}
-
-// Deletes a temporary file |file_path|.
-void DeleteTemporaryFile(const base::FilePath& file_path) {
- content::BrowserThread::PostBlockingPoolTask(
- FROM_HERE, base::Bind(base::IgnoreResult(base::DeleteFile), file_path,
- false /* not recursive*/));
-}
-
-// A fake callback to be passed as CopyFileProgressCallback.
-void FakeCopyFileProgressCallback(int64_t size) {}
-
-} // namespace
-
-MTPDeviceDelegateImplLinux::PendingTaskInfo::PendingTaskInfo(
- const base::FilePath& path,
- content::BrowserThread::ID thread_id,
- const tracked_objects::Location& location,
- const base::Closure& task)
- : path(path),
- thread_id(thread_id),
- location(location),
- task(task) {
-}
-
-MTPDeviceDelegateImplLinux::PendingTaskInfo::PendingTaskInfo(
- const PendingTaskInfo& other) = default;
-
-MTPDeviceDelegateImplLinux::PendingTaskInfo::~PendingTaskInfo() {
-}
-
-// Represents a file on the MTP device.
-// Lives on the IO thread.
-class MTPDeviceDelegateImplLinux::MTPFileNode {
- public:
- MTPFileNode(uint32_t file_id,
- const std::string& file_name,
- MTPFileNode* parent,
- FileIdToMTPFileNodeMap* file_id_to_node_map);
- ~MTPFileNode();
-
- const MTPFileNode* GetChild(const std::string& name) const;
-
- void EnsureChildExists(const std::string& name, uint32_t id);
-
- // Clears all the children, except those in |children_to_keep|.
- void ClearNonexistentChildren(
- const std::set<std::string>& children_to_keep);
-
- bool DeleteChild(uint32_t file_id);
-
- bool HasChildren() const;
-
- uint32_t file_id() const { return file_id_; }
- const std::string& file_name() const { return file_name_; }
- MTPFileNode* parent() { return parent_; }
-
- private:
- // Container for holding a node's children.
- typedef base::ScopedPtrHashMap<std::string, std::unique_ptr<MTPFileNode>>
- ChildNodes;
-
- const uint32_t file_id_;
- const std::string file_name_;
-
- ChildNodes children_;
- MTPFileNode* const parent_;
- FileIdToMTPFileNodeMap* file_id_to_node_map_;
-
- DISALLOW_COPY_AND_ASSIGN(MTPFileNode);
-};
-
-MTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode(
- uint32_t file_id,
- const std::string& file_name,
- MTPFileNode* parent,
- FileIdToMTPFileNodeMap* file_id_to_node_map)
- : file_id_(file_id),
- file_name_(file_name),
- parent_(parent),
- file_id_to_node_map_(file_id_to_node_map) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(file_id_to_node_map_);
- DCHECK(!base::ContainsKey(*file_id_to_node_map_, file_id_));
- (*file_id_to_node_map_)[file_id_] = this;
-}
-
-MTPDeviceDelegateImplLinux::MTPFileNode::~MTPFileNode() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- size_t erased = file_id_to_node_map_->erase(file_id_);
- DCHECK_EQ(1U, erased);
-}
-
-const MTPDeviceDelegateImplLinux::MTPFileNode*
-MTPDeviceDelegateImplLinux::MTPFileNode::GetChild(
- const std::string& name) const {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- return children_.get(name);
-}
-
-void MTPDeviceDelegateImplLinux::MTPFileNode::EnsureChildExists(
- const std::string& name,
- uint32_t id) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- const MTPFileNode* child = GetChild(name);
- if (child && child->file_id() == id)
- return;
-
- children_.set(name, base::WrapUnique(new MTPFileNode(id, name, this,
- file_id_to_node_map_)));
-}
-
-void MTPDeviceDelegateImplLinux::MTPFileNode::ClearNonexistentChildren(
- const std::set<std::string>& children_to_keep) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- std::set<std::string> children_to_erase;
- for (ChildNodes::const_iterator it = children_.begin();
- it != children_.end(); ++it) {
- if (base::ContainsKey(children_to_keep, it->first))
- continue;
- children_to_erase.insert(it->first);
- }
- for (std::set<std::string>::iterator it = children_to_erase.begin();
- it != children_to_erase.end(); ++it) {
- children_.take_and_erase(*it);
- }
-}
-
-bool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32_t file_id) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- for (ChildNodes::iterator it = children_.begin();
- it != children_.end(); ++it) {
- if (it->second->file_id() == file_id) {
- DCHECK(!it->second->HasChildren());
- children_.erase(it);
- return true;
- }
- }
- return false;
-}
-
-bool MTPDeviceDelegateImplLinux::MTPFileNode::HasChildren() const {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- return children_.size() > 0;
-}
-
-MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux(
- const std::string& device_location,
- const bool read_only)
- : init_state_(UNINITIALIZED),
- task_in_progress_(false),
- device_path_(device_location),
- read_only_(read_only),
- root_node_(new MTPFileNode(mtpd::kRootFileId,
- "", // Root node has no name.
- NULL, // And no parent node.
- &file_id_to_node_map_)),
- weak_ptr_factory_(this) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!device_path_.empty());
- base::RemoveChars(device_location, kRootPath, &storage_name_);
- DCHECK(!storage_name_.empty());
-}
-
-MTPDeviceDelegateImplLinux::~MTPDeviceDelegateImplLinux() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-}
-
-void MTPDeviceDelegateImplLinux::CreateDirectory(
- const base::FilePath& directory_path,
- const bool exclusive,
- const bool recursive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!directory_path.empty());
-
- // If |directory_path| is not the path in this device, fails with error.
- if (!device_path_.IsParent(directory_path)) {
- error_callback.Run(base::File::FILE_ERROR_FAILED);
- return;
- }
-
- // Decomposes |directory_path| to components. CreateDirectoryInternal creates
- // directories by reading |components| from back.
- std::vector<base::FilePath> components;
- if (recursive) {
- for (base::FilePath path = directory_path; path != device_path_;
- path = path.DirName()) {
- components.push_back(path);
- }
- } else {
- components.push_back(directory_path);
- }
-
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(), components, exclusive,
- success_callback, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- directory_path, content::BrowserThread::IO, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::GetFileInfo(
- const base::FilePath& file_path,
- const GetFileInfoSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!file_path.empty());
-
- // If a ReadDirectory operation is in progress, the file info may already be
- // cached.
- FileInfoCache::const_iterator it = file_info_cache_.find(file_path);
- if (it != file_info_cache_.end()) {
- // TODO(thestig): This code is repeated in several places. Combine them.
- // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc
- const MTPDeviceTaskHelper::MTPEntry& cached_file_entry = it->second;
- success_callback.Run(cached_file_entry.file_info);
- return;
- }
- base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(),
- file_path,
- success_callback,
- error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(file_path,
- content::BrowserThread::IO,
- FROM_HERE,
- closure));
-}
-
-void MTPDeviceDelegateImplLinux::ReadDirectory(
- const base::FilePath& root,
- const ReadDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!root.empty());
- base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::ReadDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(),
- root,
- success_callback,
- error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(root,
- content::BrowserThread::IO,
- FROM_HERE,
- closure));
-}
-
-void MTPDeviceDelegateImplLinux::CreateSnapshotFile(
- const base::FilePath& device_file_path,
- const base::FilePath& local_path,
- const CreateSnapshotFileSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!device_file_path.empty());
- DCHECK(!local_path.empty());
- base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal,
- weak_ptr_factory_.GetWeakPtr(),
- device_file_path,
- local_path,
- success_callback,
- error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(device_file_path,
- content::BrowserThread::IO,
- FROM_HERE,
- closure));
-}
-
-bool MTPDeviceDelegateImplLinux::IsStreaming() {
- return true;
-}
-
-void MTPDeviceDelegateImplLinux::ReadBytes(
- const base::FilePath& device_file_path,
- const scoped_refptr<net::IOBuffer>& buf,
- int64_t offset,
- int buf_len,
- const ReadBytesSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!device_file_path.empty());
- base::Closure closure = base::Bind(
- &MTPDeviceDelegateImplLinux::ReadBytesInternal,
- weak_ptr_factory_.GetWeakPtr(), device_file_path, base::RetainedRef(buf),
- offset, buf_len, success_callback, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(device_file_path,
- content::BrowserThread::IO,
- FROM_HERE,
- closure));
-}
-
-bool MTPDeviceDelegateImplLinux::IsReadOnly() const {
- return read_only_;
-}
-
-void MTPDeviceDelegateImplLinux::CopyFileLocal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CreateTemporaryFileCallback& create_temporary_file_callback,
- const CopyFileProgressCallback& progress_callback,
- const CopyFileLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!source_file_path.empty());
- DCHECK(!device_file_path.empty());
-
- // Create a temporary file for creating a copy of source file on local.
- content::BrowserThread::PostTaskAndReplyWithResult(
- content::BrowserThread::FILE, FROM_HERE, create_temporary_file_callback,
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidCreateTemporaryFileToCopyFileLocal,
- weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path,
- progress_callback, success_callback, error_callback));
-}
-
-void MTPDeviceDelegateImplLinux::MoveFileLocal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CreateTemporaryFileCallback& create_temporary_file_callback,
- const MoveFileLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!source_file_path.empty());
- DCHECK(!device_file_path.empty());
-
- // Get file info to move file on local.
- const GetFileInfoSuccessCallback success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::MoveFileLocalInternal,
- weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path,
- create_temporary_file_callback, success_callback, error_callback);
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(), source_file_path,
- success_callback_wrapper, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- source_file_path, content::BrowserThread::IO, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::CopyFileFromLocal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CopyFileFromLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!source_file_path.empty());
- DCHECK(!device_file_path.empty());
-
- // Get file info of destination file path.
- const GetFileInfoSuccessCallback success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidGetDestFileInfoToCopyFileFromLocal,
- weak_ptr_factory_.GetWeakPtr(), error_callback);
- const ErrorCallback error_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnGetDestFileInfoErrorToCopyFileFromLocal,
- weak_ptr_factory_.GetWeakPtr(), source_file_path, device_file_path,
- success_callback, error_callback);
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(), device_file_path,
- success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- device_file_path, content::BrowserThread::IO, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::DeleteFile(
- const base::FilePath& file_path,
- const DeleteFileSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!file_path.empty());
-
- const GetFileInfoSuccessCallback& success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal,
- weak_ptr_factory_.GetWeakPtr(), file_path, success_callback,
- error_callback);
-
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(), file_path,
- success_callback_wrapper, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO,
- FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::DeleteDirectory(
- const base::FilePath& file_path,
- const DeleteDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!file_path.empty());
-
- const GetFileInfoSuccessCallback& success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::DeleteDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(), file_path, success_callback,
- error_callback);
-
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(), file_path,
- success_callback_wrapper, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(file_path, content::BrowserThread::IO,
- FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::AddWatcher(
- const GURL& origin,
- const base::FilePath& file_path,
- const bool recursive,
- const storage::WatcherManager::StatusCallback& callback,
- const storage::WatcherManager::NotificationCallback&
- notification_callback) {
- if (recursive) {
- callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
- return;
- }
-
- const auto it = subscribers_.find(file_path);
- if (it != subscribers_.end()) {
- // Adds to existing origin callback map.
- if (ContainsKey(it->second, origin)) {
- callback.Run(base::File::FILE_ERROR_EXISTS);
- return;
- }
-
- it->second.insert(std::make_pair(origin, notification_callback));
- } else {
- // Creates new origin callback map.
- OriginNotificationCallbackMap callback_map;
- callback_map.insert(std::make_pair(origin, notification_callback));
- subscribers_.insert(std::make_pair(file_path, callback_map));
- }
-
- callback.Run(base::File::FILE_OK);
-}
-
-void MTPDeviceDelegateImplLinux::RemoveWatcher(
- const GURL& origin,
- const base::FilePath& file_path,
- const bool recursive,
- const storage::WatcherManager::StatusCallback& callback) {
- if (recursive) {
- callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
- return;
- }
-
- const auto it = subscribers_.find(file_path);
- if (it == subscribers_.end()) {
- callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- return;
- }
-
- if (it->second.erase(origin) == 0) {
- callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- return;
- }
-
- if (it->second.empty())
- subscribers_.erase(it);
-
- callback.Run(base::File::FILE_OK);
-}
-
-void MTPDeviceDelegateImplLinux::NotifyFileChange(
- const base::FilePath& file_path,
- const storage::WatcherManager::ChangeType change_type) {
- const auto it = subscribers_.find(file_path);
- if (it != subscribers_.end()) {
- for (const auto& origin_callback : it->second) {
- origin_callback.second.Run(change_type);
- }
- }
-}
-
-void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object.
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread,
- storage_name_,
- read_only_));
- delete this;
-}
-
-void MTPDeviceDelegateImplLinux::GetFileInfoInternal(
- const base::FilePath& file_path,
- const GetFileInfoSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- uint32_t file_id;
- if (CachedPathToId(file_path, &file_id)) {
- GetFileInfoSuccessCallback success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfo,
- weak_ptr_factory_.GetWeakPtr(),
- success_callback);
- ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(),
- error_callback,
- file_id);
-
-
- base::Closure closure = base::Bind(&GetFileInfoOnUIThread,
- storage_name_,
- read_only_,
- file_id,
- success_callback_wrapper,
- error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(),
- content::BrowserThread::UI,
- FROM_HERE,
- closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::CreateDirectoryInternal(
- const std::vector<base::FilePath>& components,
- const bool exclusive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- const base::FilePath current_component = components.back();
- std::vector<base::FilePath> other_components = components;
- other_components.pop_back();
-
- if (other_components.empty()) {
- // Either we reached the last component in the recursive case, or this is
- // the non-recursive case.
- uint32_t parent_id;
- if (CachedPathToId(current_component.DirName(), &parent_id)) {
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateSingleDirectory,
- weak_ptr_factory_.GetWeakPtr(), current_component,
- exclusive, success_callback, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- } else {
- // Ensures that parent directories are created for recursive case.
- uint32_t directory_id;
- if (CachedPathToId(current_component, &directory_id)) {
- // Parent directory |current_component| already exists, continue creating
- // directories.
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(), other_components,
- exclusive, success_callback, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
- } else {
- // If parent directory |current_component| does not exist, create it.
- const CreateDirectorySuccessCallback success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::
- OnDidCreateParentDirectoryToCreateDirectory,
- weak_ptr_factory_.GetWeakPtr(), current_component,
- other_components, exclusive, success_callback,
- error_callback);
- // Wraps error callback to return all errors of creating parent
- // directories as FILE_ERROR_FAILED.
- const ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::
- OnCreateParentDirectoryErrorToCreateDirectory,
- weak_ptr_factory_.GetWeakPtr(), error_callback);
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateSingleDirectory,
- weak_ptr_factory_.GetWeakPtr(), current_component,
- false /* not exclusive */, success_callback_wrapper,
- error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
- }
- }
-
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::ReadDirectoryInternal(
- const base::FilePath& root,
- const ReadDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- uint32_t dir_id;
- if (CachedPathToId(root, &dir_id)) {
- GetFileInfoSuccessCallback success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory,
- weak_ptr_factory_.GetWeakPtr(),
- dir_id,
- success_callback,
- error_callback);
- ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(),
- error_callback,
- dir_id);
- base::Closure closure = base::Bind(&GetFileInfoOnUIThread,
- storage_name_,
- read_only_,
- dir_id,
- success_callback_wrapper,
- error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(),
- content::BrowserThread::UI,
- FROM_HERE,
- closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal(
- const base::FilePath& device_file_path,
- const base::FilePath& local_path,
- const CreateSnapshotFileSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- uint32_t file_id;
- if (CachedPathToId(device_file_path, &file_id)) {
- std::unique_ptr<SnapshotRequestInfo> request_info(new SnapshotRequestInfo(
- file_id, local_path, success_callback, error_callback));
- GetFileInfoSuccessCallback success_callback_wrapper =
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(&request_info));
- ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(),
- error_callback,
- file_id);
- base::Closure closure = base::Bind(&GetFileInfoOnUIThread,
- storage_name_,
- read_only_,
- file_id,
- success_callback_wrapper,
- error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(),
- content::BrowserThread::UI,
- FROM_HERE,
- closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::ReadBytesInternal(
- const base::FilePath& device_file_path,
- net::IOBuffer* buf,
- int64_t offset,
- int buf_len,
- const ReadBytesSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- uint32_t file_id;
- if (CachedPathToId(device_file_path, &file_id)) {
- ReadBytesRequest request(
- file_id, buf, offset, buf_len,
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadBytes,
- weak_ptr_factory_.GetWeakPtr(),
- success_callback),
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(),
- error_callback,
- file_id));
-
- base::Closure closure =
- base::Bind(&ReadBytesOnUIThread, storage_name_, read_only_, request);
- EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(),
- content::BrowserThread::UI,
- FROM_HERE,
- closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::MoveFileLocalInternal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CreateTemporaryFileCallback& create_temporary_file_callback,
- const MoveFileLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& source_file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (source_file_info.is_directory) {
- error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE);
- return;
- }
-
- if (source_file_path.DirName() == device_file_path.DirName()) {
- // If a file is moved in a same directory, rename the file.
- uint32_t file_id;
- if (CachedPathToId(source_file_path, &file_id)) {
- const MTPDeviceTaskHelper::RenameObjectSuccessCallback
- success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidMoveFileLocalWithRename,
- weak_ptr_factory_.GetWeakPtr(), success_callback,
- source_file_path, file_id);
- const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(), error_callback, file_id);
- const base::Closure closure =
- base::Bind(&RenameObjectOnUIThread, storage_name_, read_only_,
- file_id, device_file_path.BaseName().value(),
- success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
- } else {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
- } else {
- // If a file is moved to a different directory, create a copy to the
- // destination path, and remove source file.
- const CopyFileLocalSuccessCallback& success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::DeleteFileInternal,
- weak_ptr_factory_.GetWeakPtr(), source_file_path,
- success_callback, error_callback, source_file_info);
- // TODO(yawano): Avoid to call external method from internal code.
- CopyFileLocal(source_file_path, device_file_path,
- create_temporary_file_callback,
- base::Bind(&FakeCopyFileProgressCallback),
- success_callback_wrapper, error_callback);
- }
-}
-
-void MTPDeviceDelegateImplLinux::OnDidOpenFDToCopyFileFromLocal(
- const base::FilePath& device_file_path,
- const CopyFileFromLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const std::pair<int, base::File::Error>& open_fd_result) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (open_fd_result.second != base::File::FILE_OK) {
- error_callback.Run(open_fd_result.second);
- return;
- }
-
- const int source_file_descriptor = open_fd_result.first;
- uint32_t parent_id;
- if (CachedPathToId(device_file_path.DirName(), &parent_id)) {
- CopyFileFromLocalSuccessCallback success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal,
- weak_ptr_factory_.GetWeakPtr(), success_callback,
- device_file_path, source_file_descriptor);
-
- ErrorCallback error_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::HandleCopyFileFromLocalError,
- weak_ptr_factory_.GetWeakPtr(), error_callback, source_file_descriptor);
-
- base::Closure closure = base::Bind(&CopyFileFromLocalOnUIThread,
- storage_name_,
- read_only_,
- source_file_descriptor,
- parent_id,
- device_file_path.BaseName().value(),
- success_callback_wrapper,
- error_callback_wrapper);
-
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
- } else {
- HandleCopyFileFromLocalError(error_callback, source_file_descriptor,
- base::File::FILE_ERROR_NOT_FOUND);
- }
-}
-
-void MTPDeviceDelegateImplLinux::DeleteFileInternal(
- const base::FilePath& file_path,
- const DeleteFileSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (file_info.is_directory) {
- error_callback.Run(base::File::FILE_ERROR_NOT_A_FILE);
- } else {
- uint32_t file_id;
- if (CachedPathToId(file_path, &file_id))
- RunDeleteObjectOnUIThread(file_path, file_id, success_callback,
- error_callback);
- else
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- }
-}
-
-void MTPDeviceDelegateImplLinux::DeleteDirectoryInternal(
- const base::FilePath& file_path,
- const DeleteDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (!file_info.is_directory) {
- error_callback.Run(base::File::FILE_ERROR_NOT_A_DIRECTORY);
- return;
- }
-
- uint32_t directory_id;
- if (!CachedPathToId(file_path, &directory_id)) {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- return;
- }
-
- // Checks the cache first. If it has children in cache, the directory cannot
- // be empty.
- FileIdToMTPFileNodeMap::const_iterator it =
- file_id_to_node_map_.find(directory_id);
- if (it != file_id_to_node_map_.end() && it->second->HasChildren()) {
- error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY);
- return;
- }
-
- // Since the directory can contain a file even if the cache returns it as
- // empty, read the directory and confirm the directory is actually empty.
- const MTPDeviceTaskHelper::ReadDirectorySuccessCallback
- success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory,
- weak_ptr_factory_.GetWeakPtr(), file_path, directory_id,
- success_callback, error_callback);
- const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(), error_callback, directory_id);
- const base::Closure closure = base::Bind(
- &ReadDirectoryOnUIThread, storage_name_, read_only_, directory_id,
- 1 /* max_size */, success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::CreateSingleDirectory(
- const base::FilePath& directory_path,
- const bool exclusive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- const GetFileInfoSuccessCallback success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnPathAlreadyExistsForCreateSingleDirectory,
- weak_ptr_factory_.GetWeakPtr(), exclusive, success_callback,
- error_callback);
- const ErrorCallback error_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnPathDoesNotExistForCreateSingleDirectory,
- weak_ptr_factory_.GetWeakPtr(), directory_path, success_callback,
- error_callback);
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
- weak_ptr_factory_.GetWeakPtr(), directory_path,
- success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory(
- const std::vector<base::FilePath>& components,
- const bool exclusive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const storage::AsyncFileUtil::EntryList& /* entries */,
- const bool has_more) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (has_more)
- return; // Wait until all entries have been read.
-
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::CreateDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(), components, exclusive,
- success_callback, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::OnDidReadDirectoryToDeleteDirectory(
- const base::FilePath& directory_path,
- const uint32_t directory_id,
- const DeleteDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const MTPDeviceTaskHelper::MTPEntries& entries,
- const bool has_more) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!has_more);
-
- if (entries.size() > 0) {
- error_callback.Run(base::File::FILE_ERROR_NOT_EMPTY);
- } else {
- RunDeleteObjectOnUIThread(directory_path, directory_id, success_callback,
- error_callback);
- }
-
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::RunDeleteObjectOnUIThread(
- const base::FilePath& object_path,
- const uint32_t object_id,
- const DeleteObjectSuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- const MTPDeviceTaskHelper::DeleteObjectSuccessCallback
- success_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidDeleteObject,
- weak_ptr_factory_.GetWeakPtr(), object_path, object_id,
- success_callback);
-
- const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError,
- weak_ptr_factory_.GetWeakPtr(), error_callback);
-
- const base::Closure closure =
- base::Bind(&DeleteObjectOnUIThread, storage_name_, read_only_, object_id,
- success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask(
- const PendingTaskInfo& task_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if ((init_state_ == INITIALIZED) && !task_in_progress_) {
- RunTask(task_info);
- return;
- }
-
- // Only *Internal functions have empty paths. Since they are the continuation
- // of the current running task, they get to cut in line.
- if (task_info.path.empty())
- pending_tasks_.push_front(task_info);
- else
- pending_tasks_.push_back(task_info);
-
- if (init_state_ == UNINITIALIZED) {
- init_state_ = PENDING_INIT;
- task_in_progress_ = true;
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(&OpenStorageOnUIThread, storage_name_, read_only_,
- base::Bind(&MTPDeviceDelegateImplLinux::OnInitCompleted,
- weak_ptr_factory_.GetWeakPtr())));
- }
-}
-
-void MTPDeviceDelegateImplLinux::RunTask(const PendingTaskInfo& task_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK_EQ(INITIALIZED, init_state_);
- DCHECK(!task_in_progress_);
- task_in_progress_ = true;
-
- bool need_to_check_cache = !task_info.path.empty();
- if (need_to_check_cache) {
- base::FilePath uncached_path =
- NextUncachedPathComponent(task_info.path, task_info.cached_path);
- if (!uncached_path.empty()) {
- // Save the current task and do a cache lookup first.
- pending_tasks_.push_front(task_info);
- FillFileCache(uncached_path);
- return;
- }
- }
-
- content::BrowserThread::PostTask(task_info.thread_id,
- task_info.location,
- task_info.task);
-}
-
-void MTPDeviceDelegateImplLinux::WriteDataIntoSnapshotFile(
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(current_snapshot_request_info_.get());
- DCHECK_GT(file_info.size, 0);
- DCHECK(task_in_progress_);
- SnapshotRequestInfo request_info(
- current_snapshot_request_info_->file_id,
- current_snapshot_request_info_->snapshot_file_path,
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile,
- weak_ptr_factory_.GetWeakPtr()),
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnWriteDataIntoSnapshotFileError,
- weak_ptr_factory_.GetWeakPtr()));
-
- base::Closure task_closure = base::Bind(&WriteDataIntoSnapshotFileOnUIThread,
- storage_name_,
- read_only_,
- request_info,
- file_info);
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- task_closure);
-}
-
-void MTPDeviceDelegateImplLinux::PendingRequestDone() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(task_in_progress_);
- task_in_progress_ = false;
- ProcessNextPendingRequest();
-}
-
-void MTPDeviceDelegateImplLinux::ProcessNextPendingRequest() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!task_in_progress_);
- if (pending_tasks_.empty())
- return;
-
- PendingTaskInfo task_info = pending_tasks_.front();
- pending_tasks_.pop_front();
- RunTask(task_info);
-}
-
-void MTPDeviceDelegateImplLinux::OnInitCompleted(bool succeeded) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- init_state_ = succeeded ? INITIALIZED : UNINITIALIZED;
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidGetFileInfo(
- const GetFileInfoSuccessCallback& success_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- success_callback.Run(file_info);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnPathAlreadyExistsForCreateSingleDirectory(
- const bool exclusive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (!file_info.is_directory || exclusive)
- error_callback.Run(base::File::FILE_ERROR_EXISTS);
- else
- success_callback.Run();
-}
-
-void MTPDeviceDelegateImplLinux::OnPathDoesNotExistForCreateSingleDirectory(
- const base::FilePath& directory_path,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (error != base::File::FILE_ERROR_NOT_FOUND) {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- return;
- }
-
- uint32_t parent_id;
- if (!CachedPathToId(directory_path.DirName(), &parent_id)) {
- error_callback.Run(base::File::FILE_ERROR_NOT_FOUND);
- return;
- }
-
- const MTPDeviceTaskHelper::CreateDirectorySuccessCallback
- success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidCreateSingleDirectory,
- weak_ptr_factory_.GetWeakPtr(), directory_path, success_callback);
- const MTPDeviceTaskHelper::ErrorCallback error_callback_wrapper =
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(), error_callback, parent_id);
- const base::Closure closure =
- base::Bind(&CreateDirectoryOnUIThread, storage_name_, read_only_,
- parent_id, directory_path.BaseName().value(),
- success_callback_wrapper, error_callback_wrapper);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::UI, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory(
- uint32_t dir_id,
- const ReadDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(task_in_progress_);
- if (!file_info.is_directory) {
- return HandleDeviceFileError(error_callback,
- dir_id,
- base::File::FILE_ERROR_NOT_A_DIRECTORY);
- }
-
- base::Closure task_closure = base::Bind(
- &ReadDirectoryOnUIThread, storage_name_, read_only_, dir_id,
- 0 /* max_size */,
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadDirectory,
- weak_ptr_factory_.GetWeakPtr(), dir_id, success_callback),
- base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError,
- weak_ptr_factory_.GetWeakPtr(), error_callback, dir_id));
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- task_closure);
-}
-
-void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile(
- std::unique_ptr<SnapshotRequestInfo> snapshot_request_info,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!current_snapshot_request_info_.get());
- DCHECK(snapshot_request_info.get());
- DCHECK(task_in_progress_);
- base::File::Error error = base::File::FILE_OK;
- if (file_info.is_directory)
- error = base::File::FILE_ERROR_NOT_A_FILE;
- else if (file_info.size < 0 ||
- file_info.size > std::numeric_limits<uint32_t>::max())
- error = base::File::FILE_ERROR_FAILED;
-
- if (error != base::File::FILE_OK)
- return HandleDeviceFileError(snapshot_request_info->error_callback,
- snapshot_request_info->file_id,
- error);
-
- base::File::Info snapshot_file_info(file_info);
- // Modify the last modified time to null. This prevents the time stamp
- // verfication in LocalFileStreamReader.
- snapshot_file_info.last_modified = base::Time();
-
- current_snapshot_request_info_.reset(snapshot_request_info.release());
- if (file_info.size == 0) {
- // Empty snapshot file.
- return OnDidWriteDataIntoSnapshotFile(
- snapshot_file_info, current_snapshot_request_info_->snapshot_file_path);
- }
- WriteDataIntoSnapshotFile(snapshot_file_info);
-}
-
-void MTPDeviceDelegateImplLinux::OnDidGetDestFileInfoToCopyFileFromLocal(
- const ErrorCallback& error_callback,
- const base::File::Info& file_info) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (file_info.is_directory)
- error_callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
- else
- error_callback.Run(base::File::FILE_ERROR_FAILED);
-}
-
-void MTPDeviceDelegateImplLinux::OnGetDestFileInfoErrorToCopyFileFromLocal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CopyFileFromLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (error != base::File::FILE_ERROR_NOT_FOUND) {
- error_callback.Run(error);
- return;
- }
-
- content::BrowserThread::PostTaskAndReplyWithResult(
- content::BrowserThread::FILE, FROM_HERE,
- base::Bind(&OpenFileDescriptor, source_file_path.value().c_str(),
- O_RDONLY),
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidOpenFDToCopyFileFromLocal,
- weak_ptr_factory_.GetWeakPtr(), device_file_path,
- success_callback, error_callback));
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCreateSingleDirectory(
- const base::FilePath& directory_path,
- const CreateDirectorySuccessCallback& success_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- success_callback.Run();
- NotifyFileChange(directory_path.DirName(),
- storage::WatcherManager::ChangeType::CHANGED);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCreateParentDirectoryToCreateDirectory(
- const base::FilePath& created_directory,
- const std::vector<base::FilePath>& components,
- const bool exclusive,
- const CreateDirectorySuccessCallback& success_callback,
- const ErrorCallback& error_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- // Calls ReadDirectoryInternal to fill the cache for created directory.
- // Calls ReadDirectoryInternal in this method to call it via
- // EnsureInitAndRunTask.
- const ReadDirectorySuccessCallback& success_callback_wrapper = base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidReadDirectoryToCreateDirectory,
- weak_ptr_factory_.GetWeakPtr(), components, exclusive, success_callback,
- error_callback);
- const base::Closure closure =
- base::Bind(&MTPDeviceDelegateImplLinux::ReadDirectoryInternal,
- weak_ptr_factory_.GetWeakPtr(), created_directory.DirName(),
- success_callback_wrapper, error_callback);
- EnsureInitAndRunTask(PendingTaskInfo(
- base::FilePath(), content::BrowserThread::IO, FROM_HERE, closure));
-}
-
-void MTPDeviceDelegateImplLinux::OnCreateParentDirectoryErrorToCreateDirectory(
- const ErrorCallback& callback,
- const base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- callback.Run(base::File::FILE_ERROR_FAILED);
-}
-
-void MTPDeviceDelegateImplLinux::OnDidReadDirectory(
- uint32_t dir_id,
- const ReadDirectorySuccessCallback& success_callback,
- const MTPDeviceTaskHelper::MTPEntries& mtp_entries,
- bool has_more) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id);
- DCHECK(it != file_id_to_node_map_.end());
- MTPFileNode* dir_node = it->second;
-
- // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|.
- std::deque<std::string> dir_path_parts;
- MTPFileNode* parent_node = dir_node;
- while (parent_node->parent()) {
- dir_path_parts.push_front(parent_node->file_name());
- parent_node = parent_node->parent();
- }
- base::FilePath dir_path = device_path_;
- for (const auto& dir_path_part : dir_path_parts)
- dir_path = dir_path.Append(dir_path_part);
-
- storage::AsyncFileUtil::EntryList file_list;
- for (const auto& mtp_entry : mtp_entries) {
- storage::DirectoryEntry entry;
- entry.name = mtp_entry.name;
- entry.is_directory = mtp_entry.file_info.is_directory;
- file_list.push_back(entry);
-
- // Refresh the in memory tree.
- dir_node->EnsureChildExists(entry.name, mtp_entry.file_id);
- child_nodes_seen_.insert(entry.name);
-
- // Add to |file_info_cache_|.
- file_info_cache_[dir_path.Append(entry.name)] = mtp_entry;
- }
-
- success_callback.Run(file_list, has_more);
- if (has_more)
- return; // Wait to be called again.
-
- // Last call, finish book keeping and continue with the next request.
- dir_node->ClearNonexistentChildren(child_nodes_seen_);
- child_nodes_seen_.clear();
- file_info_cache_.clear();
-
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile(
- const base::File::Info& file_info,
- const base::FilePath& snapshot_file_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(current_snapshot_request_info_.get());
- current_snapshot_request_info_->success_callback.Run(
- file_info, snapshot_file_path);
- current_snapshot_request_info_.reset();
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnWriteDataIntoSnapshotFileError(
- base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(current_snapshot_request_info_.get());
- current_snapshot_request_info_->error_callback.Run(error);
- current_snapshot_request_info_.reset();
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidReadBytes(
- const ReadBytesSuccessCallback& success_callback,
- const base::File::Info& file_info, int bytes_read) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- success_callback.Run(file_info, bytes_read);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidFillFileCache(
- const base::FilePath& path,
- const storage::AsyncFileUtil::EntryList& /* entries */,
- bool has_more) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(path.IsParent(pending_tasks_.front().path));
- if (has_more)
- return; // Wait until all entries have been read.
- pending_tasks_.front().cached_path = path;
-}
-
-void MTPDeviceDelegateImplLinux::OnFillFileCacheFailed(
- base::File::Error /* error */) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- // When filling the cache fails for the task at the front of the queue, clear
- // the path of the task so it will not try to do any more caching. Instead,
- // the task will just run and fail the CachedPathToId() lookup.
- pending_tasks_.front().path.clear();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCreateTemporaryFileToCopyFileLocal(
- const base::FilePath& source_file_path,
- const base::FilePath& device_file_path,
- const CopyFileProgressCallback& progress_callback,
- const CopyFileLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::FilePath& temporary_file_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (temporary_file_path.empty()) {
- error_callback.Run(base::File::FILE_ERROR_FAILED);
- return;
- }
-
- CreateSnapshotFile(
- source_file_path, temporary_file_path,
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidCreateSnapshotFileOfCopyFileLocal,
- weak_ptr_factory_.GetWeakPtr(), device_file_path, progress_callback,
- success_callback, error_callback),
- base::Bind(&MTPDeviceDelegateImplLinux::HandleCopyFileLocalError,
- weak_ptr_factory_.GetWeakPtr(), error_callback,
- temporary_file_path));
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCreateSnapshotFileOfCopyFileLocal(
- const base::FilePath& device_file_path,
- const CopyFileProgressCallback& progress_callback,
- const CopyFileLocalSuccessCallback& success_callback,
- const ErrorCallback& error_callback,
- const base::File::Info& file_info,
- const base::FilePath& temporary_file_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- // Consider that half of copy is completed by creating a temporary file.
- progress_callback.Run(file_info.size / 2);
-
- // TODO(yawano): Avoid to call external method from internal code.
- CopyFileFromLocal(
- temporary_file_path, device_file_path,
- base::Bind(
- &MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocalOfCopyFileLocal,
- weak_ptr_factory_.GetWeakPtr(), success_callback,
- temporary_file_path),
- base::Bind(&MTPDeviceDelegateImplLinux::HandleCopyFileLocalError,
- weak_ptr_factory_.GetWeakPtr(), error_callback,
- temporary_file_path));
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocalOfCopyFileLocal(
- const CopyFileFromLocalSuccessCallback success_callback,
- const base::FilePath& temporary_file_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- DeleteTemporaryFile(temporary_file_path);
- success_callback.Run();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidMoveFileLocalWithRename(
- const MoveFileLocalSuccessCallback& success_callback,
- const base::FilePath& source_file_path,
- const uint32_t file_id) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- EvictCachedPathToId(file_id);
- success_callback.Run();
- NotifyFileChange(source_file_path,
- storage::WatcherManager::ChangeType::DELETED);
- NotifyFileChange(source_file_path.DirName(),
- storage::WatcherManager::ChangeType::CHANGED);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidCopyFileFromLocal(
- const CopyFileFromLocalSuccessCallback& success_callback,
- const base::FilePath& file_path,
- const int source_file_descriptor) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- const base::Closure closure = base::Bind(&CloseFileDescriptor,
- source_file_descriptor);
-
- content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
- closure);
-
- success_callback.Run();
- NotifyFileChange(file_path.DirName(),
- storage::WatcherManager::ChangeType::CHANGED);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::HandleCopyFileLocalError(
- const ErrorCallback& error_callback,
- const base::FilePath& temporary_file_path,
- const base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- DeleteTemporaryFile(temporary_file_path);
- error_callback.Run(error);
-}
-
-void MTPDeviceDelegateImplLinux::HandleCopyFileFromLocalError(
- const ErrorCallback& error_callback,
- const int source_file_descriptor,
- base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- const base::Closure closure = base::Bind(&CloseFileDescriptor,
- source_file_descriptor);
-
- content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
- closure);
-
- error_callback.Run(error);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::OnDidDeleteObject(
- const base::FilePath& object_path,
- const uint32_t object_id,
- const DeleteObjectSuccessCallback success_callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- EvictCachedPathToId(object_id);
- success_callback.Run();
- NotifyFileChange(object_path, storage::WatcherManager::ChangeType::DELETED);
- NotifyFileChange(object_path.DirName(),
- storage::WatcherManager::ChangeType::CHANGED);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::HandleDeleteFileOrDirectoryError(
- const ErrorCallback& error_callback,
- base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- error_callback.Run(error);
- PendingRequestDone();
-}
-
-void MTPDeviceDelegateImplLinux::HandleDeviceFileError(
- const ErrorCallback& error_callback,
- uint32_t file_id,
- base::File::Error error) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- EvictCachedPathToId(file_id);
- error_callback.Run(error);
- PendingRequestDone();
-}
-
-base::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent(
- const base::FilePath& path,
- const base::FilePath& cached_path) const {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(cached_path.empty() || cached_path.IsParent(path));
-
- base::FilePath uncached_path;
- std::string device_relpath = GetDeviceRelativePath(device_path_, path);
- if (!device_relpath.empty() && device_relpath != kRootPath) {
- uncached_path = device_path_;
- std::vector<std::string> device_relpath_components = base::SplitString(
- device_relpath, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- DCHECK(!device_relpath_components.empty());
- bool all_components_cached = true;
- const MTPFileNode* current_node = root_node_.get();
- for (size_t i = 0; i < device_relpath_components.size(); ++i) {
- current_node = current_node->GetChild(device_relpath_components[i]);
- if (!current_node) {
- // With a cache miss, check if it is a genuine failure. If so, pretend
- // the entire |path| is cached, so there is no further attempt to do
- // more caching. The actual operation will then fail.
- all_components_cached =
- !cached_path.empty() && (uncached_path == cached_path);
- break;
- }
- uncached_path = uncached_path.Append(device_relpath_components[i]);
- }
- if (all_components_cached)
- uncached_path.clear();
- }
- return uncached_path;
-}
-
-void MTPDeviceDelegateImplLinux::FillFileCache(
- const base::FilePath& uncached_path) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(task_in_progress_);
-
- ReadDirectorySuccessCallback success_callback =
- base::Bind(&MTPDeviceDelegateImplLinux::OnDidFillFileCache,
- weak_ptr_factory_.GetWeakPtr(),
- uncached_path);
- ErrorCallback error_callback =
- base::Bind(&MTPDeviceDelegateImplLinux::OnFillFileCacheFailed,
- weak_ptr_factory_.GetWeakPtr());
- ReadDirectoryInternal(uncached_path, success_callback, error_callback);
-}
-
-bool MTPDeviceDelegateImplLinux::CachedPathToId(const base::FilePath& path,
- uint32_t* id) const {
- DCHECK(id);
-
- std::string device_relpath = GetDeviceRelativePath(device_path_, path);
- if (device_relpath.empty())
- return false;
- std::vector<std::string> device_relpath_components;
- if (device_relpath != kRootPath) {
- device_relpath_components = base::SplitString(
- device_relpath, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- }
- const MTPFileNode* current_node = root_node_.get();
- for (size_t i = 0; i < device_relpath_components.size(); ++i) {
- current_node = current_node->GetChild(device_relpath_components[i]);
- if (!current_node)
- return false;
- }
- *id = current_node->file_id();
- return true;
-}
-
-void MTPDeviceDelegateImplLinux::EvictCachedPathToId(const uint32_t id) {
- FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(id);
- if (it != file_id_to_node_map_.end()) {
- DCHECK(!it->second->HasChildren());
- MTPFileNode* parent = it->second->parent();
- if (parent) {
- const bool ret = parent->DeleteChild(id);
- DCHECK(ret);
- }
- }
-}
-
-void CreateMTPDeviceAsyncDelegate(
- const std::string& device_location,
- const bool read_only,
- const CreateMTPDeviceAsyncDelegateCallback& callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- callback.Run(new MTPDeviceDelegateImplLinux(device_location, read_only));
-}

Powered by Google App Engine
This is Rietveld 408576698