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/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
     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,
     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 
     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 
    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 
    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 
    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*
    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*
    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*
    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 
    233 ImportedMediaGalleryRegistry::ImportedMediaGalleryRegistry() {}
    234 
    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)
    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 
    255 void ImportedMediaGalleryRegistry::RevokePicasaFileSystem() {
    256   DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
    257   DCHECK(picasa_data_provider_);
    258   picasa_data_provider_.reset();
    259 }
    260 
    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 
    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)
    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 
    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