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