1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_
6#define CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_
7
8#include <list>
9#include <map>
10#include <vector>
11
12#include "base/containers/hash_tables.h"
13#include "base/files/file.h"
14#include "base/files/file_path.h"
15#include "base/memory/weak_ptr.h"
16#include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h"
17
18// Delegate for presenting an Image Capture device through the filesystem
19// API. The synthetic filesystem will be rooted at the constructed location,
20// and names of all files notified through the ItemAdded call will be
21// all appear as children of that directory. (ItemAdded calls with directories
22// will be ignored.)
23// Note on thread management: This class is thread-compatible: it can be created
24// on any thread, but then mutates all state on the UI thread. The async
25// delegate interface can be invoked on any thread, as it simply forwards calls
26// to the UI thread.
27class MTPDeviceDelegateImplMac : public MTPDeviceAsyncDelegate {
28 public:
29  MTPDeviceDelegateImplMac(const std::string& device_id,
30                           const base::FilePath::StringType& synthetic_path);
31
32  // MTPDeviceAsyncDelegate implementation. These functions are called on the
33  // IO thread by the async filesystem file util. They forward to
34  // similarly-named methods on the UI thread.
35  virtual void GetFileInfo(
36      const base::FilePath& file_path,
37      const GetFileInfoSuccessCallback& success_callback,
38      const ErrorCallback& error_callback) OVERRIDE;
39
40  // Note: passed absolute paths, but expects relative paths in reply.
41  virtual void ReadDirectory(
42      const base::FilePath& root,
43      const ReadDirectorySuccessCallback& success_callback,
44      const ErrorCallback& error_callback) OVERRIDE;
45
46  // Note: passed absolute paths.
47  virtual void CreateSnapshotFile(
48      const base::FilePath& device_file_path,
49      const base::FilePath& local_path,
50      const CreateSnapshotFileSuccessCallback& success_callback,
51      const ErrorCallback& error_callback) OVERRIDE;
52  virtual bool IsStreaming() OVERRIDE;
53  virtual void ReadBytes(const base::FilePath& device_file_path,
54                         const scoped_refptr<net::IOBuffer>& buf,
55                         int64 offset,
56                         int buf_len,
57                         const ReadBytesSuccessCallback& success_callback,
58                         const ErrorCallback& error_callback) OVERRIDE;
59  virtual void CancelPendingTasksAndDeleteDelegate() OVERRIDE;
60
61  // Forward delegates for ImageCaptureDeviceListener. These are
62  // invoked in callbacks of the ImageCapture library on the UI thread.
63  virtual void ItemAdded(const std::string& name,
64                         const base::File::Info& info);
65  virtual void NoMoreItems();
66  virtual void DownloadedFile(const std::string& name,
67                              base::File::Error error);
68
69  // Scheduled when early directory reads are requested. The
70  // timeout will signal an ABORT error to the caller if the
71  // device metadata cannot be read.
72  void ReadDirectoryTimeout(const base::FilePath& root);
73
74 private:
75  class DeviceListener;
76
77  virtual ~MTPDeviceDelegateImplMac();
78
79  // Delegate for GetFileInfo, called on the UI thread.
80  void GetFileInfoImpl(const base::FilePath& file_path,
81                       base::File::Info* file_info,
82                       base::File::Error* error);
83
84  // Delegate for ReadDirectory, called on the UI thread.
85  void ReadDirectoryImpl(
86      const base::FilePath& root,
87      const ReadDirectorySuccessCallback& success_callback,
88      const ErrorCallback& error_callback);
89
90  // Delegate for CreateSnapshotFile, called on the UI thread.
91  void DownloadFile(
92      const base::FilePath& device_file_path,
93      const base::FilePath& local_path,
94      const CreateSnapshotFileSuccessCallback& success_callback,
95      const ErrorCallback& error_callback);
96
97  // Public for closures; should not be called except by
98  // CancelTasksAndDeleteDelegate.
99  void CancelAndDelete();
100
101  // Cancels any outstanding downloads.
102  void CancelDownloads();
103
104  // If necessary, notifies the ReadDirectory callback that all data
105  // has been read.
106  void NotifyReadDir();
107
108  std::string device_id_;
109  base::FilePath root_path_;
110
111  // Interface object for the camera underlying this MTP session.
112  scoped_ptr<DeviceListener> camera_interface_;
113
114  // Stores a map from filename to file metadata received from the camera.
115  base::hash_map<base::FilePath::StringType,
116                 base::File::Info> file_info_;
117
118  // List of filenames received from the camera.
119  std::vector<base::FilePath> file_paths_;
120
121  // Set to true when all file metadata has been received from the camera.
122  bool received_all_files_;
123
124  struct ReadFileRequest {
125    ReadFileRequest();
126    ReadFileRequest(const std::string& request_file,
127                    const base::FilePath& snapshot_filename,
128                    CreateSnapshotFileSuccessCallback success_cb,
129                    ErrorCallback error_cb);
130    ~ReadFileRequest();
131
132    std::string request_file;
133    base::FilePath snapshot_file;
134    CreateSnapshotFileSuccessCallback success_callback;
135    ErrorCallback error_callback;
136  };
137
138  typedef std::list<ReadFileRequest> ReadFileTransactionList;
139
140  struct ReadDirectoryRequest {
141    ReadDirectoryRequest(const base::FilePath& dir,
142                         ReadDirectorySuccessCallback success_cb,
143                         ErrorCallback error_cb);
144    ~ReadDirectoryRequest();
145
146    base::FilePath directory;
147    ReadDirectorySuccessCallback success_callback;
148    ErrorCallback error_callback;
149  };
150
151  typedef std::list<ReadDirectoryRequest> ReadDirTransactionList;
152
153  ReadFileTransactionList read_file_transactions_;
154  ReadDirTransactionList read_dir_transactions_;
155
156  base::WeakPtrFactory<MTPDeviceDelegateImplMac> weak_factory_;
157
158  DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMac);
159};
160
161#endif  // CHROME_BROWSER_MEDIA_GALLERIES_MAC_MTP_DEVICE_DELEGATE_IMPL_MAC_H_
162