Home | History | Annotate | Download | only in media_galleries
      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/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 "webkit/browser/fileapi/external_mount_points.h"
     17 #include "webkit/common/fileapi/file_system_mount_option.h"
     18 
     19 using base::Bind;
     20 using fileapi::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
     30 ImportedMediaGalleryRegistry* ImportedMediaGalleryRegistry::GetInstance() {
     31   return g_imported_media_gallery_registry.Pointer();
     32 }
     33 
     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 
     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, fileapi::kFileSystemTypePicasa, fileapi::FileSystemMountOption(),
     59       root.AppendASCII("picasa"));
     60   if (!result)
     61     return result;
     62 
     63   picasa_fs_names_.insert(fs_name);
     64 
     65   if (picasa_fs_names_.size() == 1) {
     66     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
     67         FROM_HERE,
     68         Bind(&ImportedMediaGalleryRegistry::RegisterPicasaFileSystem,
     69              base::Unretained(this), database_path));
     70 #ifndef NDEBUG
     71     picasa_database_path_ = database_path;
     72   } else {
     73     DCHECK_EQ(picasa_database_path_.value(), database_path.value());
     74 #endif
     75   }
     76 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
     77 
     78   return result;
     79 }
     80 
     81 bool ImportedMediaGalleryRegistry::RegisterITunesFilesystemOnUIThread(
     82     const std::string& fs_name, const base::FilePath& library_xml_path) {
     83   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     84   DCHECK(!library_xml_path.empty());
     85 
     86   bool result = false;
     87 
     88 #if defined(OS_WIN) || defined(OS_MACOSX)
     89   base::FilePath root = ImportedRoot();
     90   if (root.empty())
     91     return false;
     92   result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
     93       fs_name, fileapi::kFileSystemTypeItunes, fileapi::FileSystemMountOption(),
     94       root.AppendASCII("itunes"));
     95   if (!result)
     96     return result;
     97 
     98   itunes_fs_names_.insert(fs_name);
     99 
    100   if (itunes_fs_names_.size() == 1) {
    101     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
    102         FROM_HERE,
    103         Bind(&ImportedMediaGalleryRegistry::RegisterITunesFileSystem,
    104              base::Unretained(this), library_xml_path));
    105 #ifndef NDEBUG
    106     itunes_xml_library_path_ = library_xml_path;
    107   } else {
    108     DCHECK_EQ(itunes_xml_library_path_.value(), library_xml_path.value());
    109 #endif
    110   }
    111 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    112 
    113   return result;
    114 }
    115 
    116 bool ImportedMediaGalleryRegistry::RegisterIPhotoFilesystemOnUIThread(
    117     const std::string& fs_name, const base::FilePath& library_xml_path) {
    118   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    119   DCHECK(!library_xml_path.empty());
    120 
    121   bool result = false;
    122 
    123   // TODO(gbillock): Investigate how to refactor this to reduce duplicated
    124   // code.
    125 #if defined(OS_MACOSX)
    126   base::FilePath root = ImportedRoot();
    127   if (root.empty())
    128     return false;
    129   result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
    130       fs_name, fileapi::kFileSystemTypeIphoto, fileapi::FileSystemMountOption(),
    131       root.AppendASCII("iphoto"));
    132   if (!result)
    133     return result;
    134 
    135   iphoto_fs_names_.insert(fs_name);
    136 
    137   if (iphoto_fs_names_.size() == 1) {
    138     MediaFileSystemBackend::MediaTaskRunner()->PostTask(
    139         FROM_HERE,
    140         Bind(&ImportedMediaGalleryRegistry::RegisterIPhotoFileSystem,
    141              base::Unretained(this), library_xml_path));
    142 #ifndef NDEBUG
    143     iphoto_xml_library_path_ = library_xml_path;
    144   } else {
    145     DCHECK_EQ(iphoto_xml_library_path_.value(), library_xml_path.value());
    146 #endif
    147   }
    148 #endif  // defined(OS_MACOSX)
    149 
    150   return result;
    151 }
    152 
    153 bool ImportedMediaGalleryRegistry::RevokeImportedFilesystemOnUIThread(
    154     const std::string& fs_name) {
    155   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    156 
    157 #if defined(OS_WIN) || defined(OS_MACOSX)
    158   if (picasa_fs_names_.erase(fs_name)) {
    159     if (picasa_fs_names_.empty()) {
    160       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
    161           FROM_HERE,
    162           Bind(&ImportedMediaGalleryRegistry::RevokePicasaFileSystem,
    163                base::Unretained(this)));
    164     }
    165     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
    166   }
    167 
    168   if (itunes_fs_names_.erase(fs_name)) {
    169     if (itunes_fs_names_.empty()) {
    170       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
    171           FROM_HERE,
    172           Bind(&ImportedMediaGalleryRegistry::RevokeITunesFileSystem,
    173                base::Unretained(this)));
    174     }
    175     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
    176   }
    177 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    178 
    179 #if defined(OS_MACOSX)
    180   if (iphoto_fs_names_.erase(fs_name)) {
    181     if (iphoto_fs_names_.empty()) {
    182       MediaFileSystemBackend::MediaTaskRunner()->PostTask(
    183           FROM_HERE,
    184           Bind(&ImportedMediaGalleryRegistry::RevokeIPhotoFileSystem,
    185                base::Unretained(this)));
    186     }
    187     return ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name);
    188   }
    189 #endif  // defined(OS_MACOSX)
    190 
    191   return false;
    192 }
    193 
    194 base::FilePath ImportedMediaGalleryRegistry::ImportedRoot() {
    195   DCHECK(!imported_root_.empty());
    196   return imported_root_;
    197 }
    198 
    199 #if defined(OS_WIN) || defined(OS_MACOSX)
    200 // static
    201 picasa::PicasaDataProvider*
    202 ImportedMediaGalleryRegistry::PicasaDataProvider() {
    203   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    204   DCHECK(GetInstance()->picasa_data_provider_);
    205   return GetInstance()->picasa_data_provider_.get();
    206 }
    207 
    208 // static
    209 itunes::ITunesDataProvider*
    210 ImportedMediaGalleryRegistry::ITunesDataProvider() {
    211   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    212   DCHECK(GetInstance()->itunes_data_provider_);
    213   return GetInstance()->itunes_data_provider_.get();
    214 }
    215 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    216 
    217 #if defined(OS_MACOSX)
    218 // static
    219 iphoto::IPhotoDataProvider*
    220 ImportedMediaGalleryRegistry::IPhotoDataProvider() {
    221   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    222   DCHECK(GetInstance()->iphoto_data_provider_);
    223   return GetInstance()->iphoto_data_provider_.get();
    224 }
    225 #endif  // defined(OS_MACOSX)
    226 
    227 ImportedMediaGalleryRegistry::ImportedMediaGalleryRegistry() {}
    228 
    229 ImportedMediaGalleryRegistry::~ImportedMediaGalleryRegistry() {
    230   if (!imported_root_.empty())
    231     base::DeleteFile(imported_root_, false);
    232 #if defined(OS_WIN) || defined(OS_MACOSX)
    233   DCHECK_EQ(0U, picasa_fs_names_.size());
    234   DCHECK_EQ(0U, itunes_fs_names_.size());
    235 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    236 #if defined(OS_MACOSX)
    237   DCHECK_EQ(0U, iphoto_fs_names_.size());
    238 #endif  // defined(OS_MACOSX)
    239 }
    240 
    241 #if defined(OS_WIN) || defined(OS_MACOSX)
    242 void ImportedMediaGalleryRegistry::RegisterPicasaFileSystem(
    243     const base::FilePath& database_path) {
    244   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    245   DCHECK(!picasa_data_provider_);
    246   picasa_data_provider_.reset(new picasa::PicasaDataProvider(database_path));
    247 }
    248 
    249 void ImportedMediaGalleryRegistry::RevokePicasaFileSystem() {
    250   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    251   DCHECK(picasa_data_provider_);
    252   picasa_data_provider_.reset();
    253 }
    254 
    255 void ImportedMediaGalleryRegistry::RegisterITunesFileSystem(
    256     const base::FilePath& xml_library_path) {
    257   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    258   DCHECK(!itunes_data_provider_);
    259   itunes_data_provider_.reset(new itunes::ITunesDataProvider(xml_library_path));
    260 }
    261 
    262 void ImportedMediaGalleryRegistry::RevokeITunesFileSystem() {
    263   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    264   DCHECK(itunes_data_provider_);
    265   itunes_data_provider_.reset();
    266 }
    267 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
    268 
    269 #if defined(OS_MACOSX)
    270 void ImportedMediaGalleryRegistry::RegisterIPhotoFileSystem(
    271     const base::FilePath& xml_library_path) {
    272   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    273   DCHECK(!iphoto_data_provider_);
    274   iphoto_data_provider_.reset(new iphoto::IPhotoDataProvider(xml_library_path));
    275 }
    276 
    277 void ImportedMediaGalleryRegistry::RevokeIPhotoFileSystem() {
    278   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    279   DCHECK(iphoto_data_provider_);
    280   iphoto_data_provider_.reset();
    281 }
    282 #endif  // defined(OS_MACOSX)
    283