| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "webkit/fileapi/media/device_media_async_file_util.h" | |
| 6 | |
| 7 #include "base/callback.h" | |
| 8 #include "base/file_util.h" | |
| 9 #include "base/single_thread_task_runner.h" | |
| 10 #include "webkit/fileapi/file_system_context.h" | |
| 11 #include "webkit/fileapi/file_system_operation_context.h" | |
| 12 #include "webkit/fileapi/file_system_task_runners.h" | |
| 13 #include "webkit/fileapi/file_system_url.h" | |
| 14 #include "webkit/fileapi/isolated_context.h" | |
| 15 #include "webkit/fileapi/media/filtering_file_enumerator.h" | |
| 16 #include "webkit/fileapi/media/media_file_system_mount_point_provider.h" | |
| 17 #include "webkit/fileapi/media/media_path_filter.h" | |
| 18 #include "webkit/fileapi/media/mtp_device_async_delegate.h" | |
| 19 #include "webkit/fileapi/media/mtp_device_map_service.h" | |
| 20 | |
| 21 namespace fileapi { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 const base::FilePath::CharType kDeviceMediaAsyncFileUtilTempDir[] = | |
| 26 FILE_PATH_LITERAL("DeviceMediaFileSystem"); | |
| 27 | |
| 28 // Returns true if the current thread is IO thread. | |
| 29 bool IsOnIOThread(FileSystemOperationContext* context) { | |
| 30 return context->file_system_context()->task_runners()-> | |
| 31 io_task_runner()->RunsTasksOnCurrentThread(); | |
| 32 } | |
| 33 | |
| 34 // Called on the IO thread. | |
| 35 MTPDeviceAsyncDelegate* GetMTPDeviceDelegate( | |
| 36 FileSystemOperationContext* context) { | |
| 37 DCHECK(IsOnIOThread(context)); | |
| 38 return MTPDeviceMapService::GetInstance()->GetMTPDeviceAsyncDelegate( | |
| 39 context->GetUserValue<std::string>( | |
| 40 MediaFileSystemMountPointProvider::kMTPDeviceDelegateURLKey)); | |
| 41 } | |
| 42 | |
| 43 // Called on a blocking pool thread to create a snapshot file to hold the | |
| 44 // contents of |device_file_path|. The snapshot file is created in | |
| 45 // "profile_path/kDeviceMediaAsyncFileUtilTempDir" directory. If the snapshot | |
| 46 // file is created successfully, |snapshot_file_path| will be a non-empty file | |
| 47 // path. In case of failure, the |snapshot_file_path| will be an empty file | |
| 48 // path. | |
| 49 void CreateSnapshotFileOnBlockingPool( | |
| 50 const base::FilePath& device_file_path, | |
| 51 const base::FilePath& profile_path, | |
| 52 base::FilePath* snapshot_file_path) { | |
| 53 DCHECK(snapshot_file_path); | |
| 54 base::FilePath isolated_media_file_system_dir_path = | |
| 55 profile_path.Append(kDeviceMediaAsyncFileUtilTempDir); | |
| 56 if (!file_util::CreateDirectory(isolated_media_file_system_dir_path) || | |
| 57 !file_util::CreateTemporaryFileInDir(isolated_media_file_system_dir_path, | |
| 58 snapshot_file_path)) { | |
| 59 LOG(WARNING) << "Could not create media snapshot file " | |
| 60 << isolated_media_file_system_dir_path.value(); | |
| 61 *snapshot_file_path = base::FilePath(); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 } // namespace | |
| 66 | |
| 67 DeviceMediaAsyncFileUtil::~DeviceMediaAsyncFileUtil() { | |
| 68 } | |
| 69 | |
| 70 // static | |
| 71 DeviceMediaAsyncFileUtil* DeviceMediaAsyncFileUtil::Create( | |
| 72 const base::FilePath& profile_path) { | |
| 73 DCHECK(!profile_path.empty()); | |
| 74 return new DeviceMediaAsyncFileUtil(profile_path); | |
| 75 } | |
| 76 | |
| 77 bool DeviceMediaAsyncFileUtil::CreateOrOpen( | |
| 78 FileSystemOperationContext* context, | |
| 79 const FileSystemURL& url, | |
| 80 int file_flags, | |
| 81 const CreateOrOpenCallback& callback) { | |
| 82 DCHECK(IsOnIOThread(context)); | |
| 83 NOTIMPLEMENTED(); | |
| 84 if (!callback.is_null()) { | |
| 85 base::PlatformFile invalid_file = base::kInvalidPlatformFileValue; | |
| 86 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, | |
| 87 base::PassPlatformFile(&invalid_file), | |
| 88 false); | |
| 89 } | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 bool DeviceMediaAsyncFileUtil::EnsureFileExists( | |
| 94 FileSystemOperationContext* context, | |
| 95 const FileSystemURL& url, | |
| 96 const EnsureFileExistsCallback& callback) { | |
| 97 DCHECK(IsOnIOThread(context)); | |
| 98 NOTIMPLEMENTED(); | |
| 99 if (!callback.is_null()) | |
| 100 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false); | |
| 101 return true; | |
| 102 } | |
| 103 | |
| 104 bool DeviceMediaAsyncFileUtil::CreateDirectory( | |
| 105 FileSystemOperationContext* context, | |
| 106 const FileSystemURL& url, | |
| 107 bool exclusive, | |
| 108 bool recursive, | |
| 109 const StatusCallback& callback) { | |
| 110 DCHECK(IsOnIOThread(context)); | |
| 111 NOTIMPLEMENTED(); | |
| 112 if (!callback.is_null()) | |
| 113 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 114 return true; | |
| 115 } | |
| 116 | |
| 117 bool DeviceMediaAsyncFileUtil::GetFileInfo( | |
| 118 FileSystemOperationContext* context, | |
| 119 const FileSystemURL& url, | |
| 120 const GetFileInfoCallback& callback) { | |
| 121 DCHECK(IsOnIOThread(context)); | |
| 122 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context); | |
| 123 if (!delegate) { | |
| 124 OnGetFileInfoError(callback, url.path(), | |
| 125 base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 126 return true; | |
| 127 } | |
| 128 delegate->GetFileInfo( | |
| 129 url.path(), | |
| 130 base::Bind(&DeviceMediaAsyncFileUtil::OnDidGetFileInfo, | |
| 131 weak_ptr_factory_.GetWeakPtr(), | |
| 132 callback, | |
| 133 url.path()), | |
| 134 base::Bind(&DeviceMediaAsyncFileUtil::OnGetFileInfoError, | |
| 135 weak_ptr_factory_.GetWeakPtr(), | |
| 136 callback, | |
| 137 url.path())); | |
| 138 return true; | |
| 139 } | |
| 140 | |
| 141 bool DeviceMediaAsyncFileUtil::ReadDirectory( | |
| 142 FileSystemOperationContext* context, | |
| 143 const FileSystemURL& url, | |
| 144 const ReadDirectoryCallback& callback) { | |
| 145 DCHECK(IsOnIOThread(context)); | |
| 146 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context); | |
| 147 if (!delegate) { | |
| 148 OnReadDirectoryError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 149 return true; | |
| 150 } | |
| 151 delegate->ReadDirectory( | |
| 152 url.path(), | |
| 153 base::Bind(&DeviceMediaAsyncFileUtil::OnDidReadDirectory, | |
| 154 weak_ptr_factory_.GetWeakPtr(), | |
| 155 callback), | |
| 156 base::Bind(&DeviceMediaAsyncFileUtil::OnReadDirectoryError, | |
| 157 weak_ptr_factory_.GetWeakPtr(), | |
| 158 callback)); | |
| 159 return true; | |
| 160 } | |
| 161 | |
| 162 bool DeviceMediaAsyncFileUtil::Touch( | |
| 163 FileSystemOperationContext* context, | |
| 164 const FileSystemURL& url, | |
| 165 const base::Time& last_access_time, | |
| 166 const base::Time& last_modified_time, | |
| 167 const StatusCallback& callback) { | |
| 168 DCHECK(IsOnIOThread(context)); | |
| 169 NOTIMPLEMENTED(); | |
| 170 if (!callback.is_null()) | |
| 171 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 bool DeviceMediaAsyncFileUtil::Truncate( | |
| 176 FileSystemOperationContext* context, | |
| 177 const FileSystemURL& url, | |
| 178 int64 length, | |
| 179 const StatusCallback& callback) { | |
| 180 DCHECK(IsOnIOThread(context)); | |
| 181 NOTIMPLEMENTED(); | |
| 182 if (!callback.is_null()) | |
| 183 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 184 return true; | |
| 185 } | |
| 186 | |
| 187 bool DeviceMediaAsyncFileUtil::CopyFileLocal( | |
| 188 FileSystemOperationContext* context, | |
| 189 const FileSystemURL& src_url, | |
| 190 const FileSystemURL& dest_url, | |
| 191 const StatusCallback& callback) { | |
| 192 DCHECK(IsOnIOThread(context)); | |
| 193 NOTIMPLEMENTED(); | |
| 194 if (!callback.is_null()) | |
| 195 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 196 return true; | |
| 197 } | |
| 198 | |
| 199 bool DeviceMediaAsyncFileUtil::MoveFileLocal( | |
| 200 FileSystemOperationContext* context, | |
| 201 const FileSystemURL& src_url, | |
| 202 const FileSystemURL& dest_url, | |
| 203 const StatusCallback& callback) { | |
| 204 DCHECK(IsOnIOThread(context)); | |
| 205 NOTIMPLEMENTED(); | |
| 206 if (!callback.is_null()) | |
| 207 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 208 return true; | |
| 209 } | |
| 210 | |
| 211 bool DeviceMediaAsyncFileUtil::CopyInForeignFile( | |
| 212 FileSystemOperationContext* context, | |
| 213 const base::FilePath& src_file_path, | |
| 214 const FileSystemURL& dest_url, | |
| 215 const StatusCallback& callback) { | |
| 216 DCHECK(IsOnIOThread(context)); | |
| 217 NOTIMPLEMENTED(); | |
| 218 if (!callback.is_null()) | |
| 219 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 220 return true; | |
| 221 } | |
| 222 | |
| 223 bool DeviceMediaAsyncFileUtil::DeleteFile( | |
| 224 FileSystemOperationContext* context, | |
| 225 const FileSystemURL& url, | |
| 226 const StatusCallback& callback) { | |
| 227 DCHECK(IsOnIOThread(context)); | |
| 228 NOTIMPLEMENTED(); | |
| 229 if (!callback.is_null()) | |
| 230 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 231 return true; | |
| 232 } | |
| 233 | |
| 234 bool DeviceMediaAsyncFileUtil::DeleteDirectory( | |
| 235 FileSystemOperationContext* context, | |
| 236 const FileSystemURL& url, | |
| 237 const StatusCallback& callback) { | |
| 238 DCHECK(IsOnIOThread(context)); | |
| 239 NOTIMPLEMENTED(); | |
| 240 if (!callback.is_null()) | |
| 241 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 bool DeviceMediaAsyncFileUtil::CreateSnapshotFile( | |
| 246 FileSystemOperationContext* context, | |
| 247 const FileSystemURL& url, | |
| 248 const CreateSnapshotFileCallback& callback) { | |
| 249 DCHECK(IsOnIOThread(context)); | |
| 250 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context); | |
| 251 if (!delegate) { | |
| 252 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 253 return true; | |
| 254 } | |
| 255 base::FilePath* snapshot_file_path = new base::FilePath; | |
| 256 return context->task_runner()->PostTaskAndReply( | |
| 257 FROM_HERE, | |
| 258 base::Bind(&CreateSnapshotFileOnBlockingPool, | |
| 259 url.path(), | |
| 260 profile_path_, | |
| 261 base::Unretained(snapshot_file_path)), | |
| 262 base::Bind(&DeviceMediaAsyncFileUtil::OnSnapshotFileCreatedRunTask, | |
| 263 weak_ptr_factory_.GetWeakPtr(), | |
| 264 context, | |
| 265 callback, | |
| 266 url.path(), | |
| 267 base::Owned(snapshot_file_path))); | |
| 268 } | |
| 269 | |
| 270 DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil( | |
| 271 const base::FilePath& profile_path) | |
| 272 : profile_path_(profile_path), | |
| 273 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
| 274 } | |
| 275 | |
| 276 void DeviceMediaAsyncFileUtil::OnDidGetFileInfo( | |
| 277 const AsyncFileUtil::GetFileInfoCallback& callback, | |
| 278 const base::FilePath& platform_path, | |
| 279 const base::PlatformFileInfo& file_info) { | |
| 280 if (!callback.is_null()) | |
| 281 callback.Run(base::PLATFORM_FILE_OK, file_info, platform_path); | |
| 282 } | |
| 283 | |
| 284 void DeviceMediaAsyncFileUtil::OnGetFileInfoError( | |
| 285 const AsyncFileUtil::GetFileInfoCallback& callback, | |
| 286 const base::FilePath& platform_path, | |
| 287 base::PlatformFileError error) { | |
| 288 if (!callback.is_null()) | |
| 289 callback.Run(error, base::PlatformFileInfo(), platform_path); | |
| 290 } | |
| 291 | |
| 292 void DeviceMediaAsyncFileUtil::OnDidReadDirectory( | |
| 293 const AsyncFileUtil::ReadDirectoryCallback& callback, | |
| 294 const AsyncFileUtil::EntryList& file_list, | |
| 295 bool has_more) { | |
| 296 if (!callback.is_null()) | |
| 297 callback.Run(base::PLATFORM_FILE_OK, file_list, has_more); | |
| 298 } | |
| 299 | |
| 300 void DeviceMediaAsyncFileUtil::OnReadDirectoryError( | |
| 301 const AsyncFileUtil::ReadDirectoryCallback& callback, | |
| 302 base::PlatformFileError error) { | |
| 303 if (!callback.is_null()) | |
| 304 callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/); | |
| 305 } | |
| 306 | |
| 307 void DeviceMediaAsyncFileUtil::OnDidCreateSnapshotFile( | |
| 308 const AsyncFileUtil::CreateSnapshotFileCallback& callback, | |
| 309 const base::PlatformFileInfo& file_info, | |
| 310 const base::FilePath& platform_path) { | |
| 311 if (!callback.is_null()) | |
| 312 callback.Run(base::PLATFORM_FILE_OK, file_info, platform_path, | |
| 313 kSnapshotFileTemporary); | |
| 314 } | |
| 315 | |
| 316 void DeviceMediaAsyncFileUtil::OnCreateSnapshotFileError( | |
| 317 const AsyncFileUtil::CreateSnapshotFileCallback& callback, | |
| 318 base::PlatformFileError error) { | |
| 319 if (!callback.is_null()) | |
| 320 callback.Run(error, base::PlatformFileInfo(), base::FilePath(), | |
| 321 kSnapshotFileTemporary); | |
| 322 } | |
| 323 | |
| 324 void DeviceMediaAsyncFileUtil::OnSnapshotFileCreatedRunTask( | |
| 325 FileSystemOperationContext* context, | |
| 326 const AsyncFileUtil::CreateSnapshotFileCallback& callback, | |
| 327 const base::FilePath& device_file_path, | |
| 328 base::FilePath* snapshot_file_path) { | |
| 329 DCHECK(IsOnIOThread(context)); | |
| 330 if (!snapshot_file_path || snapshot_file_path->empty()) { | |
| 331 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_FAILED); | |
| 332 return; | |
| 333 } | |
| 334 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context); | |
| 335 if (!delegate) { | |
| 336 OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND); | |
| 337 return; | |
| 338 } | |
| 339 delegate->CreateSnapshotFile( | |
| 340 device_file_path, | |
| 341 *snapshot_file_path, | |
| 342 base::Bind(&DeviceMediaAsyncFileUtil::OnDidCreateSnapshotFile, | |
| 343 weak_ptr_factory_.GetWeakPtr(), | |
| 344 callback), | |
| 345 base::Bind(&DeviceMediaAsyncFileUtil::OnCreateSnapshotFileError, | |
| 346 weak_ptr_factory_.GetWeakPtr(), | |
| 347 callback)); | |
| 348 } | |
| 349 | |
| 350 } // namespace fileapi | |
| OLD | NEW |