• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
6 
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/logging.h"
10 #include "chrome/browser/media_galleries/fileapi/iphoto_data_provider.h"
11 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
12 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
13 #include "chrome/browser/media_galleries/fileapi/picasa_data_provider.h"
14 #include "chrome/common/extensions/extension_constants.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "storage/browser/fileapi/external_mount_points.h"
17 #include "storage/common/fileapi/file_system_mount_option.h"
18 
19 using base::Bind;
20 using storage::ExternalMountPoints;
21 
22 namespace {
23 
24 static base::LazyInstance<ImportedMediaGalleryRegistry>::Leaky
25 g_imported_media_gallery_registry = LAZY_INSTANCE_INITIALIZER;
26 
27 }  // namespace
28 
29 // static
GetInstance()30 ImportedMediaGalleryRegistry* ImportedMediaGalleryRegistry::GetInstance() {
31   return g_imported_media_gallery_registry.Pointer();
32 }
33 
Initialize()34 void ImportedMediaGalleryRegistry::Initialize() {
35   base::ThreadRestrictions::AssertIOAllowed();
36   if (imported_root_.empty()) {
37     if (!base::CreateTemporaryFile(&imported_root_))
38       imported_root_ = base::FilePath();
39     // TODO(vandebo) Setting the permissions of |imported_root_| in CPSP to
40     // zero would be an extra step to ensure permissions are correctly
41     // enforced.
42   }
43 }
44 
RegisterPicasaFilesystemOnUIThread(const std::string & fs_name,const base::FilePath & database_path)45 bool ImportedMediaGalleryRegistry::RegisterPicasaFilesystemOnUIThread(
46     const std::string& fs_name, const base::FilePath& database_path) {
47   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
48   DCHECK(!fs_name.empty());
49   DCHECK(!database_path.empty());
50 
51   bool result = false;
52 
53 #if defined(OS_WIN) || defined(OS_MACOSX)
54   base::FilePath root = ImportedRoot();
55   if (root.empty())
56     return false;
57   result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
58       fs_name,
59       storage::kFileSystemTypePicasa,
60       storage::FileSystemMountOption(),
61       root.AppendASCII("picasa"));
62   if (!result)
63     return result;
64 
65   picasa_fs_names_.insert(fs_name);
66 
67   if (picasa_fs_names_.size() == 1) {
68     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
69         FROM_HERE,
70         Bind(&ImportedMediaGalleryRegistry::RegisterPicasaFileSystem,
71              base::Unretained(this), database_path));
72 #ifndef NDEBUG
73     picasa_database_path_ = database_path;
74   } else {
75     DCHECK_EQ(picasa_database_path_.value(), database_path.value());
76 #endif
77   }
78 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
79 
80   return result;
81 }
82 
RegisterITunesFilesystemOnUIThread(const std::string & fs_name,const base::FilePath & library_xml_path)83 bool ImportedMediaGalleryRegistry::RegisterITunesFilesystemOnUIThread(
84     const std::string& fs_name, const base::FilePath& library_xml_path) {
85   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
86   DCHECK(!library_xml_path.empty());
87 
88   bool result = false;
89 
90 #if defined(OS_WIN) || defined(OS_MACOSX)
91   base::FilePath root = ImportedRoot();
92   if (root.empty())
93     return false;
94   result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
95       fs_name,
96       storage::kFileSystemTypeItunes,
97       storage::FileSystemMountOption(),
98       root.AppendASCII("itunes"));
99   if (!result)
100     return result;
101 
102   itunes_fs_names_.insert(fs_name);
103 
104   if (itunes_fs_names_.size() == 1) {
105     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
106         FROM_HERE,
107         Bind(&ImportedMediaGalleryRegistry::RegisterITunesFileSystem,
108              base::Unretained(this), library_xml_path));
109 #ifndef NDEBUG
110     itunes_xml_library_path_ = library_xml_path;
111   } else {
112     DCHECK_EQ(itunes_xml_library_path_.value(), library_xml_path.value());
113 #endif
114   }
115 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
116 
117   return result;
118 }
119 
RegisterIPhotoFilesystemOnUIThread(const std::string & fs_name,const base::FilePath & library_xml_path)120 bool ImportedMediaGalleryRegistry::RegisterIPhotoFilesystemOnUIThread(
121     const std::string& fs_name, const base::FilePath& library_xml_path) {
122   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
123   DCHECK(!library_xml_path.empty());
124 
125   bool result = false;
126 
127   // TODO(gbillock): Investigate how to refactor this to reduce duplicated
128   // code.
129 #if defined(OS_MACOSX)
130   base::FilePath root = ImportedRoot();
131   if (root.empty())
132     return false;
133   result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
134       fs_name,
135       storage::kFileSystemTypeIphoto,
136       storage::FileSystemMountOption(),
137       root.AppendASCII("iphoto"));
138   if (!result)
139     return result;
140 
141   iphoto_fs_names_.insert(fs_name);
142 
143   if (iphoto_fs_names_.size() == 1) {
144     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
145         FROM_HERE,
146         Bind(&ImportedMediaGalleryRegistry::RegisterIPhotoFileSystem,
147              base::Unretained(this), library_xml_path));
148 #ifndef NDEBUG
149     iphoto_xml_library_path_ = library_xml_path;
150   } else {
151     DCHECK_EQ(iphoto_xml_library_path_.value(), library_xml_path.value());
152 #endif
153   }
154 #endif  // defined(OS_MACOSX)
155 
156   return result;
157 }
158 
RevokeImportedFilesystemOnUIThread(const std::string & fs_name)159 bool ImportedMediaGalleryRegistry::RevokeImportedFilesystemOnUIThread(
160     const std::string& fs_name) {
161   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
162 
163 #if defined(OS_WIN) || defined(OS_MACOSX)
164   if (picasa_fs_names_.erase(fs_name)) {
165     if (picasa_fs_names_.empty()) {
166       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
167           FROM_HERE,
168           Bind(&ImportedMediaGalleryRegistry::RevokePicasaFileSystem,
169                base::Unretained(this)));
170     }
171     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
172   }
173 
174   if (itunes_fs_names_.erase(fs_name)) {
175     if (itunes_fs_names_.empty()) {
176       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
177           FROM_HERE,
178           Bind(&ImportedMediaGalleryRegistry::RevokeITunesFileSystem,
179                base::Unretained(this)));
180     }
181     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
182   }
183 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
184 
185 #if defined(OS_MACOSX)
186   if (iphoto_fs_names_.erase(fs_name)) {
187     if (iphoto_fs_names_.empty()) {
188       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
189           FROM_HERE,
190           Bind(&ImportedMediaGalleryRegistry::RevokeIPhotoFileSystem,
191                base::Unretained(this)));
192     }
193     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
194   }
195 #endif  // defined(OS_MACOSX)
196 
197   return false;
198 }
199 
ImportedRoot()200 base::FilePath ImportedMediaGalleryRegistry::ImportedRoot() {
201   DCHECK(!imported_root_.empty());
202   return imported_root_;
203 }
204 
205 #if defined(OS_WIN) || defined(OS_MACOSX)
206 // static
207 picasa::PicasaDataProvider*
PicasaDataProvider()208 ImportedMediaGalleryRegistry::PicasaDataProvider() {
209   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
210   DCHECK(GetInstance()->picasa_data_provider_);
211   return GetInstance()->picasa_data_provider_.get();
212 }
213 
214 // static
215 itunes::ITunesDataProvider*
ITunesDataProvider()216 ImportedMediaGalleryRegistry::ITunesDataProvider() {
217   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
218   DCHECK(GetInstance()->itunes_data_provider_);
219   return GetInstance()->itunes_data_provider_.get();
220 }
221 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
222 
223 #if defined(OS_MACOSX)
224 // static
225 iphoto::IPhotoDataProvider*
IPhotoDataProvider()226 ImportedMediaGalleryRegistry::IPhotoDataProvider() {
227   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
228   DCHECK(GetInstance()->iphoto_data_provider_);
229   return GetInstance()->iphoto_data_provider_.get();
230 }
231 #endif  // defined(OS_MACOSX)
232 
ImportedMediaGalleryRegistry()233 ImportedMediaGalleryRegistry::ImportedMediaGalleryRegistry() {}
234 
~ImportedMediaGalleryRegistry()235 ImportedMediaGalleryRegistry::~ImportedMediaGalleryRegistry() {
236   if (!imported_root_.empty())
237     base::DeleteFile(imported_root_, false);
238 #if defined(OS_WIN) || defined(OS_MACOSX)
239   DCHECK_EQ(0U, picasa_fs_names_.size());
240   DCHECK_EQ(0U, itunes_fs_names_.size());
241 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
242 #if defined(OS_MACOSX)
243   DCHECK_EQ(0U, iphoto_fs_names_.size());
244 #endif  // defined(OS_MACOSX)
245 }
246 
247 #if defined(OS_WIN) || defined(OS_MACOSX)
RegisterPicasaFileSystem(const base::FilePath & database_path)248 void ImportedMediaGalleryRegistry::RegisterPicasaFileSystem(
249     const base::FilePath& database_path) {
250   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
251   DCHECK(!picasa_data_provider_);
252   picasa_data_provider_.reset(new picasa::PicasaDataProvider(database_path));
253 }
254 
RevokePicasaFileSystem()255 void ImportedMediaGalleryRegistry::RevokePicasaFileSystem() {
256   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
257   DCHECK(picasa_data_provider_);
258   picasa_data_provider_.reset();
259 }
260 
RegisterITunesFileSystem(const base::FilePath & xml_library_path)261 void ImportedMediaGalleryRegistry::RegisterITunesFileSystem(
262     const base::FilePath& xml_library_path) {
263   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
264   DCHECK(!itunes_data_provider_);
265   itunes_data_provider_.reset(new itunes::ITunesDataProvider(xml_library_path));
266 }
267 
RevokeITunesFileSystem()268 void ImportedMediaGalleryRegistry::RevokeITunesFileSystem() {
269   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
270   DCHECK(itunes_data_provider_);
271   itunes_data_provider_.reset();
272 }
273 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
274 
275 #if defined(OS_MACOSX)
RegisterIPhotoFileSystem(const base::FilePath & xml_library_path)276 void ImportedMediaGalleryRegistry::RegisterIPhotoFileSystem(
277     const base::FilePath& xml_library_path) {
278   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
279   DCHECK(!iphoto_data_provider_);
280   iphoto_data_provider_.reset(new iphoto::IPhotoDataProvider(xml_library_path));
281 }
282 
RevokeIPhotoFileSystem()283 void ImportedMediaGalleryRegistry::RevokeIPhotoFileSystem() {
284   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
285   DCHECK(iphoto_data_provider_);
286   iphoto_data_provider_.reset();
287 }
288 #endif  // defined(OS_MACOSX)
289