12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_ 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <list> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Delegate for presenting an Image Capture device through the filesystem 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// API. The synthetic filesystem will be rooted at the constructed location, 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and names of all files notified through the ItemAdded call will be 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// all appear as children of that directory. (ItemAdded calls with directories 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// will be ignored.) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Note on thread management: This class is thread-compatible: it can be created 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// on any thread, but then mutates all state on the UI thread. The async 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// delegate interface can be invoked on any thread, as it simply forwards calls 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to the UI thread. 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MTPDeviceDelegateImplMac : public MTPDeviceAsyncDelegate { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceDelegateImplMac(const std::string& device_id, 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath::StringType& synthetic_path); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // MTPDeviceAsyncDelegate implementation. These functions are called on the 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // IO thread by the async filesystem file util. They forward to 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // similarly-named methods on the UI thread. 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetFileInfo( 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path, 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetFileInfoSuccessCallback& success_callback, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE; 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Note: passed absolute paths, but expects relative paths in reply. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ReadDirectory( 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& root, 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ReadDirectorySuccessCallback& success_callback, 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE; 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Note: passed absolute paths. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void CreateSnapshotFile( 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& device_file_path, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_path, 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CreateSnapshotFileSuccessCallback& success_callback, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool IsStreaming() OVERRIDE; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ReadBytes(const base::FilePath& device_file_path, 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<net::IOBuffer>& buf, 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64 offset, 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int buf_len, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ReadBytesSuccessCallback& success_callback, 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ErrorCallback& error_callback) OVERRIDE; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void CancelPendingTasksAndDeleteDelegate() OVERRIDE; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Forward delegates for ImageCaptureDeviceListener. These are 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // invoked in callbacks of the ImageCapture library on the UI thread. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ItemAdded(const std::string& name, 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& info); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void NoMoreItems(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DownloadedFile(const std::string& name, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Scheduled when early directory reads are requested. The 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // timeout will signal an ABORT error to the caller if the 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // device metadata cannot be read. 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ReadDirectoryTimeout(const base::FilePath& root); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class DeviceListener; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~MTPDeviceDelegateImplMac(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Delegate for GetFileInfo, called on the UI thread. 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void GetFileInfoImpl(const base::FilePath& file_path, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info* file_info, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error* error); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Delegate for ReadDirectory, called on the UI thread. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ReadDirectoryImpl( 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& root, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ReadDirectorySuccessCallback& success_callback, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Delegate for CreateSnapshotFile, called on the UI thread. 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void DownloadFile( 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& device_file_path, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& local_path, 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CreateSnapshotFileSuccessCallback& success_callback, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Public for closures; should not be called except by 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CancelTasksAndDeleteDelegate. 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CancelAndDelete(); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Cancels any outstanding downloads. 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CancelDownloads(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If necessary, notifies the ReadDirectory callback that all data 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // has been read. 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void NotifyReadDir(); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string device_id_; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath root_path_; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Interface object for the camera underlying this MTP session. 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<DeviceListener> camera_interface_; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Stores a map from filename to file metadata received from the camera. 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<base::FilePath::StringType, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info> file_info_; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // List of filenames received from the camera. 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> file_paths_; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set to true when all file metadata has been received from the camera. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool received_all_files_; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) struct ReadFileRequest { 125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ReadFileRequest(); 126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ReadFileRequest(const std::string& request_file, 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::FilePath& snapshot_filename, 128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) CreateSnapshotFileSuccessCallback success_cb, 129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ErrorCallback error_cb); 130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ~ReadFileRequest(); 131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string request_file; 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath snapshot_file; 134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) CreateSnapshotFileSuccessCallback success_callback; 135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ErrorCallback error_callback; 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) }; 137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) typedef std::list<ReadFileRequest> ReadFileTransactionList; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct ReadDirectoryRequest { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadDirectoryRequest(const base::FilePath& dir, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadDirectorySuccessCallback success_cb, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ErrorCallback error_cb); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~ReadDirectoryRequest(); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath directory; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadDirectorySuccessCallback success_callback; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ErrorCallback error_callback; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::list<ReadDirectoryRequest> ReadDirTransactionList; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ReadFileTransactionList read_file_transactions_; 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadDirTransactionList read_dir_transactions_; 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtrFactory<MTPDeviceDelegateImplMac> weak_factory_; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMac); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_ 162