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

Side by Side Diff: chrome/browser/media_galleries/linux/mtp_device_task_helper.cc

Issue 2358493002: Remove MTP support on Linux. (Closed)
Patch Set: move files Created 4 years, 2 months 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 unified diff | Download patch
OLDNEW
(Empty)
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 #include <limits>
9
10 #include "base/logging.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 "storage/browser/fileapi/async_file_util.h"
19 #include "storage/common/fileapi/file_system_util.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
21
22 using storage_monitor::StorageMonitor;
23
24 namespace {
25
26 // Does nothing.
27 // This method is used to handle the results of
28 // MediaTransferProtocolManager::CloseStorage method call.
29 void DoNothing(bool error) {
30 }
31
32 device::MediaTransferProtocolManager* GetMediaTransferProtocolManager() {
33 return StorageMonitor::GetInstance()->media_transfer_protocol_manager();
34 }
35
36 base::File::Info FileInfoFromMTPFileEntry(const MtpFileEntry& file_entry) {
37 base::File::Info file_entry_info;
38 file_entry_info.size = file_entry.file_size();
39 file_entry_info.is_directory =
40 file_entry.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
41 file_entry_info.is_symbolic_link = false;
42 file_entry_info.last_modified =
43 base::Time::FromTimeT(file_entry.modification_time());
44 file_entry_info.last_accessed = file_entry_info.last_modified;
45 file_entry_info.creation_time = base::Time();
46 return file_entry_info;
47 }
48
49 } // namespace
50
51 MTPDeviceTaskHelper::MTPDeviceTaskHelper()
52 : weak_ptr_factory_(this) {
53 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
54 }
55
56 MTPDeviceTaskHelper::~MTPDeviceTaskHelper() {
57 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
58 }
59
60 void MTPDeviceTaskHelper::OpenStorage(const std::string& storage_name,
61 const bool read_only,
62 const OpenStorageCallback& callback) {
63 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
64 DCHECK(!storage_name.empty());
65 if (!device_handle_.empty()) {
66 content::BrowserThread::PostTask(content::BrowserThread::IO,
67 FROM_HERE,
68 base::Bind(callback, true));
69 return;
70 }
71
72 const std::string mode =
73 read_only ? mtpd::kReadOnlyMode : mtpd::kReadWriteMode;
74 GetMediaTransferProtocolManager()->OpenStorage(
75 storage_name, mode, base::Bind(&MTPDeviceTaskHelper::OnDidOpenStorage,
76 weak_ptr_factory_.GetWeakPtr(), callback));
77 }
78
79 void MTPDeviceTaskHelper::GetFileInfo(
80 uint32_t file_id,
81 const GetFileInfoSuccessCallback& success_callback,
82 const ErrorCallback& error_callback) {
83 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
84 if (device_handle_.empty())
85 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
86
87 GetMediaTransferProtocolManager()->GetFileInfo(
88 device_handle_, file_id,
89 base::Bind(&MTPDeviceTaskHelper::OnGetFileInfo,
90 weak_ptr_factory_.GetWeakPtr(),
91 success_callback,
92 error_callback));
93 }
94
95 void MTPDeviceTaskHelper::CreateDirectory(
96 const uint32_t parent_id,
97 const std::string& directory_name,
98 const CreateDirectorySuccessCallback& success_callback,
99 const ErrorCallback& error_callback) {
100 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
101 if (device_handle_.empty())
102 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
103
104 GetMediaTransferProtocolManager()->CreateDirectory(
105 device_handle_, parent_id, directory_name,
106 base::Bind(&MTPDeviceTaskHelper::OnCreateDirectory,
107 weak_ptr_factory_.GetWeakPtr(), success_callback,
108 error_callback));
109 }
110
111 void MTPDeviceTaskHelper::ReadDirectory(
112 const uint32_t directory_id,
113 const size_t max_size,
114 const ReadDirectorySuccessCallback& success_callback,
115 const ErrorCallback& error_callback) {
116 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
117 if (device_handle_.empty())
118 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
119
120 GetMediaTransferProtocolManager()->ReadDirectory(
121 device_handle_, directory_id, max_size,
122 base::Bind(&MTPDeviceTaskHelper::OnDidReadDirectory,
123 weak_ptr_factory_.GetWeakPtr(), success_callback,
124 error_callback));
125 }
126
127 void MTPDeviceTaskHelper::WriteDataIntoSnapshotFile(
128 const SnapshotRequestInfo& request_info,
129 const base::File::Info& snapshot_file_info) {
130 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
131 if (device_handle_.empty()) {
132 return HandleDeviceError(request_info.error_callback,
133 base::File::FILE_ERROR_FAILED);
134 }
135
136 if (!read_file_worker_)
137 read_file_worker_.reset(new MTPReadFileWorker(device_handle_));
138 read_file_worker_->WriteDataIntoSnapshotFile(request_info,
139 snapshot_file_info);
140 }
141
142 void MTPDeviceTaskHelper::ReadBytes(
143 const MTPDeviceAsyncDelegate::ReadBytesRequest& request) {
144 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
145 if (device_handle_.empty()) {
146 return HandleDeviceError(request.error_callback,
147 base::File::FILE_ERROR_FAILED);
148 }
149
150 GetMediaTransferProtocolManager()->GetFileInfo(
151 device_handle_, request.file_id,
152 base::Bind(&MTPDeviceTaskHelper::OnGetFileInfoToReadBytes,
153 weak_ptr_factory_.GetWeakPtr(), request));
154 }
155
156 void MTPDeviceTaskHelper::RenameObject(
157 const uint32_t object_id,
158 const std::string& new_name,
159 const RenameObjectSuccessCallback& success_callback,
160 const ErrorCallback& error_callback) {
161 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
162
163 GetMediaTransferProtocolManager()->RenameObject(
164 device_handle_, object_id, new_name,
165 base::Bind(&MTPDeviceTaskHelper::OnRenameObject,
166 weak_ptr_factory_.GetWeakPtr(), success_callback,
167 error_callback));
168 }
169
170 MTPDeviceTaskHelper::MTPEntry::MTPEntry() : file_id(0) {}
171
172 // TODO(yawano) storage_name is not used, delete it.
173 void MTPDeviceTaskHelper::CopyFileFromLocal(
174 const std::string& storage_name,
175 const int source_file_descriptor,
176 const uint32_t parent_id,
177 const std::string& file_name,
178 const CopyFileFromLocalSuccessCallback& success_callback,
179 const ErrorCallback& error_callback) {
180 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
181
182 GetMediaTransferProtocolManager()->CopyFileFromLocal(
183 device_handle_, source_file_descriptor, parent_id, file_name,
184 base::Bind(&MTPDeviceTaskHelper::OnCopyFileFromLocal,
185 weak_ptr_factory_.GetWeakPtr(), success_callback,
186 error_callback));
187 }
188
189 void MTPDeviceTaskHelper::DeleteObject(
190 const uint32_t object_id,
191 const DeleteObjectSuccessCallback& success_callback,
192 const ErrorCallback& error_callback) {
193 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
194
195 GetMediaTransferProtocolManager()->DeleteObject(
196 device_handle_, object_id,
197 base::Bind(&MTPDeviceTaskHelper::OnDeleteObject,
198 weak_ptr_factory_.GetWeakPtr(), success_callback,
199 error_callback));
200 }
201
202 void MTPDeviceTaskHelper::CloseStorage() const {
203 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
204 if (device_handle_.empty())
205 return;
206 GetMediaTransferProtocolManager()->CloseStorage(device_handle_,
207 base::Bind(&DoNothing));
208 }
209
210 void MTPDeviceTaskHelper::OnDidOpenStorage(
211 const OpenStorageCallback& completion_callback,
212 const std::string& device_handle,
213 bool error) {
214 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
215 device_handle_ = device_handle;
216 content::BrowserThread::PostTask(content::BrowserThread::IO,
217 FROM_HERE,
218 base::Bind(completion_callback, !error));
219 }
220
221 void MTPDeviceTaskHelper::OnGetFileInfo(
222 const GetFileInfoSuccessCallback& success_callback,
223 const ErrorCallback& error_callback,
224 const MtpFileEntry& file_entry,
225 bool error) const {
226 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
227 if (error) {
228 return HandleDeviceError(error_callback,
229 base::File::FILE_ERROR_NOT_FOUND);
230 }
231
232 content::BrowserThread::PostTask(
233 content::BrowserThread::IO,
234 FROM_HERE,
235 base::Bind(success_callback, FileInfoFromMTPFileEntry(file_entry)));
236 }
237
238 void MTPDeviceTaskHelper::OnCreateDirectory(
239 const CreateDirectorySuccessCallback& success_callback,
240 const ErrorCallback& error_callback,
241 const bool error) const {
242 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
243 if (error) {
244 content::BrowserThread::PostTask(
245 content::BrowserThread::IO, FROM_HERE,
246 base::Bind(error_callback, base::File::FILE_ERROR_FAILED));
247 return;
248 }
249
250 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
251 success_callback);
252 }
253
254 void MTPDeviceTaskHelper::OnDidReadDirectory(
255 const ReadDirectorySuccessCallback& success_callback,
256 const ErrorCallback& error_callback,
257 const std::vector<MtpFileEntry>& file_entries,
258 bool has_more,
259 bool error) const {
260 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
261 if (error)
262 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
263
264 MTPEntries entries;
265 base::FilePath current;
266 MTPDeviceObjectEnumerator file_enum(file_entries);
267 while (!(current = file_enum.Next()).empty()) {
268 MTPEntry entry;
269 entry.name = storage::VirtualPath::BaseName(current).value();
270 bool ret = file_enum.GetEntryId(&entry.file_id);
271 DCHECK(ret);
272 entry.file_info.is_directory = file_enum.IsDirectory();
273 entry.file_info.size = file_enum.Size();
274 entry.file_info.last_modified = file_enum.LastModifiedTime();
275 entries.push_back(entry);
276 }
277 content::BrowserThread::PostTask(
278 content::BrowserThread::IO,
279 FROM_HERE,
280 base::Bind(success_callback, entries, has_more));
281 }
282
283 void MTPDeviceTaskHelper::OnGetFileInfoToReadBytes(
284 const MTPDeviceAsyncDelegate::ReadBytesRequest& request,
285 const MtpFileEntry& file_entry,
286 bool error) {
287 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
288 DCHECK(request.buf.get());
289 DCHECK_GE(request.buf_len, 0);
290 DCHECK_GE(request.offset, 0);
291 if (error) {
292 return HandleDeviceError(request.error_callback,
293 base::File::FILE_ERROR_FAILED);
294 }
295
296 base::File::Info file_info = FileInfoFromMTPFileEntry(file_entry);
297 if (file_info.is_directory) {
298 return HandleDeviceError(request.error_callback,
299 base::File::FILE_ERROR_NOT_A_FILE);
300 } else if (file_info.size < 0 ||
301 file_info.size > std::numeric_limits<uint32_t>::max() ||
302 request.offset > file_info.size) {
303 return HandleDeviceError(request.error_callback,
304 base::File::FILE_ERROR_FAILED);
305 } else if (request.offset == file_info.size) {
306 content::BrowserThread::PostTask(content::BrowserThread::IO,
307 FROM_HERE,
308 base::Bind(request.success_callback,
309 file_info, 0u));
310 return;
311 }
312
313 uint32_t bytes_to_read =
314 std::min(base::checked_cast<uint32_t>(request.buf_len),
315 base::saturated_cast<uint32_t>(file_info.size - request.offset));
316
317 GetMediaTransferProtocolManager()->ReadFileChunk(
318 device_handle_, request.file_id,
319 base::checked_cast<uint32_t>(request.offset), bytes_to_read,
320 base::Bind(&MTPDeviceTaskHelper::OnDidReadBytes,
321 weak_ptr_factory_.GetWeakPtr(), request, file_info));
322 }
323
324 void MTPDeviceTaskHelper::OnDidReadBytes(
325 const MTPDeviceAsyncDelegate::ReadBytesRequest& request,
326 const base::File::Info& file_info,
327 const std::string& data,
328 bool error) const {
329 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
330 if (error) {
331 return HandleDeviceError(request.error_callback,
332 base::File::FILE_ERROR_FAILED);
333 }
334
335 CHECK_LE(base::checked_cast<int>(data.length()), request.buf_len);
336 std::copy(data.begin(), data.end(), request.buf->data());
337
338 content::BrowserThread::PostTask(content::BrowserThread::IO,
339 FROM_HERE,
340 base::Bind(request.success_callback,
341 file_info, data.length()));
342 }
343
344 void MTPDeviceTaskHelper::OnRenameObject(
345 const RenameObjectSuccessCallback& success_callback,
346 const ErrorCallback& error_callback,
347 const bool error) const {
348 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
349 if (error) {
350 content::BrowserThread::PostTask(
351 content::BrowserThread::IO, FROM_HERE,
352 base::Bind(error_callback, base::File::FILE_ERROR_FAILED));
353 return;
354 }
355
356 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
357 success_callback);
358 }
359
360 void MTPDeviceTaskHelper::OnCopyFileFromLocal(
361 const CopyFileFromLocalSuccessCallback& success_callback,
362 const ErrorCallback& error_callback,
363 const bool error) const {
364 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
365 if (error) {
366 content::BrowserThread::PostTask(
367 content::BrowserThread::IO, FROM_HERE,
368 base::Bind(error_callback, base::File::FILE_ERROR_FAILED));
369 return;
370 }
371
372 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
373 success_callback);
374 }
375
376 void MTPDeviceTaskHelper::OnDeleteObject(
377 const DeleteObjectSuccessCallback& success_callback,
378 const ErrorCallback& error_callback,
379 const bool error) const {
380 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
381 if (error) {
382 content::BrowserThread::PostTask(
383 content::BrowserThread::IO, FROM_HERE,
384 base::Bind(error_callback, base::File::FILE_ERROR_FAILED));
385 return;
386 }
387
388 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
389 success_callback);
390 }
391
392 void MTPDeviceTaskHelper::HandleDeviceError(
393 const ErrorCallback& error_callback,
394 base::File::Error error) const {
395 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
396 content::BrowserThread::PostTask(content::BrowserThread::IO,
397 FROM_HERE,
398 base::Bind(error_callback, error));
399 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698