media_file_system_backend.cc revision bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3
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/local_file_stream_reader.h"
22#include "webkit/browser/fileapi/async_file_util_adapter.h"
23#include "webkit/browser/fileapi/copy_or_move_file_validator.h"
24#include "webkit/browser/fileapi/file_system_context.h"
25#include "webkit/browser/fileapi/file_system_file_stream_reader.h"
26#include "webkit/browser/fileapi/file_system_operation_context.h"
27#include "webkit/browser/fileapi/file_system_task_runners.h"
28#include "webkit/browser/fileapi/isolated_context.h"
29#include "webkit/browser/fileapi/isolated_file_util.h"
30#include "webkit/browser/fileapi/local_file_stream_writer.h"
31#include "webkit/browser/fileapi/local_file_system_operation.h"
32#include "webkit/browser/fileapi/native_file_util.h"
33#include "webkit/common/fileapi/file_system_types.h"
34#include "webkit/common/fileapi/file_system_util.h"
35
36#if defined(OS_WIN) || defined(OS_MACOSX)
37#include "chrome/browser/media_galleries/fileapi/itunes_file_util.h"
38#include "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h"
39#endif  // defined(OS_WIN) || defined(OS_MACOSX)
40
41using fileapi::FileSystemContext;
42using fileapi::FileSystemURL;
43
44namespace chrome {
45
46const char MediaFileSystemBackend::kMediaTaskRunnerName[] =
47    "media-task-runner";
48const char MediaFileSystemBackend::kMediaPathFilterKey[] =
49    "MediaPathFilterKey";
50const char MediaFileSystemBackend::kMTPDeviceDelegateURLKey[] =
51    "MTPDeviceDelegateKey";
52
53MediaFileSystemBackend::MediaFileSystemBackend(
54    const base::FilePath& profile_path,
55    base::SequencedTaskRunner* media_task_runner)
56    : profile_path_(profile_path),
57      media_task_runner_(media_task_runner),
58      media_path_filter_(new MediaPathFilter),
59      media_copy_or_move_file_validator_factory_(new MediaFileValidatorFactory),
60      native_media_file_util_(new NativeMediaFileUtil()),
61      device_media_async_file_util_(
62          DeviceMediaAsyncFileUtil::Create(profile_path_))
63#if defined(OS_WIN) || defined(OS_MACOSX)
64      ,
65      picasa_file_util_(new picasa::PicasaFileUtil()),
66      itunes_file_util_(new itunes::ItunesFileUtil())
67#endif  // defined(OS_WIN) || defined(OS_MACOSX)
68{
69}
70
71MediaFileSystemBackend::~MediaFileSystemBackend() {
72}
73
74// static
75bool MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread() {
76  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
77  base::SequencedWorkerPool::SequenceToken media_sequence_token =
78      pool->GetNamedSequenceToken(kMediaTaskRunnerName);
79  return pool->IsRunningSequenceOnCurrentThread(media_sequence_token);
80}
81
82// static
83scoped_refptr<base::SequencedTaskRunner>
84MediaFileSystemBackend::MediaTaskRunner() {
85  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
86  base::SequencedWorkerPool::SequenceToken media_sequence_token =
87      pool->GetNamedSequenceToken(kMediaTaskRunnerName);
88  return pool->GetSequencedTaskRunner(media_sequence_token);
89}
90
91bool MediaFileSystemBackend::CanHandleType(
92    fileapi::FileSystemType type) const {
93  switch (type) {
94    case fileapi::kFileSystemTypeNativeMedia:
95    case fileapi::kFileSystemTypeDeviceMedia:
96#if defined(OS_WIN) || defined(OS_MACOSX)
97    case fileapi::kFileSystemTypePicasa:
98    case fileapi::kFileSystemTypeItunes:
99#endif  // defined(OS_WIN) || defined(OS_MACOSX)
100      return true;
101    default:
102      return false;
103  }
104}
105
106void MediaFileSystemBackend::Initialize(fileapi::FileSystemContext* context) {
107}
108
109void MediaFileSystemBackend::OpenFileSystem(
110    const GURL& origin_url,
111    fileapi::FileSystemType type,
112    fileapi::OpenFileSystemMode mode,
113    const OpenFileSystemCallback& callback) {
114  // We never allow opening a new isolated FileSystem via usual OpenFileSystem.
115  base::MessageLoopProxy::current()->PostTask(
116      FROM_HERE,
117      base::Bind(callback,
118                 GetFileSystemRootURI(origin_url, type),
119                 GetFileSystemName(origin_url, type),
120                 base::PLATFORM_FILE_ERROR_SECURITY));
121}
122
123fileapi::FileSystemFileUtil* MediaFileSystemBackend::GetFileUtil(
124    fileapi::FileSystemType type) {
125  NOTREACHED();
126  return NULL;
127}
128
129fileapi::AsyncFileUtil* MediaFileSystemBackend::GetAsyncFileUtil(
130    fileapi::FileSystemType type) {
131  switch (type) {
132    case fileapi::kFileSystemTypeNativeMedia:
133      return native_media_file_util_.get();
134    case fileapi::kFileSystemTypeDeviceMedia:
135      return device_media_async_file_util_.get();
136#if defined(OS_WIN) || defined(OS_MACOSX)
137    case fileapi::kFileSystemTypeItunes:
138      return itunes_file_util_.get();
139    case fileapi::kFileSystemTypePicasa:
140      return picasa_file_util_.get();
141#endif  // defined(OS_WIN) || 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::kFileSystemTypeItunes:
157      if (!media_copy_or_move_file_validator_factory_) {
158        *error_code = base::PLATFORM_FILE_ERROR_SECURITY;
159        return NULL;
160      }
161      return media_copy_or_move_file_validator_factory_.get();
162    default:
163      NOTREACHED();
164  }
165  return NULL;
166}
167
168fileapi::FileSystemOperation*
169MediaFileSystemBackend::CreateFileSystemOperation(
170    const FileSystemURL& url,
171    FileSystemContext* context,
172    base::PlatformFileError* error_code) const {
173  scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
174      new fileapi::FileSystemOperationContext(
175          context, media_task_runner_.get()));
176
177  operation_context->SetUserValue(kMediaPathFilterKey,
178                                  media_path_filter_.get());
179  if (url.type() == fileapi::kFileSystemTypeDeviceMedia) {
180    operation_context->SetUserValue(kMTPDeviceDelegateURLKey,
181                                    url.filesystem_id());
182  }
183
184  return new fileapi::LocalFileSystemOperation(url, context,
185                                               operation_context.Pass());
186}
187
188scoped_ptr<webkit_blob::FileStreamReader>
189MediaFileSystemBackend::CreateFileStreamReader(
190    const FileSystemURL& url,
191    int64 offset,
192    const base::Time& expected_modification_time,
193    FileSystemContext* context) const {
194  return scoped_ptr<webkit_blob::FileStreamReader>(
195      new webkit_blob::LocalFileStreamReader(
196          context->task_runners()->file_task_runner(),
197          url.path(), offset, expected_modification_time));
198}
199
200scoped_ptr<fileapi::FileStreamWriter>
201MediaFileSystemBackend::CreateFileStreamWriter(
202    const FileSystemURL& url,
203    int64 offset,
204    FileSystemContext* context) const {
205  return scoped_ptr<fileapi::FileStreamWriter>(
206      new fileapi::LocalFileStreamWriter(
207          context->task_runners()->file_task_runner(),
208          url.path(), offset));
209}
210
211fileapi::FileSystemQuotaUtil*
212MediaFileSystemBackend::GetQuotaUtil() {
213  // No quota support.
214  return NULL;
215}
216
217}  // namespace chrome
218