Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / device_media_async_file_util.cc
blob41b516bb6aeebb737660fac8aa840e650b3fd09d
1 // Copyright (c) 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/fileapi/device_media_async_file_util.h"
7 #include "base/callback.h"
8 #include "base/file_util.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/task_runner_util.h"
11 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
12 #include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h"
13 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
14 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "webkit/browser/fileapi/file_system_operation_context.h"
17 #include "webkit/browser/fileapi/file_system_url.h"
18 #include "webkit/common/blob/shareable_file_reference.h"
20 using fileapi::FileSystemOperationContext;
21 using fileapi::FileSystemURL;
22 using webkit_blob::ShareableFileReference;
24 namespace {
26 const char kDeviceMediaAsyncFileUtilTempDir[] = "DeviceMediaFileSystem";
28 // Called on the IO thread.
29 MTPDeviceAsyncDelegate* GetMTPDeviceDelegate(const FileSystemURL& url) {
30 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
31 return MTPDeviceMapService::GetInstance()->GetMTPDeviceAsyncDelegate(
32 url.filesystem_id());
35 // Called on a blocking pool thread to create a snapshot file to hold the
36 // contents of |device_file_path|. The snapshot file is created in
37 // "profile_path/kDeviceMediaAsyncFileUtilTempDir" directory. If the snapshot
38 // file is created successfully, |snapshot_file_path| will be a non-empty file
39 // path. In case of failure, the |snapshot_file_path| will be an empty file
40 // path.
41 void CreateSnapshotFileOnBlockingPool(
42 const base::FilePath& device_file_path,
43 const base::FilePath& profile_path,
44 base::FilePath* snapshot_file_path) {
45 DCHECK(snapshot_file_path);
46 base::FilePath isolated_media_file_system_dir_path =
47 profile_path.AppendASCII(kDeviceMediaAsyncFileUtilTempDir);
48 if (!base::CreateDirectory(isolated_media_file_system_dir_path) ||
49 !base::CreateTemporaryFileInDir(isolated_media_file_system_dir_path,
50 snapshot_file_path)) {
51 LOG(WARNING) << "Could not create media snapshot file "
52 << isolated_media_file_system_dir_path.value();
53 *snapshot_file_path = base::FilePath();
57 } // namespace
59 DeviceMediaAsyncFileUtil::~DeviceMediaAsyncFileUtil() {
62 // static
63 DeviceMediaAsyncFileUtil* DeviceMediaAsyncFileUtil::Create(
64 const base::FilePath& profile_path) {
65 DCHECK(!profile_path.empty());
66 return new DeviceMediaAsyncFileUtil(profile_path);
69 void DeviceMediaAsyncFileUtil::CreateOrOpen(
70 scoped_ptr<FileSystemOperationContext> context,
71 const FileSystemURL& url,
72 int file_flags,
73 const CreateOrOpenCallback& callback) {
74 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
75 NOTIMPLEMENTED();
76 base::PlatformFile invalid_file = base::kInvalidPlatformFileValue;
77 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY,
78 base::PassPlatformFile(&invalid_file),
79 base::Closure());
82 void DeviceMediaAsyncFileUtil::EnsureFileExists(
83 scoped_ptr<FileSystemOperationContext> context,
84 const FileSystemURL& url,
85 const EnsureFileExistsCallback& callback) {
86 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
87 NOTIMPLEMENTED();
88 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false);
91 void DeviceMediaAsyncFileUtil::CreateDirectory(
92 scoped_ptr<FileSystemOperationContext> context,
93 const FileSystemURL& url,
94 bool exclusive,
95 bool recursive,
96 const StatusCallback& callback) {
97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
98 NOTIMPLEMENTED();
99 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
102 void DeviceMediaAsyncFileUtil::GetFileInfo(
103 scoped_ptr<FileSystemOperationContext> context,
104 const FileSystemURL& url,
105 const GetFileInfoCallback& callback) {
106 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
107 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url);
108 if (!delegate) {
109 OnGetFileInfoError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
110 return;
112 delegate->GetFileInfo(
113 url.path(),
114 base::Bind(&DeviceMediaAsyncFileUtil::OnDidGetFileInfo,
115 weak_ptr_factory_.GetWeakPtr(),
116 callback),
117 base::Bind(&DeviceMediaAsyncFileUtil::OnGetFileInfoError,
118 weak_ptr_factory_.GetWeakPtr(),
119 callback));
122 void DeviceMediaAsyncFileUtil::ReadDirectory(
123 scoped_ptr<FileSystemOperationContext> context,
124 const FileSystemURL& url,
125 const ReadDirectoryCallback& callback) {
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
127 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url);
128 if (!delegate) {
129 OnReadDirectoryError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
130 return;
132 delegate->ReadDirectory(
133 url.path(),
134 base::Bind(&DeviceMediaAsyncFileUtil::OnDidReadDirectory,
135 weak_ptr_factory_.GetWeakPtr(),
136 callback),
137 base::Bind(&DeviceMediaAsyncFileUtil::OnReadDirectoryError,
138 weak_ptr_factory_.GetWeakPtr(),
139 callback));
142 void DeviceMediaAsyncFileUtil::Touch(
143 scoped_ptr<FileSystemOperationContext> context,
144 const FileSystemURL& url,
145 const base::Time& last_access_time,
146 const base::Time& last_modified_time,
147 const StatusCallback& callback) {
148 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
149 NOTIMPLEMENTED();
150 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
153 void DeviceMediaAsyncFileUtil::Truncate(
154 scoped_ptr<FileSystemOperationContext> context,
155 const FileSystemURL& url,
156 int64 length,
157 const StatusCallback& callback) {
158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
159 NOTIMPLEMENTED();
160 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
163 void DeviceMediaAsyncFileUtil::CopyFileLocal(
164 scoped_ptr<FileSystemOperationContext> context,
165 const FileSystemURL& src_url,
166 const FileSystemURL& dest_url,
167 CopyOrMoveOption option,
168 const CopyFileProgressCallback& progress_callback,
169 const StatusCallback& callback) {
170 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
171 NOTIMPLEMENTED();
172 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
175 void DeviceMediaAsyncFileUtil::MoveFileLocal(
176 scoped_ptr<FileSystemOperationContext> context,
177 const FileSystemURL& src_url,
178 const FileSystemURL& dest_url,
179 CopyOrMoveOption option,
180 const StatusCallback& callback) {
181 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
182 NOTIMPLEMENTED();
183 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
186 void DeviceMediaAsyncFileUtil::CopyInForeignFile(
187 scoped_ptr<FileSystemOperationContext> context,
188 const base::FilePath& src_file_path,
189 const FileSystemURL& dest_url,
190 const StatusCallback& callback) {
191 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
192 NOTIMPLEMENTED();
193 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
196 void DeviceMediaAsyncFileUtil::DeleteFile(
197 scoped_ptr<FileSystemOperationContext> context,
198 const FileSystemURL& url,
199 const StatusCallback& callback) {
200 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
201 NOTIMPLEMENTED();
202 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
205 void DeviceMediaAsyncFileUtil::DeleteDirectory(
206 scoped_ptr<FileSystemOperationContext> context,
207 const FileSystemURL& url,
208 const StatusCallback& callback) {
209 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
210 NOTIMPLEMENTED();
211 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
214 void DeviceMediaAsyncFileUtil::DeleteRecursively(
215 scoped_ptr<FileSystemOperationContext> context,
216 const FileSystemURL& url,
217 const StatusCallback& callback) {
218 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
219 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
222 void DeviceMediaAsyncFileUtil::CreateSnapshotFile(
223 scoped_ptr<FileSystemOperationContext> context,
224 const FileSystemURL& url,
225 const CreateSnapshotFileCallback& callback) {
226 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
227 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url);
228 if (!delegate) {
229 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
230 return;
232 base::FilePath* snapshot_file_path = new base::FilePath;
233 base::SequencedTaskRunner* task_runner = context->task_runner();
234 const bool success = task_runner->PostTaskAndReply(
235 FROM_HERE,
236 base::Bind(&CreateSnapshotFileOnBlockingPool,
237 url.path(),
238 profile_path_,
239 base::Unretained(snapshot_file_path)),
240 base::Bind(&DeviceMediaAsyncFileUtil::OnSnapshotFileCreatedRunTask,
241 weak_ptr_factory_.GetWeakPtr(),
242 base::Passed(&context),
243 callback,
244 url,
245 base::Owned(snapshot_file_path)));
246 DCHECK(success);
249 DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil(
250 const base::FilePath& profile_path)
251 : profile_path_(profile_path),
252 weak_ptr_factory_(this) {
255 void DeviceMediaAsyncFileUtil::OnDidGetFileInfo(
256 const AsyncFileUtil::GetFileInfoCallback& callback,
257 const base::PlatformFileInfo& file_info) {
258 callback.Run(base::PLATFORM_FILE_OK, file_info);
261 void DeviceMediaAsyncFileUtil::OnGetFileInfoError(
262 const AsyncFileUtil::GetFileInfoCallback& callback,
263 base::PlatformFileError error) {
264 callback.Run(error, base::PlatformFileInfo());
267 void DeviceMediaAsyncFileUtil::OnDidReadDirectory(
268 const AsyncFileUtil::ReadDirectoryCallback& callback,
269 const AsyncFileUtil::EntryList& file_list,
270 bool has_more) {
271 callback.Run(base::PLATFORM_FILE_OK, file_list, has_more);
274 void DeviceMediaAsyncFileUtil::OnReadDirectoryError(
275 const AsyncFileUtil::ReadDirectoryCallback& callback,
276 base::PlatformFileError error) {
277 callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/);
280 void DeviceMediaAsyncFileUtil::OnDidCreateSnapshotFile(
281 const AsyncFileUtil::CreateSnapshotFileCallback& callback,
282 base::SequencedTaskRunner* media_task_runner,
283 const base::PlatformFileInfo& file_info,
284 const base::FilePath& platform_path) {
285 base::PostTaskAndReplyWithResult(
286 media_task_runner,
287 FROM_HERE,
288 base::Bind(&NativeMediaFileUtil::IsMediaFile, platform_path),
289 base::Bind(&DeviceMediaAsyncFileUtil::OnDidCheckMedia,
290 weak_ptr_factory_.GetWeakPtr(),
291 callback,
292 file_info,
293 ShareableFileReference::GetOrCreate(
294 platform_path,
295 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
296 media_task_runner)));
299 void DeviceMediaAsyncFileUtil::OnDidCheckMedia(
300 const AsyncFileUtil::CreateSnapshotFileCallback& callback,
301 const base::PlatformFileInfo& file_info,
302 scoped_refptr<webkit_blob::ShareableFileReference> platform_file,
303 base::PlatformFileError error) {
304 base::FilePath platform_path(platform_file.get()->path());
305 if (error != base::PLATFORM_FILE_OK)
306 platform_file = NULL;
307 callback.Run(error, file_info, platform_path, platform_file);
310 void DeviceMediaAsyncFileUtil::OnCreateSnapshotFileError(
311 const AsyncFileUtil::CreateSnapshotFileCallback& callback,
312 base::PlatformFileError error) {
313 callback.Run(error, base::PlatformFileInfo(), base::FilePath(),
314 scoped_refptr<ShareableFileReference>());
317 void DeviceMediaAsyncFileUtil::OnSnapshotFileCreatedRunTask(
318 scoped_ptr<FileSystemOperationContext> context,
319 const AsyncFileUtil::CreateSnapshotFileCallback& callback,
320 const FileSystemURL& url,
321 base::FilePath* snapshot_file_path) {
322 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
323 if (!snapshot_file_path || snapshot_file_path->empty()) {
324 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_FAILED);
325 return;
327 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url);
328 if (!delegate) {
329 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
330 return;
332 delegate->CreateSnapshotFile(
333 url.path(), // device file path
334 *snapshot_file_path,
335 base::Bind(&DeviceMediaAsyncFileUtil::OnDidCreateSnapshotFile,
336 weak_ptr_factory_.GetWeakPtr(),
337 callback,
338 make_scoped_refptr(context->task_runner())),
339 base::Bind(&DeviceMediaAsyncFileUtil::OnCreateSnapshotFileError,
340 weak_ptr_factory_.GetWeakPtr(),
341 callback));