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

Unified Diff: chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc

Issue 11348337: Move MTPDeviceDelegateImplLinux worker classes to its own files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments Created 8 years 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
« no previous file with comments | « chrome/browser/media_gallery/mtp_device_delegate_impl_linux.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc
diff --git a/chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc b/chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc
deleted file mode 100644
index 6977d8d5739bf99e41657478de1964753a07541b..0000000000000000000000000000000000000000
--- a/chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc
+++ /dev/null
@@ -1,961 +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_gallery/mtp_device_delegate_impl_linux.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "base/bind.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/sequenced_task_runner.h"
-#include "base/sequenced_task_runner_helpers.h"
-#include "base/string_util.h"
-#include "base/synchronization/cancellation_flag.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/media_transfer_protocol/media_transfer_protocol_manager.h"
-#include "chrome/browser/media_transfer_protocol/mtp_file_entry.pb.h"
-#include "content/public/browser/browser_thread.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
-
-using base::Bind;
-using base::PlatformFileError;
-using base::PlatformFileInfo;
-using base::SequencedTaskRunner;
-using base::Time;
-using content::BrowserThread;
-using fileapi::FileSystemFileUtil;
-
-namespace chrome {
-
-namespace {
-
-using base::DeleteHelper;
-using base::RefCountedThreadSafe;
-using base::WaitableEvent;
-
-// Helper struct to delete worker objects on |media_task_runner_| thread.
-template <typename WORKER> struct WorkerDeleter {
- static void Destruct(const WORKER* worker) {
- if (!worker->media_task_runner()->RunsTasksOnCurrentThread()) {
- worker->media_task_runner()->DeleteSoon(FROM_HERE, worker);
- return;
- }
- delete worker;
- }
-};
-
-typedef struct WorkerDeleter<class GetFileInfoWorker> GetFileInfoWorkerDeleter;
-typedef struct WorkerDeleter<class OpenStorageWorker> OpenStorageWorkerDeleter;
-typedef struct WorkerDeleter<class ReadDirectoryWorker>
- ReadDirectoryWorkerDeleter;
-typedef struct WorkerDeleter<class ReadFileWorker> ReadFileWorkerDeleter;
-
-// File path separator constant.
-const char kRootPath[] = "/";
-
-// Returns MediaTransferProtocolManager instance on success or NULL on failure.
-MediaTransferProtocolManager* GetMediaTransferProtocolManager() {
- MediaTransferProtocolManager* mtp_device_mgr =
- MediaTransferProtocolManager::GetInstance();
- DCHECK(mtp_device_mgr);
- return mtp_device_mgr;
-}
-
-// Does nothing.
-// This method is used to handle the results of
-// MediaTransferProtocolManager::CloseStorage method call.
-void DoNothing(bool error) {
-}
-
-// Closes the device storage on the UI thread.
-void CloseStorageOnUIThread(const std::string& device_handle) {
- DCHECK(!device_handle.empty());
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- GetMediaTransferProtocolManager()->CloseStorage(device_handle,
- Bind(&DoNothing));
-}
-
-// 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".
-std::string GetDeviceRelativePath(const std::string& registered_dev_path,
- const std::string& file_path) {
- DCHECK(!registered_dev_path.empty());
- DCHECK(!file_path.empty());
-
- std::string actual_file_path;
- if (registered_dev_path == file_path) {
- actual_file_path = kRootPath;
- } else {
- actual_file_path = file_path;
- ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
- registered_dev_path.c_str(), "");
- }
- DCHECK(!actual_file_path.empty());
- return actual_file_path;
-}
-
-// Worker class to open a MTP device for communication. This class is
-// instantiated and destructed on |media_task_runner_|. In order to post a
-// request on Dbus thread, the caller should run on UI thread. Therefore, this
-// class posts the open device request on UI thread and receives the response
-// on UI thread.
-class OpenStorageWorker
- : public RefCountedThreadSafe<OpenStorageWorker, OpenStorageWorkerDeleter> {
- public:
- // Constructed on |media_task_runner_| thread.
- OpenStorageWorker(const std::string& name, SequencedTaskRunner* task_runner,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : storage_name_(name),
- media_task_runner_(task_runner),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- }
-
- // This function is invoked on |media_task_runner_| to post the task on UI
- // thread. This blocks the |media_task_runner_| until the task is complete.
- void Run() {
- if (on_shutdown_event_->IsSignaled()) {
- // Process is in shutdown mode.
- // Do not post any task on |media_task_runner_|.
- return;
- }
-
- DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- Bind(&OpenStorageWorker::DoWorkOnUIThread, this));
- on_task_completed_event_->Wait();
-
- if (on_shutdown_event_->IsSignaled())
- cancel_tasks_flag_.Set();
- }
-
- // Returns a device handle string if the OpenStorage() request was
- // successfully completed or an empty string otherwise.
- const std::string& device_handle() const { return device_handle_; }
-
- // Returns the |media_task_runner_| associated with this worker object.
- // This function is exposed for WorkerDeleter struct to access the
- // |media_task_runner_|.
- SequencedTaskRunner* media_task_runner() const {
- return media_task_runner_.get();
- }
-
- private:
- friend struct WorkerDeleter<OpenStorageWorker>;
- friend class DeleteHelper<OpenStorageWorker>;
- friend class RefCountedThreadSafe<OpenStorageWorker,
- OpenStorageWorkerDeleter>;
-
- // Destructed via OpenStorageWorkerDeleter struct.
- virtual ~OpenStorageWorker() {
- // This object must be destructed on |media_task_runner_|.
- }
-
- // Dispatches a request to MediaTransferProtocolManager to open the MTP
- // storage for communication. This is called on UI thread.
- void DoWorkOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- GetMediaTransferProtocolManager()->OpenStorage(
- storage_name_, mtpd::kReadOnlyMode,
- Bind(&OpenStorageWorker::OnDidWorkOnUIThread, this));
- }
-
- // Query callback for DoWorkOnUIThread(). |error| is set to true if the device
- // did not open successfully. This function signals to unblock
- // |media_task_runner_|.
- void OnDidWorkOnUIThread(const std::string& device_handle, bool error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- if (!error)
- device_handle_ = device_handle;
- on_task_completed_event_->Signal();
- }
-
- // Stores the storage name to open the device.
- const std::string storage_name_;
-
- // Stores a reference to |media_task_runner_| to destruct this object on the
- // correct thread.
- scoped_refptr<SequencedTaskRunner> media_task_runner_;
-
- // |media_task_runner_| can wait on this event until the required operation
- // is complete.
- // TODO(kmadhusu): Remove this WaitableEvent after modifying the
- // DeviceMediaFileUtil functions as asynchronous functions.
- WaitableEvent* on_task_completed_event_;
-
- // Stores a reference to waitable event associated with the shut down message.
- WaitableEvent* on_shutdown_event_;
-
- // Stores the result of OpenStorage() request.
- std::string device_handle_;
-
- // Set to ignore the request results. This will be set when
- // MTPDeviceDelegateImplLinux object is about to be deleted.
- // |on_task_completed_event_| and |on_shutdown_event_| should not be
- // dereferenced when this is set.
- base::CancellationFlag cancel_tasks_flag_;
-
- DISALLOW_COPY_AND_ASSIGN(OpenStorageWorker);
-};
-
-// Worker class to get media device file information given a |path|.
-class GetFileInfoWorker
- : public RefCountedThreadSafe<GetFileInfoWorker, GetFileInfoWorkerDeleter> {
- public:
- // Constructed on |media_task_runner_| thread.
- GetFileInfoWorker(const std::string& handle,
- const std::string& path,
- SequencedTaskRunner* task_runner,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : device_handle_(handle),
- path_(path),
- media_task_runner_(task_runner),
- error_(base::PLATFORM_FILE_OK),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- }
-
- // This function is invoked on |media_task_runner_| to post the task on UI
- // thread. This blocks the |media_task_runner_| until the task is complete.
- void Run() {
- if (on_shutdown_event_->IsSignaled()) {
- // Process is in shutdown mode.
- // Do not post any task on |media_task_runner_|.
- return;
- }
-
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- Bind(&GetFileInfoWorker::DoWorkOnUIThread, this));
- on_task_completed_event_->Wait();
-
- if (on_shutdown_event_->IsSignaled())
- cancel_tasks_flag_.Set();
- }
-
- // Returns GetFileInfo() result and fills in |file_info| with requested file
- // entry details.
- PlatformFileError get_file_info(PlatformFileInfo* file_info) const {
- if (file_info)
- *file_info = file_entry_info_;
- return error_;
- }
-
- // Returns the |media_task_runner_| associated with this worker object.
- // This function is exposed for WorkerDeleter struct to access the
- // |media_task_runner_|.
- SequencedTaskRunner* media_task_runner() const {
- return media_task_runner_.get();
- }
-
- private:
- friend struct WorkerDeleter<GetFileInfoWorker>;
- friend class DeleteHelper<GetFileInfoWorker>;
- friend class RefCountedThreadSafe<GetFileInfoWorker,
- GetFileInfoWorkerDeleter>;
-
- // Destructed via GetFileInfoWorkerDeleter.
- virtual ~GetFileInfoWorker() {
- // This object must be destructed on |media_task_runner_|.
- }
-
- // Dispatches a request to MediaTransferProtocolManager to get file
- // information.
- void DoWorkOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet()) {
- error_ = base::PLATFORM_FILE_ERROR_FAILED;
- return;
- }
-
- GetMediaTransferProtocolManager()->GetFileInfoByPath(
- device_handle_, path_,
- Bind(&GetFileInfoWorker::OnDidWorkOnUIThread, this));
- }
-
- // Query callback for DoWorkOnUIThread(). On success, |file_entry| has media
- // file information. On failure, |error| is set to true. This function signals
- // to unblock |media_task_runner_|.
- void OnDidWorkOnUIThread(const MtpFileEntry& file_entry, bool error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet()) {
- error_ = base::PLATFORM_FILE_ERROR_FAILED;
- return;
- }
-
- if (error) {
- error_ = base::PLATFORM_FILE_ERROR_NOT_FOUND;
- } else {
- file_entry_info_.size = file_entry.file_size();
- file_entry_info_.is_directory =
- file_entry.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
- file_entry_info_.is_symbolic_link = false;
- file_entry_info_.last_modified =
- base::Time::FromTimeT(file_entry.modification_time());
- file_entry_info_.last_accessed =
- base::Time::FromTimeT(file_entry.modification_time());
- file_entry_info_.creation_time = base::Time();
- }
- on_task_completed_event_->Signal();
- }
-
- // Stores the device handle to query the device.
- const std::string device_handle_;
-
- // Stores the requested media device file path.
- const std::string path_;
-
- // Stores a reference to |media_task_runner_| to destruct this object on the
- // correct thread.
- scoped_refptr<SequencedTaskRunner> media_task_runner_;
-
- // Stores the result of GetFileInfo().
- PlatformFileError error_;
-
- // Stores the media file entry information.
- PlatformFileInfo file_entry_info_;
-
- // |media_task_runner_| can wait on this event until the required operation
- // is complete.
- // TODO(kmadhusu): Remove this WaitableEvent after modifying the
- // DeviceMediaFileUtil functions as asynchronous functions.
- WaitableEvent* on_task_completed_event_;
-
- // Stores a reference to waitable event associated with the shut down message.
- WaitableEvent* on_shutdown_event_;
-
- // Set to ignore the request results. This will be set when
- // MTPDeviceDelegateImplLinux object is about to be deleted.
- // |on_task_completed_event_| and |on_shutdown_event_| should not be
- // dereferenced when this is set.
- base::CancellationFlag cancel_tasks_flag_;
-
- DISALLOW_COPY_AND_ASSIGN(GetFileInfoWorker);
-};
-
-// Worker class to read media device file data given a file |path|.
-class ReadFileWorker
- : public RefCountedThreadSafe<ReadFileWorker, ReadFileWorkerDeleter> {
- public:
- // Constructed on |media_task_runner_| thread.
- ReadFileWorker(const std::string& handle,
- const std::string& src_path,
- uint32 total_size,
- const FilePath& dest_path,
- SequencedTaskRunner* task_runner,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : device_handle_(handle),
- src_path_(src_path),
- total_bytes_(total_size),
- dest_path_(dest_path),
- bytes_read_(0),
- error_occurred_(false),
- media_task_runner_(task_runner),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- }
-
- // This function is invoked on |media_task_runner_| to post the task on UI
- // thread. This blocks the |media_task_runner_| until the task is complete.
- void Run() {
- if (on_shutdown_event_->IsSignaled()) {
- // Process is in shutdown mode.
- // Do not post any task on |media_task_runner_|.
- return;
- }
-
- int dest_fd = open(dest_path_.value().c_str(), O_WRONLY);
- if (dest_fd < 0)
- return;
- file_util::ScopedFD dest_fd_scoper(&dest_fd);
-
- while (bytes_read_ < total_bytes_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- Bind(&ReadFileWorker::DoWorkOnUIThread, this));
- on_task_completed_event_->Wait();
- if (error_occurred_)
- break;
- if (on_shutdown_event_->IsSignaled()) {
- cancel_tasks_flag_.Set();
- break;
- }
-
- int bytes_written =
- file_util::WriteFileDescriptor(dest_fd, data_.data(), data_.size());
- if (static_cast<int>(data_.size()) != bytes_written)
- break;
-
- bytes_read_ += data_.size();
- }
- }
-
- bool Succeeded() const {
- return !error_occurred_ && (bytes_read_ == total_bytes_);
- }
-
- // Returns the |media_task_runner_| associated with this worker object.
- // This function is exposed for WorkerDeleter struct to access the
- // |media_task_runner_|.
- SequencedTaskRunner* media_task_runner() const {
- return media_task_runner_.get();
- }
-
- private:
- friend struct WorkerDeleter<ReadFileWorker>;
- friend class DeleteHelper<ReadFileWorker>;
- friend class RefCountedThreadSafe<ReadFileWorker, ReadFileWorkerDeleter>;
-
- // Destructed via ReadFileWorkerDeleter.
- virtual ~ReadFileWorker() {
- // This object must be destructed on |media_task_runner_|.
- }
-
- // Dispatches a request to MediaTransferProtocolManager to get the media file
- // contents.
- void DoWorkOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- GetMediaTransferProtocolManager()->ReadFileChunkByPath(
- device_handle_, src_path_, bytes_read_, BytesToRead(),
- Bind(&ReadFileWorker::OnDidWorkOnUIThread, this));
- }
-
- // Query callback for DoWorkOnUIThread(). On success, |data| has the media
- // file contents. On failure, |error| is set to true. This function signals
- // to unblock |media_task_runner_|.
- void OnDidWorkOnUIThread(const std::string& data, bool error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- error_occurred_ = error || (data.size() != BytesToRead());
- if (!error_occurred_)
- data_ = data;
- on_task_completed_event_->Signal();
- }
-
- uint32 BytesToRead() const {
- // Read data in 1 MB chunks.
- static const uint32 kReadChunkSize = 1024 * 1024;
- return std::min(kReadChunkSize, total_bytes_ - bytes_read_);
- }
-
- // The device unique identifier to query the device.
- const std::string device_handle_;
-
- // The media device file path.
- const std::string src_path_;
-
- // Number of bytes to read.
- const uint32 total_bytes_;
-
- // Where to write the data read from the device.
- const FilePath dest_path_;
-
- /*****************************************************************************
- * The variables below are accessed on both |media_task_runner_| and the UI
- * thread. However, there's no concurrent access because the UI thread is in a
- * blocked state when access occurs on |media_task_runner_|.
- */
-
- // Number of bytes read from the device.
- uint32 bytes_read_;
-
- // Temporary data storage.
- std::string data_;
-
- // Whether an error occurred during file transfer.
- bool error_occurred_;
-
- /****************************************************************************/
-
- // A reference to |media_task_runner_| to destruct this object on the correct
- // thread.
- scoped_refptr<SequencedTaskRunner> media_task_runner_;
-
- // |media_task_runner_| can wait on this event until the required operation
- // is complete.
- // TODO(kmadhusu): Remove this WaitableEvent after modifying the
- // DeviceMediaFileUtil functions as asynchronous functions.
- WaitableEvent* on_task_completed_event_;
-
- // Stores a reference to waitable event associated with the shut down message.
- WaitableEvent* on_shutdown_event_;
-
- // Set to ignore the request results. This will be set when
- // MTPDeviceDelegateImplLinux object is about to be deleted.
- // |on_task_completed_event_| and |on_shutdown_event_| should not be
- // dereferenced when this is set.
- base::CancellationFlag cancel_tasks_flag_;
-
- DISALLOW_COPY_AND_ASSIGN(ReadFileWorker);
-};
-
-// Worker class to read directory contents. Device is already opened for
-// communication.
-class ReadDirectoryWorker
- : public RefCountedThreadSafe<ReadDirectoryWorker,
- ReadDirectoryWorkerDeleter> {
- public:
- // Construct a worker object given the directory |path|. This object is
- // constructed on |media_task_runner_| thread.
- ReadDirectoryWorker(const std::string& handle,
- const std::string& path,
- SequencedTaskRunner* task_runner,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : device_handle_(handle),
- dir_path_(path),
- dir_entry_id_(0),
- media_task_runner_(task_runner),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(!dir_path_.empty());
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- }
-
- // Construct a worker object given the directory |entry_id|. This object is
- // constructed on |media_task_runner_| thread.
- ReadDirectoryWorker(const std::string& storage_name,
- const uint32_t entry_id,
- SequencedTaskRunner* task_runner,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : device_handle_(storage_name),
- dir_entry_id_(entry_id),
- media_task_runner_(task_runner),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- }
-
- // This function is invoked on |media_task_runner_| to post the task on UI
- // thread. This blocks the |media_task_runner_| until the task is complete.
- void Run() {
- if (on_shutdown_event_->IsSignaled()) {
- // Process is in shutdown mode.
- // Do not post any task on |media_task_runner_|.
- return;
- }
-
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- Bind(&ReadDirectoryWorker::DoWorkOnUIThread, this));
- on_task_completed_event_->Wait();
- if (on_shutdown_event_->IsSignaled())
- cancel_tasks_flag_.Set();
- }
-
- // Returns the directory entries for the given directory path.
- const std::vector<MtpFileEntry>& get_file_entries() const {
- return file_entries_;
- }
-
- // Returns the |media_task_runner_| associated with this worker object.
- // This function is exposed for WorkerDeleter struct to access the
- // |media_task_runner_|.
- SequencedTaskRunner* media_task_runner() const {
- return media_task_runner_.get();
- }
-
- private:
- friend struct WorkerDeleter<ReadDirectoryWorker>;
- friend class DeleteHelper<ReadDirectoryWorker>;
- friend class RefCountedThreadSafe<ReadDirectoryWorker,
- ReadDirectoryWorkerDeleter>;
-
- // Destructed via ReadDirectoryWorkerDeleter.
- virtual ~ReadDirectoryWorker() {
- // This object must be destructed on |media_task_runner_|.
- }
-
- // Dispatches a request to MediaTransferProtocolManager to read the directory
- // entries. This is called on UI thread.
- void DoWorkOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- if (!dir_path_.empty()) {
- GetMediaTransferProtocolManager()->ReadDirectoryByPath(
- device_handle_, dir_path_,
- Bind(&ReadDirectoryWorker::OnDidWorkOnUIThread, this));
- } else {
- GetMediaTransferProtocolManager()->ReadDirectoryById(
- device_handle_, dir_entry_id_,
- Bind(&ReadDirectoryWorker::OnDidWorkOnUIThread, this));
- }
- }
-
- // Query callback for DoWorkOnUIThread(). On success, |file_entries| has the
- // directory file entries. |error| is true if there was an error. This
- // function signals to unblock |media_task_runner_|.
- void OnDidWorkOnUIThread(const std::vector<MtpFileEntry>& file_entries,
- bool error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (cancel_tasks_flag_.IsSet())
- return;
-
- if (!error)
- file_entries_ = file_entries;
- on_task_completed_event_->Signal();
- }
-
- // Stores the device handle to communicate with storage device.
- const std::string device_handle_;
-
- // Stores the directory path whose contents needs to be listed.
- const std::string dir_path_;
-
- // Stores the directory entry id whose contents needs to be listed.
- const uint32_t dir_entry_id_;
-
- // Stores a reference to |media_task_runner_| to destruct this object on the
- // correct thread.
- scoped_refptr<SequencedTaskRunner> media_task_runner_;
-
- // |media_task_runner_| can wait on this event until the required operation
- // is complete.
- // TODO(kmadhusu): Remove this WaitableEvent after modifying the
- // DeviceMediaFileUtil functions as asynchronous functions.
- WaitableEvent* on_task_completed_event_;
-
- // Stores a reference to waitable event associated with the shut down message.
- WaitableEvent* on_shutdown_event_;
-
- // Stores the result of read directory request.
- std::vector<MtpFileEntry> file_entries_;
-
- // Set to ignore the request results. This will be set when
- // MTPDeviceDelegateImplLinux object is about to be deleted.
- // |on_task_completed_event_| and |on_shutdown_event_| should not be
- // dereferenced when this is set.
- base::CancellationFlag cancel_tasks_flag_;
-
- DISALLOW_COPY_AND_ASSIGN(ReadDirectoryWorker);
-};
-
-// Simply enumerate each files from a given file entry list.
-// Used to enumerate top-level files of an media file system.
-class MediaFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
- public:
- explicit MediaFileEnumerator(const std::vector<MtpFileEntry>& entries)
- : file_entries_(entries),
- file_entry_iter_(file_entries_.begin()) {
- }
-
- virtual ~MediaFileEnumerator() {}
-
- // AbstractFileEnumerator override.
- // Returns the next file entry path on success and empty file path on
- // failure.
- virtual FilePath Next() OVERRIDE {
- if (file_entry_iter_ == file_entries_.end())
- return FilePath();
-
- current_file_info_ = *file_entry_iter_;
- ++file_entry_iter_;
- return FilePath(current_file_info_.file_name());
- }
-
- // AbstractFileEnumerator override.
- // Returns the size of the current file entry.
- virtual int64 Size() OVERRIDE {
- return current_file_info_.file_size();
- }
-
- // AbstractFileEnumerator override.
- // Returns true if the current file entry is a directory else false.
- virtual bool IsDirectory() OVERRIDE {
- return current_file_info_.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
- }
-
- // AbstractFileEnumerator override.
- // Returns the last modified time of the current file entry.
- virtual base::Time LastModifiedTime() OVERRIDE {
- return base::Time::FromTimeT(current_file_info_.modification_time());
- }
-
- private:
- // List of directory file entries information.
- const std::vector<MtpFileEntry> file_entries_;
-
- // Iterator to access the individual file entries.
- std::vector<MtpFileEntry>::const_iterator file_entry_iter_;
-
- // Stores the current file information.
- MtpFileEntry current_file_info_;
-
- DISALLOW_COPY_AND_ASSIGN(MediaFileEnumerator);
-};
-
-// Recursively enumerate each file entry from a given media file entry set.
-class RecursiveMediaFileEnumerator
- : public FileSystemFileUtil::AbstractFileEnumerator {
- public:
- RecursiveMediaFileEnumerator(const std::string& handle,
- SequencedTaskRunner* task_runner,
- const std::vector<MtpFileEntry>& entries,
- WaitableEvent* task_completed_event,
- WaitableEvent* shutdown_event)
- : device_handle_(handle),
- media_task_runner_(task_runner),
- file_entries_(entries),
- file_entry_iter_(file_entries_.begin()),
- on_task_completed_event_(task_completed_event),
- on_shutdown_event_(shutdown_event) {
- DCHECK(on_task_completed_event_);
- DCHECK(on_shutdown_event_);
- current_enumerator_.reset(new MediaFileEnumerator(entries));
- }
-
- virtual ~RecursiveMediaFileEnumerator() {}
-
- // AbstractFileEnumerator override.
- // Returns the next file entry path on success and empty file path on
- // failure or when it reaches the end.
- virtual FilePath Next() OVERRIDE {
- if (on_shutdown_event_->IsSignaled()) {
- // Process is in shut down mode.
- return FilePath();
- }
-
- FilePath path = current_enumerator_->Next();
- if (!path.empty())
- return path;
-
- // We reached the end.
- if (file_entry_iter_ == file_entries_.end())
- return FilePath();
-
- // Enumerate subdirectories of the next media file entry.
- MtpFileEntry next_file_entry = *file_entry_iter_;
- ++file_entry_iter_;
-
- // Create a ReadDirectoryWorker object to enumerate sub directories.
- scoped_refptr<ReadDirectoryWorker> worker(new ReadDirectoryWorker(
- device_handle_, next_file_entry.item_id(), media_task_runner_,
- on_task_completed_event_, on_shutdown_event_));
- worker->Run();
- if (!worker->get_file_entries().empty()) {
- current_enumerator_.reset(
- new MediaFileEnumerator(worker->get_file_entries()));
- } else {
- current_enumerator_.reset(new FileSystemFileUtil::EmptyFileEnumerator());
- }
- return current_enumerator_->Next();
- }
-
- // AbstractFileEnumerator override.
- // Returns the size of the current file entry.
- virtual int64 Size() OVERRIDE {
- return current_enumerator_->Size();
- }
-
- // AbstractFileEnumerator override.
- // Returns true if the current media file entry is a folder type else false.
- virtual bool IsDirectory() OVERRIDE {
- return current_enumerator_->IsDirectory();
- }
-
- // AbstractFileEnumerator override.
- // Returns the last modified time of the current file entry.
- virtual base::Time LastModifiedTime() OVERRIDE {
- return current_enumerator_->LastModifiedTime();
- }
-
- private:
- // Stores the device handle that was used to open the device.
- const std::string device_handle_;
-
- // Stores a reference to |media_task_runner_| to construct and destruct
- // ReadDirectoryWorker object on the correct thread.
- scoped_refptr<SequencedTaskRunner> media_task_runner_;
-
- // List of top-level directory file entries.
- const std::vector<MtpFileEntry> file_entries_;
-
- // Iterator to access the individual file entries.
- std::vector<MtpFileEntry>::const_iterator file_entry_iter_;
-
- // Enumerator to access current directory Id/path entries.
- scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> current_enumerator_;
-
- // |media_task_runner_| can wait on this event until the requested operation
- // is complete.
- WaitableEvent* on_task_completed_event_;
-
- // Stores a reference to waitable event associated with the shut down message.
- WaitableEvent* on_shutdown_event_;
-
- DISALLOW_COPY_AND_ASSIGN(RecursiveMediaFileEnumerator);
-};
-
-} // namespace
-
-MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux(
- const std::string& device_location)
- : device_path_(device_location),
- on_task_completed_event_(false, false),
- on_shutdown_event_(true, false) {
- CHECK(!device_path_.empty());
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
- base::SequencedWorkerPool::SequenceToken media_sequence_token =
- pool->GetNamedSequenceToken("media-task-runner");
- media_task_runner_ = pool->GetSequencedTaskRunner(media_sequence_token);
-}
-
-PlatformFileError MTPDeviceDelegateImplLinux::GetFileInfo(
- const FilePath& file_path,
- PlatformFileInfo* file_info) {
- if (!LazyInit())
- return base::PLATFORM_FILE_ERROR_FAILED;
-
- scoped_refptr<GetFileInfoWorker> worker(new GetFileInfoWorker(
- device_handle_, GetDeviceRelativePath(device_path_, file_path.value()),
- media_task_runner_, &on_task_completed_event_, &on_shutdown_event_));
- worker->Run();
- return worker->get_file_info(file_info);
-}
-
-scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
- MTPDeviceDelegateImplLinux::CreateFileEnumerator(
- const FilePath& root,
- bool recursive) {
- if (root.value().empty() || !LazyInit()) {
- return make_scoped_ptr(new FileSystemFileUtil::EmptyFileEnumerator())
- .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
- }
-
- scoped_refptr<ReadDirectoryWorker> worker(new ReadDirectoryWorker(
- device_handle_, GetDeviceRelativePath(device_path_, root.value()),
- media_task_runner_, &on_task_completed_event_, &on_shutdown_event_));
- worker->Run();
-
- if (worker->get_file_entries().empty()) {
- return make_scoped_ptr(new FileSystemFileUtil::EmptyFileEnumerator())
- .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
- }
-
- if (recursive) {
- return make_scoped_ptr(new RecursiveMediaFileEnumerator(
- device_handle_, media_task_runner_, worker->get_file_entries(),
- &on_task_completed_event_, &on_shutdown_event_))
- .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
- }
- return make_scoped_ptr(new MediaFileEnumerator(worker->get_file_entries()))
- .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
-}
-
-PlatformFileError MTPDeviceDelegateImplLinux::CreateSnapshotFile(
- const FilePath& device_file_path,
- const FilePath& local_path,
- PlatformFileInfo* file_info) {
- if (!LazyInit())
- return base::PLATFORM_FILE_ERROR_FAILED;
-
- PlatformFileError error = GetFileInfo(device_file_path, file_info);
- if (error != base::PLATFORM_FILE_OK)
- return error;
-
- if (file_info->size <= 0 || file_info->size > kuint32max)
- return base::PLATFORM_FILE_ERROR_FAILED;
-
- scoped_refptr<ReadFileWorker> worker(new ReadFileWorker(
- device_handle_,
- GetDeviceRelativePath(device_path_, device_file_path.value()),
- file_info->size, local_path, media_task_runner_,
- &on_task_completed_event_, &on_shutdown_event_));
- worker->Run();
-
- if (!worker->Succeeded())
- return base::PLATFORM_FILE_ERROR_FAILED;
-
- // Modify the last modified time to null. This prevents the time stamp
- // verfication in LocalFileStreamReader.
- file_info->last_modified = base::Time();
- return base::PLATFORM_FILE_OK;
-}
-
-SequencedTaskRunner* MTPDeviceDelegateImplLinux::GetMediaTaskRunner() {
- return media_task_runner_.get();
-}
-
-void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Caution: This function is called on the IO thread. Access only the thread
- // safe member variables in this function. Do all the clean up operations in
- // DeleteDelegateOnTaskRunner().
- on_shutdown_event_.Signal();
- on_task_completed_event_.Signal();
- media_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&MTPDeviceDelegateImplLinux::DeleteDelegateOnTaskRunner,
- base::Unretained(this)));
-}
-
-base::WeakPtr<fileapi::MTPDeviceDelegate> MTPDeviceDelegateImplLinux::
- GetAsWeakPtrOnIOThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- base::WeakPtr<fileapi::MTPDeviceDelegate> delegate = AsWeakPtr();
- // The weak pointer is instantiated on the IO thread, but only accessed on
- // |media_task_runner_|. Therefore, detach from the current thread.
- DetachFromThread();
- return delegate;
-}
-
-MTPDeviceDelegateImplLinux::~MTPDeviceDelegateImplLinux() {
- DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
- // Do all the clean up operations on DeleteDelegateOnTaskRunner().
-}
-
-bool MTPDeviceDelegateImplLinux::LazyInit() {
- DCHECK(media_task_runner_);
- DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
-
- if (!device_handle_.empty())
- return true; // Already successfully initialized.
-
- std::string storage_name;
- RemoveChars(device_path_, kRootPath, &storage_name);
- DCHECK(!storage_name.empty());
- scoped_refptr<OpenStorageWorker> worker(new OpenStorageWorker(
- storage_name, media_task_runner_, &on_task_completed_event_,
- &on_shutdown_event_));
- worker->Run();
- device_handle_ = worker->device_handle();
- return !device_handle_.empty();
-}
-
-void MTPDeviceDelegateImplLinux::DeleteDelegateOnTaskRunner() {
- DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- Bind(&CloseStorageOnUIThread, device_handle_));
- delete this;
-}
-
-} // namespace chrome
« no previous file with comments | « chrome/browser/media_gallery/mtp_device_delegate_impl_linux.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698