Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / linux / mtp_device_task_helper.cc
1 // Copyright 2013 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 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "chrome/browser/media_galleries/linux/mtp_device_object_enumerator.h"
12 #include "chrome/browser/media_galleries/linux/mtp_read_file_worker.h"
13 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
14 #include "components/storage_monitor/storage_monitor.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h"
17 #include "net/base/io_buffer.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19 #include "webkit/browser/fileapi/async_file_util.h"
20 #include "webkit/common/fileapi/file_system_util.h"
21
22 namespace {
23
24 // Does nothing.
25 // This method is used to handle the results of
26 // MediaTransferProtocolManager::CloseStorage method call.
27 void DoNothing(bool error) {
28 }
29
30 device::MediaTransferProtocolManager* GetMediaTransferProtocolManager() {
31   return StorageMonitor::GetInstance()->media_transfer_protocol_manager();
32 }
33
34 }  // namespace
35
36 MTPDeviceTaskHelper::MTPDeviceTaskHelper()
37     : weak_ptr_factory_(this) {
38   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
39 }
40
41 MTPDeviceTaskHelper::~MTPDeviceTaskHelper() {
42   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
43 }
44
45 void MTPDeviceTaskHelper::OpenStorage(const std::string& storage_name,
46                                       const OpenStorageCallback& callback) {
47   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
48   DCHECK(!storage_name.empty());
49   if (!device_handle_.empty()) {
50     content::BrowserThread::PostTask(content::BrowserThread::IO,
51                                      FROM_HERE,
52                                      base::Bind(callback, true));
53     return;
54   }
55   GetMediaTransferProtocolManager()->OpenStorage(
56       storage_name, mtpd::kReadOnlyMode,
57       base::Bind(&MTPDeviceTaskHelper::OnDidOpenStorage,
58                  weak_ptr_factory_.GetWeakPtr(),
59                  callback));
60 }
61
62 void MTPDeviceTaskHelper::GetFileInfoByPath(
63     const std::string& file_path,
64     const GetFileInfoSuccessCallback& success_callback,
65     const ErrorCallback& error_callback) {
66   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
67   if (device_handle_.empty())
68     return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
69
70   GetMediaTransferProtocolManager()->GetFileInfoByPath(
71       device_handle_, file_path,
72       base::Bind(&MTPDeviceTaskHelper::OnGetFileInfo,
73                  weak_ptr_factory_.GetWeakPtr(),
74                  success_callback,
75                  error_callback));
76 }
77
78 void MTPDeviceTaskHelper::ReadDirectoryByPath(
79     const std::string& dir_path,
80     const ReadDirectorySuccessCallback& success_callback,
81     const ErrorCallback& error_callback) {
82   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
83   if (device_handle_.empty())
84     return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
85
86   GetMediaTransferProtocolManager()->ReadDirectoryByPath(
87       device_handle_, dir_path,
88       base::Bind(&MTPDeviceTaskHelper::OnDidReadDirectoryByPath,
89                  weak_ptr_factory_.GetWeakPtr(),
90                  success_callback,
91                  error_callback));
92 }
93
94 void MTPDeviceTaskHelper::WriteDataIntoSnapshotFile(
95     const SnapshotRequestInfo& request_info,
96     const base::File::Info& snapshot_file_info) {
97   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
98   if (device_handle_.empty()) {
99     return HandleDeviceError(request_info.error_callback,
100                              base::File::FILE_ERROR_FAILED);
101   }
102
103   if (!read_file_worker_)
104     read_file_worker_.reset(new MTPReadFileWorker(device_handle_));
105   read_file_worker_->WriteDataIntoSnapshotFile(request_info,
106                                                snapshot_file_info);
107 }
108
109 void MTPDeviceTaskHelper::ReadBytes(
110     const MTPDeviceAsyncDelegate::ReadBytesRequest& request) {
111   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
112   if (device_handle_.empty()) {
113     return HandleDeviceError(request.error_callback,
114                              base::File::FILE_ERROR_FAILED);
115   }
116
117   GetMediaTransferProtocolManager()->ReadFileChunkByPath(
118       device_handle_,
119       request.device_file_relative_path,
120       base::checked_cast<uint32>(request.offset),
121       base::checked_cast<uint32>(request.buf_len),
122       base::Bind(&MTPDeviceTaskHelper::OnDidReadBytes,
123                  weak_ptr_factory_.GetWeakPtr(), request));
124 }
125
126 void MTPDeviceTaskHelper::CloseStorage() const {
127   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
128   if (device_handle_.empty())
129     return;
130   GetMediaTransferProtocolManager()->CloseStorage(device_handle_,
131                                                   base::Bind(&DoNothing));
132 }
133
134 void MTPDeviceTaskHelper::OnDidOpenStorage(
135     const OpenStorageCallback& completion_callback,
136     const std::string& device_handle,
137     bool error) {
138   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
139   device_handle_ = device_handle;
140   content::BrowserThread::PostTask(content::BrowserThread::IO,
141                                    FROM_HERE,
142                                    base::Bind(completion_callback, !error));
143 }
144
145 void MTPDeviceTaskHelper::OnGetFileInfo(
146     const GetFileInfoSuccessCallback& success_callback,
147     const ErrorCallback& error_callback,
148     const MtpFileEntry& file_entry,
149     bool error) const {
150   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
151   if (error) {
152     return HandleDeviceError(error_callback,
153                              base::File::FILE_ERROR_NOT_FOUND);
154   }
155
156   base::File::Info file_entry_info;
157   file_entry_info.size = file_entry.file_size();
158   file_entry_info.is_directory =
159       file_entry.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
160   file_entry_info.is_symbolic_link = false;
161   file_entry_info.last_modified =
162       base::Time::FromTimeT(file_entry.modification_time());
163   file_entry_info.last_accessed = file_entry_info.last_modified;
164   file_entry_info.creation_time = base::Time();
165   content::BrowserThread::PostTask(content::BrowserThread::IO,
166                                    FROM_HERE,
167                                    base::Bind(success_callback,
168                                               file_entry_info));
169 }
170
171 void MTPDeviceTaskHelper::OnDidReadDirectoryByPath(
172     const ReadDirectorySuccessCallback& success_callback,
173     const ErrorCallback& error_callback,
174     const std::vector<MtpFileEntry>& file_entries,
175     bool error) const {
176   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
177   if (error)
178     return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
179
180   fileapi::AsyncFileUtil::EntryList entries;
181   base::FilePath current;
182   MTPDeviceObjectEnumerator file_enum(file_entries);
183   while (!(current = file_enum.Next()).empty()) {
184     fileapi::DirectoryEntry entry;
185     entry.name = fileapi::VirtualPath::BaseName(current).value();
186     entry.is_directory = file_enum.IsDirectory();
187     entry.size = file_enum.Size();
188     entry.last_modified_time = file_enum.LastModifiedTime();
189     entries.push_back(entry);
190   }
191   content::BrowserThread::PostTask(content::BrowserThread::IO,
192                                    FROM_HERE,
193                                    base::Bind(success_callback, entries));
194 }
195
196 void MTPDeviceTaskHelper::OnDidReadBytes(
197     const MTPDeviceAsyncDelegate::ReadBytesRequest& request,
198     const std::string& data,
199     bool error) const {
200   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
201   if (error) {
202     return HandleDeviceError(request.error_callback,
203                              base::File::FILE_ERROR_FAILED);
204   }
205
206   CHECK_LE(base::checked_cast<int>(data.length()), request.buf_len);
207   std::copy(data.begin(), data.end(), request.buf->data());
208
209   content::BrowserThread::PostTask(content::BrowserThread::IO,
210                                    FROM_HERE,
211                                    base::Bind(request.success_callback,
212                                               data.length()));
213 }
214
215 void MTPDeviceTaskHelper::HandleDeviceError(
216     const ErrorCallback& error_callback,
217     base::File::Error error) const {
218   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
219   content::BrowserThread::PostTask(content::BrowserThread::IO,
220                                    FROM_HERE,
221                                    base::Bind(error_callback, error));
222 }