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