Disabling NativeViewAcccessibilityWinTest.RetrieveAllAlerts.
[chromium-blink-merge.git] / chrome / browser / media_galleries / linux / mtp_device_task_helper.cc
blobe19ce1815bba6ba8dc91f98a9dfa264b32f44e6a
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.
5 #include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "chrome/browser/media_galleries/linux/mtp_device_object_enumerator.h"
13 #include "chrome/browser/media_galleries/linux/mtp_read_file_worker.h"
14 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
15 #include "components/storage_monitor/storage_monitor.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h"
18 #include "net/base/io_buffer.h"
19 #include "storage/browser/fileapi/async_file_util.h"
20 #include "storage/common/fileapi/file_system_util.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
23 using storage_monitor::StorageMonitor;
25 namespace {
27 // Does nothing.
28 // This method is used to handle the results of
29 // MediaTransferProtocolManager::CloseStorage method call.
30 void DoNothing(bool error) {
33 device::MediaTransferProtocolManager* GetMediaTransferProtocolManager() {
34 return StorageMonitor::GetInstance()->media_transfer_protocol_manager();
37 base::File::Info FileInfoFromMTPFileEntry(const MtpFileEntry& file_entry) {
38 base::File::Info file_entry_info;
39 file_entry_info.size = file_entry.file_size();
40 file_entry_info.is_directory =
41 file_entry.file_type() == MtpFileEntry::FILE_TYPE_FOLDER;
42 file_entry_info.is_symbolic_link = false;
43 file_entry_info.last_modified =
44 base::Time::FromTimeT(file_entry.modification_time());
45 file_entry_info.last_accessed = file_entry_info.last_modified;
46 file_entry_info.creation_time = base::Time();
47 return file_entry_info;
50 } // namespace
52 MTPDeviceTaskHelper::MTPDeviceTaskHelper()
53 : weak_ptr_factory_(this) {
54 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
57 MTPDeviceTaskHelper::~MTPDeviceTaskHelper() {
58 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
61 void MTPDeviceTaskHelper::OpenStorage(const std::string& storage_name,
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;
71 GetMediaTransferProtocolManager()->OpenStorage(
72 storage_name, mtpd::kReadOnlyMode,
73 base::Bind(&MTPDeviceTaskHelper::OnDidOpenStorage,
74 weak_ptr_factory_.GetWeakPtr(),
75 callback));
78 void MTPDeviceTaskHelper::GetFileInfo(
79 uint32 file_id,
80 const GetFileInfoSuccessCallback& success_callback,
81 const ErrorCallback& error_callback) {
82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
83 if (device_handle_.empty())
84 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
86 GetMediaTransferProtocolManager()->GetFileInfo(
87 device_handle_, file_id,
88 base::Bind(&MTPDeviceTaskHelper::OnGetFileInfo,
89 weak_ptr_factory_.GetWeakPtr(),
90 success_callback,
91 error_callback));
94 void MTPDeviceTaskHelper::ReadDirectory(
95 uint32 dir_id,
96 const ReadDirectorySuccessCallback& success_callback,
97 const ErrorCallback& error_callback) {
98 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
99 if (device_handle_.empty())
100 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
102 GetMediaTransferProtocolManager()->ReadDirectory(
103 device_handle_, dir_id,
104 base::Bind(&MTPDeviceTaskHelper::OnDidReadDirectory,
105 weak_ptr_factory_.GetWeakPtr(),
106 success_callback,
107 error_callback));
110 void MTPDeviceTaskHelper::WriteDataIntoSnapshotFile(
111 const SnapshotRequestInfo& request_info,
112 const base::File::Info& snapshot_file_info) {
113 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
114 if (device_handle_.empty()) {
115 return HandleDeviceError(request_info.error_callback,
116 base::File::FILE_ERROR_FAILED);
119 if (!read_file_worker_)
120 read_file_worker_.reset(new MTPReadFileWorker(device_handle_));
121 read_file_worker_->WriteDataIntoSnapshotFile(request_info,
122 snapshot_file_info);
125 void MTPDeviceTaskHelper::ReadBytes(
126 const MTPDeviceAsyncDelegate::ReadBytesRequest& request) {
127 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
128 if (device_handle_.empty()) {
129 return HandleDeviceError(request.error_callback,
130 base::File::FILE_ERROR_FAILED);
133 GetMediaTransferProtocolManager()->GetFileInfo(
134 device_handle_, request.file_id,
135 base::Bind(&MTPDeviceTaskHelper::OnGetFileInfoToReadBytes,
136 weak_ptr_factory_.GetWeakPtr(), request));
139 void MTPDeviceTaskHelper::CloseStorage() const {
140 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
141 if (device_handle_.empty())
142 return;
143 GetMediaTransferProtocolManager()->CloseStorage(device_handle_,
144 base::Bind(&DoNothing));
147 void MTPDeviceTaskHelper::OnDidOpenStorage(
148 const OpenStorageCallback& completion_callback,
149 const std::string& device_handle,
150 bool error) {
151 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
152 device_handle_ = device_handle;
153 content::BrowserThread::PostTask(content::BrowserThread::IO,
154 FROM_HERE,
155 base::Bind(completion_callback, !error));
158 void MTPDeviceTaskHelper::OnGetFileInfo(
159 const GetFileInfoSuccessCallback& success_callback,
160 const ErrorCallback& error_callback,
161 const MtpFileEntry& file_entry,
162 bool error) const {
163 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
164 if (error) {
165 return HandleDeviceError(error_callback,
166 base::File::FILE_ERROR_NOT_FOUND);
169 content::BrowserThread::PostTask(
170 content::BrowserThread::IO,
171 FROM_HERE,
172 base::Bind(success_callback, FileInfoFromMTPFileEntry(file_entry)));
175 void MTPDeviceTaskHelper::OnDidReadDirectory(
176 const ReadDirectorySuccessCallback& success_callback,
177 const ErrorCallback& error_callback,
178 const std::vector<MtpFileEntry>& file_entries,
179 bool has_more,
180 bool error) const {
181 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
182 if (error)
183 return HandleDeviceError(error_callback, base::File::FILE_ERROR_FAILED);
185 storage::AsyncFileUtil::EntryList entries;
186 base::FilePath current;
187 MTPDeviceObjectEnumerator file_enum(file_entries);
188 while (!(current = file_enum.Next()).empty()) {
189 storage::DirectoryEntry entry;
190 entry.name = storage::VirtualPath::BaseName(current).value();
191 uint32 file_id = 0;
192 bool ret = file_enum.GetEntryId(&file_id);
193 DCHECK(ret);
194 entry.name.push_back(',');
195 entry.name += base::UintToString(file_id);
196 entry.is_directory = file_enum.IsDirectory();
197 entry.size = file_enum.Size();
198 entry.last_modified_time = file_enum.LastModifiedTime();
199 entries.push_back(entry);
201 content::BrowserThread::PostTask(
202 content::BrowserThread::IO,
203 FROM_HERE,
204 base::Bind(success_callback, entries, has_more));
207 void MTPDeviceTaskHelper::OnGetFileInfoToReadBytes(
208 const MTPDeviceAsyncDelegate::ReadBytesRequest& request,
209 const MtpFileEntry& file_entry,
210 bool error) {
211 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
212 DCHECK(request.buf.get());
213 DCHECK_GE(request.buf_len, 0);
214 DCHECK_GE(request.offset, 0);
215 if (error) {
216 return HandleDeviceError(request.error_callback,
217 base::File::FILE_ERROR_FAILED);
220 base::File::Info file_info = FileInfoFromMTPFileEntry(file_entry);
221 if (file_info.is_directory) {
222 return HandleDeviceError(request.error_callback,
223 base::File::FILE_ERROR_NOT_A_FILE);
224 } else if (file_info.size < 0 || file_info.size > kuint32max ||
225 request.offset > file_info.size) {
226 return HandleDeviceError(request.error_callback,
227 base::File::FILE_ERROR_FAILED);
228 } else if (request.offset == file_info.size) {
229 content::BrowserThread::PostTask(content::BrowserThread::IO,
230 FROM_HERE,
231 base::Bind(request.success_callback,
232 file_info, 0u));
233 return;
236 uint32 bytes_to_read = std::min(
237 base::checked_cast<uint32>(request.buf_len),
238 base::saturated_cast<uint32>(file_info.size - request.offset));
240 GetMediaTransferProtocolManager()->ReadFileChunk(
241 device_handle_,
242 request.file_id,
243 base::checked_cast<uint32>(request.offset),
244 bytes_to_read,
245 base::Bind(&MTPDeviceTaskHelper::OnDidReadBytes,
246 weak_ptr_factory_.GetWeakPtr(), request, file_info));
249 void MTPDeviceTaskHelper::OnDidReadBytes(
250 const MTPDeviceAsyncDelegate::ReadBytesRequest& request,
251 const base::File::Info& file_info,
252 const std::string& data,
253 bool error) const {
254 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
255 if (error) {
256 return HandleDeviceError(request.error_callback,
257 base::File::FILE_ERROR_FAILED);
260 CHECK_LE(base::checked_cast<int>(data.length()), request.buf_len);
261 std::copy(data.begin(), data.end(), request.buf->data());
263 content::BrowserThread::PostTask(content::BrowserThread::IO,
264 FROM_HERE,
265 base::Bind(request.success_callback,
266 file_info, data.length()));
269 void MTPDeviceTaskHelper::HandleDeviceError(
270 const ErrorCallback& error_callback,
271 base::File::Error error) const {
272 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
273 content::BrowserThread::PostTask(content::BrowserThread::IO,
274 FROM_HERE,
275 base::Bind(error_callback, error));