media_file_system_backend.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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 "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
6
7#include <string>
8
9#include "base/bind.h"
10#include "base/files/file_path.h"
11#include "base/logging.h"
12#include "base/message_loop/message_loop_proxy.h"
13#include "base/platform_file.h"
14#include "base/sequenced_task_runner.h"
15#include "base/threading/sequenced_worker_pool.h"
16#include "chrome/browser/media_galleries/fileapi/device_media_async_file_util.h"
17#include "chrome/browser/media_galleries/fileapi/media_file_validator_factory.h"
18#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
19#include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
20#include "content/public/browser/browser_thread.h"
21#include "webkit/browser/blob/file_stream_reader.h"
22#include "webkit/browser/fileapi/copy_or_move_file_validator.h"
23#include "webkit/browser/fileapi/file_stream_writer.h"
24#include "webkit/browser/fileapi/file_system_context.h"
25#include "webkit/browser/fileapi/file_system_operation.h"
26#include "webkit/browser/fileapi/file_system_operation_context.h"
27#include "webkit/browser/fileapi/isolated_context.h"
28#include "webkit/browser/fileapi/native_file_util.h"
29#include "webkit/common/fileapi/file_system_types.h"
30#include "webkit/common/fileapi/file_system_util.h"
31
32#if defined(OS_WIN) || defined(OS_MACOSX)
33#include "chrome/browser/media_galleries/fileapi/itunes_file_util.h"
34#include "chrome/browser/media_galleries/fileapi/picasa_file_util.h"
35#endif  // defined(OS_WIN) || defined(OS_MACOSX)
36
37#if defined(OS_MACOSX)
38#include "chrome/browser/media_galleries/fileapi/iphoto_file_util.h"
39#endif  // defined(OS_MACOSX)
40
41using fileapi::FileSystemContext;
42using fileapi::FileSystemURL;
43
44const char MediaFileSystemBackend::kMediaTaskRunnerName[] =
45    "media-task-runner";
46
47MediaFileSystemBackend::MediaFileSystemBackend(
48    const base::FilePath& profile_path,
49    base::SequencedTaskRunner* media_task_runner)
50    : profile_path_(profile_path),
51      media_task_runner_(media_task_runner),
52      media_path_filter_(new MediaPathFilter),
53      media_copy_or_move_file_validator_factory_(new MediaFileValidatorFactory),
54      native_media_file_util_(
55          new NativeMediaFileUtil(media_path_filter_.get())),
56      device_media_async_file_util_(
57          DeviceMediaAsyncFileUtil::Create(profile_path_))
58#if defined(OS_WIN) || defined(OS_MACOSX)
59      ,
60      picasa_file_util_(new picasa::PicasaFileUtil(media_path_filter_.get())),
61      itunes_file_util_(new itunes::ITunesFileUtil(media_path_filter_.get()))
62#endif  // defined(OS_WIN) || defined(OS_MACOSX)
63#if defined(OS_MACOSX)
64      ,
65      iphoto_file_util_(new iphoto::IPhotoFileUtil(media_path_filter_.get()))
66#endif  // defined(OS_MACOSX)
67{
68}
69
70MediaFileSystemBackend::~MediaFileSystemBackend() {
71}
72
73// static
74bool MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread() {
75  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
76  base::SequencedWorkerPool::SequenceToken media_sequence_token =
77      pool->GetNamedSequenceToken(kMediaTaskRunnerName);
78  return pool->IsRunningSequenceOnCurrentThread(media_sequence_token);
79}
80
81// static
82scoped_refptr<base::SequencedTaskRunner>
83MediaFileSystemBackend::MediaTaskRunner() {
84  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
85  base::SequencedWorkerPool::SequenceToken media_sequence_token =
86      pool->GetNamedSequenceToken(kMediaTaskRunnerName);
87  return pool->GetSequencedTaskRunner(media_sequence_token);
88}
89
90bool MediaFileSystemBackend::CanHandleType(
91    fileapi::FileSystemType type) const {
92  switch (type) {
93    case fileapi::kFileSystemTypeNativeMedia:
94    case fileapi::kFileSystemTypeDeviceMedia:
95#if defined(OS_WIN) || defined(OS_MACOSX)
96    case fileapi::kFileSystemTypePicasa:
97    case fileapi::kFileSystemTypeItunes:
98#endif  // defined(OS_WIN) || defined(OS_MACOSX)
99#if defined(OS_MACOSX)
100    case fileapi::kFileSystemTypeIphoto:
101#endif  // defined(OS_MACOSX)
102      return true;
103    default:
104      return false;
105  }
106}
107
108void MediaFileSystemBackend::Initialize(fileapi::FileSystemContext* context) {
109}
110
111void MediaFileSystemBackend::OpenFileSystem(
112    const GURL& origin_url,
113    fileapi::FileSystemType type,
114    fileapi::OpenFileSystemMode mode,
115    const OpenFileSystemCallback& callback) {
116  // We never allow opening a new isolated FileSystem via usual OpenFileSystem.
117  base::MessageLoopProxy::current()->PostTask(
118      FROM_HERE,
119      base::Bind(callback,
120                 GetFileSystemRootURI(origin_url, type),
121                 GetFileSystemName(origin_url, type),
122                 base::PLATFORM_FILE_ERROR_SECURITY));
123}
124
125fileapi::AsyncFileUtil* MediaFileSystemBackend::GetAsyncFileUtil(
126    fileapi::FileSystemType type) {
127  switch (type) {
128    case fileapi::kFileSystemTypeNativeMedia:
129      return native_media_file_util_.get();
130    case fileapi::kFileSystemTypeDeviceMedia:
131      return device_media_async_file_util_.get();
132#if defined(OS_WIN) || defined(OS_MACOSX)
133    case fileapi::kFileSystemTypeItunes:
134      return itunes_file_util_.get();
135    case fileapi::kFileSystemTypePicasa:
136      return picasa_file_util_.get();
137#endif  // defined(OS_WIN) || defined(OS_MACOSX)
138#if defined(OS_MACOSX)
139    case fileapi::kFileSystemTypeIphoto:
140      return iphoto_file_util_.get();
141#endif  // defined(OS_MACOSX)
142    default:
143      NOTREACHED();
144  }
145  return NULL;
146}
147
148fileapi::CopyOrMoveFileValidatorFactory*
149MediaFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
150    fileapi::FileSystemType type, base::PlatformFileError* error_code) {
151  DCHECK(error_code);
152  *error_code = base::PLATFORM_FILE_OK;
153  switch (type) {
154    case fileapi::kFileSystemTypeNativeMedia:
155    case fileapi::kFileSystemTypeDeviceMedia:
156    case fileapi::kFileSystemTypeIphoto:
157    case fileapi::kFileSystemTypeItunes:
158      if (!media_copy_or_move_file_validator_factory_) {
159        *error_code = base::PLATFORM_FILE_ERROR_SECURITY;
160        return NULL;
161      }
162      return media_copy_or_move_file_validator_factory_.get();
163    default:
164      NOTREACHED();
165  }
166  return NULL;
167}
168
169fileapi::FileSystemOperation*
170MediaFileSystemBackend::CreateFileSystemOperation(
171    const FileSystemURL& url,
172    FileSystemContext* context,
173    base::PlatformFileError* error_code) const {
174  scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
175      new fileapi::FileSystemOperationContext(
176          context, media_task_runner_.get()));
177  return fileapi::FileSystemOperation::Create(
178      url, context, operation_context.Pass());
179}
180
181scoped_ptr<webkit_blob::FileStreamReader>
182MediaFileSystemBackend::CreateFileStreamReader(
183    const FileSystemURL& url,
184    int64 offset,
185    const base::Time& expected_modification_time,
186    FileSystemContext* context) const {
187  return scoped_ptr<webkit_blob::FileStreamReader>(
188      webkit_blob::FileStreamReader::CreateForLocalFile(
189          context->default_file_task_runner(),
190          url.path(), offset, expected_modification_time));
191}
192
193scoped_ptr<fileapi::FileStreamWriter>
194MediaFileSystemBackend::CreateFileStreamWriter(
195    const FileSystemURL& url,
196    int64 offset,
197    FileSystemContext* context) const {
198  return scoped_ptr<fileapi::FileStreamWriter>(
199      fileapi::FileStreamWriter::CreateForLocalFile(
200          context->default_file_task_runner(),
201          url.path(), offset));
202}
203
204fileapi::FileSystemQuotaUtil*
205MediaFileSystemBackend::GetQuotaUtil() {
206  // No quota support.
207  return NULL;
208}
209