Index: chrome/browser/media_galleries/media_file_system_registry.cc |
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc |
index 1010eb6a1694891baed271dd9b6ecef2eb6122b2..9451af8a7461295795ef8cf5e25ea31792f21a69 100644 |
--- a/chrome/browser/media_galleries/media_file_system_registry.cc |
+++ b/chrome/browser/media_galleries/media_file_system_registry.cc |
@@ -13,6 +13,7 @@ |
#include "base/prefs/pref_service.h" |
#include "base/stl_util.h" |
#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" |
#include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h" |
#include "chrome/browser/media_galleries/imported_media_gallery_registry.h" |
#include "chrome/browser/media_galleries/media_file_system_context.h" |
@@ -36,14 +37,15 @@ |
#include "extensions/browser/extension_system.h" |
#include "extensions/common/extension.h" |
#include "extensions/common/extension_set.h" |
-#include "webkit/browser/fileapi/isolated_context.h" |
+#include "webkit/browser/fileapi/external_mount_points.h" |
+#include "webkit/common/fileapi/file_system_mount_option.h" |
#include "webkit/common/fileapi/file_system_types.h" |
using content::BrowserThread; |
using content::NavigationController; |
using content::RenderProcessHost; |
using content::WebContents; |
-using fileapi::IsolatedContext; |
+using fileapi::ExternalMountPoints; |
using storage_monitor::MediaStorageUtil; |
using storage_monitor::StorageInfo; |
using storage_monitor::StorageMonitor; |
@@ -261,15 +263,19 @@ class ExtensionGalleriesHost |
// |no_references_callback| is called when the last RenderViewHost reference |
// goes away. RenderViewHost references are added through ReferenceFromRVH(). |
ExtensionGalleriesHost(MediaFileSystemContext* file_system_context, |
+ const base::FilePath& profile_path, |
+ const std::string& extension_id, |
const base::Closure& no_references_callback) |
: file_system_context_(file_system_context), |
+ profile_path_(profile_path), |
+ extension_id_(extension_id), |
no_references_callback_(no_references_callback), |
rph_refs_(base::Bind(&ExtensionGalleriesHost::CleanUp, |
base::Unretained(this))) { |
} |
// For each gallery in the list of permitted |galleries|, checks if the |
- // device is attached and if so looks up or creates a file system id and |
+ // device is attached and if so looks up or creates a file system name and |
// passes the information needed for the renderer to create those file |
// system objects to the |callback|. |
void GetMediaFileSystems(const MediaGalleryPrefIdSet& galleries, |
@@ -288,6 +294,20 @@ class ExtensionGalleriesHost |
base::Owned(device_ids), galleries, galleries_info, callback)); |
} |
+ // Checks if |gallery| is attached and if so, registers the file system and |
+ // then calls |callback| with the result. |
+ void RegisterMediaFileSystem( |
+ const MediaGalleryPrefInfo& gallery, |
+ const base::Callback<void(base::File::Error result)>& callback) { |
+ // Extract all the device ids so we can make sure they are attached. |
+ MediaStorageUtil::DeviceIdSet* device_ids = |
+ new MediaStorageUtil::DeviceIdSet; |
+ device_ids->insert(gallery.device_id); |
+ MediaStorageUtil::FilterAttachedDevices(device_ids, base::Bind( |
+ &ExtensionGalleriesHost::RegisterAttachedMediaFileSystem, this, |
+ base::Owned(device_ids), gallery, callback)); |
+ } |
+ |
// Revoke the file system for |id| if this extension has created one for |id|. |
void RevokeGalleryByPrefId(MediaGalleryPrefId id) { |
PrefIdFsInfoMap::iterator gallery = pref_id_map_.find(id); |
@@ -357,15 +377,15 @@ class ExtensionGalleriesHost |
if (!MediaStorageUtil::CanCreateFileSystem(device_id, path)) |
continue; |
- std::string fsid = |
- file_system_context_->RegisterFileSystem(device_id, path); |
- if (fsid.empty()) |
+ std::string fs_name = MediaFileSystemBackend::ConstructMountName( |
+ profile_path_, extension_id_, pref_id); |
+ if (!file_system_context_->RegisterFileSystem(device_id, fs_name, path)) |
continue; |
MediaFileSystemInfo new_entry( |
gallery_info.GetGalleryDisplayName(), |
- path, |
- fsid, |
+ file_system_context_->GetRegisteredPath(fs_name), |
+ fs_name, |
pref_id, |
GetTransientIdForRemovableDeviceId(device_id), |
StorageInfo::IsRemovableDevice(device_id), |
@@ -383,6 +403,46 @@ class ExtensionGalleriesHost |
callback.Run(result); |
} |
+ void RegisterAttachedMediaFileSystem( |
+ const MediaStorageUtil::DeviceIdSet* attached_device, |
+ const MediaGalleryPrefInfo& gallery, |
+ const base::Callback<void(base::File::Error result)>& callback) { |
+ base::File::Error result = base::File::FILE_ERROR_NOT_FOUND; |
+ |
+ // If rph_refs is empty then we're actually in the middle of shutdown, and |
+ // Filter...() lagging which can invoke this method interleaved in the |
+ // destruction callback sequence and re-populate pref_id_map_. |
+ if (!attached_device->empty() && !rph_refs_.empty()) { |
+ std::string fs_name = MediaFileSystemBackend::ConstructMountName( |
+ profile_path_, extension_id_, gallery.pref_id); |
+ base::FilePath path = gallery.AbsolutePath(); |
+ const std::string& device_id = gallery.device_id; |
+ |
+ if (ContainsKey(pref_id_map_, gallery.pref_id)) { |
+ result = base::File::FILE_OK; |
+ } else if (MediaStorageUtil::CanCreateFileSystem(device_id, path) && |
+ file_system_context_->RegisterFileSystem(device_id, fs_name, |
+ path)) { |
+ result = base::File::FILE_OK; |
+ pref_id_map_[gallery.pref_id] = MediaFileSystemInfo( |
+ gallery.GetGalleryDisplayName(), |
+ file_system_context_->GetRegisteredPath(fs_name), |
+ fs_name, |
+ gallery.pref_id, |
+ GetTransientIdForRemovableDeviceId(device_id), |
+ StorageInfo::IsRemovableDevice(device_id), |
+ StorageInfo::IsMediaDevice(device_id)); |
+ } |
+ } |
+ |
+ if (pref_id_map_.empty()) { |
+ rph_refs_.Reset(); |
+ CleanUp(); |
+ } |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(callback, result)); |
+ } |
+ |
std::string GetTransientIdForRemovableDeviceId(const std::string& device_id) { |
if (!StorageInfo::IsRemovableDevice(device_id)) |
return std::string(); |
@@ -406,6 +466,12 @@ class ExtensionGalleriesHost |
// safe to store a raw pointer. |
MediaFileSystemContext* file_system_context_; |
+ // Path for the active profile. |
+ const base::FilePath profile_path_; |
+ |
+ // Id of the extension this host belongs to. |
+ const std::string extension_id_; |
+ |
// A callback to call when the last RVH reference goes away. |
base::Closure no_references_callback_; |
@@ -440,22 +506,9 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension( |
return; |
} |
- ExtensionGalleriesHostMap::iterator extension_hosts = |
- extension_hosts_map_.find(profile); |
- if (extension_hosts->second.empty()) |
- preferences->AddGalleryChangeObserver(this); |
- |
ExtensionGalleriesHost* extension_host = |
- extension_hosts->second[extension->id()].get(); |
- if (!extension_host) { |
- extension_host = new ExtensionGalleriesHost( |
- file_system_context_.get(), |
- base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty, |
- base::Unretained(this), |
- profile, |
- extension->id())); |
- extension_hosts_map_[profile][extension->id()] = extension_host; |
- } |
+ GetExtensionGalleryHost(profile, preferences, extension->id()); |
+ |
// This must come before the GetMediaFileSystems call to make sure the |
// RVH of the context is referenced before the filesystems are retrieved. |
extension_host->ReferenceFromRVH(rvh); |
@@ -464,6 +517,40 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension( |
callback); |
} |
+void MediaFileSystemRegistry::RegisterMediaFileSystemForExtension( |
+ const content::RenderViewHost* rvh, |
+ const extensions::Extension* extension, |
+ MediaGalleryPrefId pref_id, |
+ const base::Callback<void(base::File::Error result)>& callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_NE(kInvalidMediaGalleryPrefId, pref_id); |
+ |
+ Profile* profile = |
+ Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext()); |
+ MediaGalleriesPreferences* preferences = GetPreferences(profile); |
+ MediaGalleriesPrefInfoMap::const_iterator gallery = |
+ preferences->known_galleries().find(pref_id); |
+ MediaGalleryPrefIdSet permitted_galleries = |
+ preferences->GalleriesForExtension(*extension); |
+ |
+ if (gallery == preferences->known_galleries().end() || |
+ !ContainsKey(permitted_galleries, pref_id)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(callback, base::File::FILE_ERROR_NOT_FOUND)); |
+ return; |
+ } |
+ |
+ ExtensionGalleriesHost* extension_host = |
+ GetExtensionGalleryHost(profile, preferences, extension->id()); |
+ |
+ // This must come before the GetMediaFileSystems call to make sure the |
+ // RVH of the context is referenced before the filesystems are retrieved. |
+ extension_host->ReferenceFromRVH(rvh); |
+ |
+ extension_host->RegisterMediaFileSystem(gallery->second, callback); |
+} |
+ |
MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences( |
Profile* profile) { |
// Create an empty ExtensionHostMap for this profile on first initialization. |
@@ -538,41 +625,49 @@ void MediaFileSystemRegistry::OnRemovableStorageDetached( |
class MediaFileSystemRegistry::MediaFileSystemContextImpl |
: public MediaFileSystemContext { |
public: |
- explicit MediaFileSystemContextImpl(MediaFileSystemRegistry* registry) |
- : registry_(registry) { |
- DCHECK(registry_); // Suppresses unused warning on Android. |
- } |
+ MediaFileSystemContextImpl() {} |
virtual ~MediaFileSystemContextImpl() {} |
- virtual std::string RegisterFileSystem( |
- const std::string& device_id, const base::FilePath& path) OVERRIDE { |
+ virtual bool RegisterFileSystem(const std::string& device_id, |
+ const std::string& fs_name, |
+ const base::FilePath& path) OVERRIDE { |
if (StorageInfo::IsMassStorageDevice(device_id)) { |
- return RegisterFileSystemForMassStorage(device_id, path); |
+ return RegisterFileSystemForMassStorage(device_id, fs_name, path); |
} else { |
- return RegisterFileSystemForMTPDevice(device_id, path); |
+ return RegisterFileSystemForMTPDevice(device_id, fs_name, path); |
} |
} |
- virtual void RevokeFileSystem(const std::string& fsid) OVERRIDE { |
+ virtual void RevokeFileSystem(const std::string& fs_name) OVERRIDE { |
ImportedMediaGalleryRegistry* imported_registry = |
ImportedMediaGalleryRegistry::GetInstance(); |
- if (imported_registry->RevokeImportedFilesystemOnUIThread(fsid)) |
+ if (imported_registry->RevokeImportedFilesystemOnUIThread(fs_name)) |
return; |
- IsolatedContext::GetInstance()->RevokeFileSystem(fsid); |
+ ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fs_name); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, base::Bind( |
- &MTPDeviceMapService::RevokeMTPFileSystem, |
- base::Unretained(MTPDeviceMapService::GetInstance()), |
- fsid)); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
+ &MTPDeviceMapService::RevokeMTPFileSystem, |
+ base::Unretained(MTPDeviceMapService::GetInstance()), |
+ fs_name)); |
+ } |
+ |
+ virtual base::FilePath GetRegisteredPath( |
+ const std::string& fs_name) const OVERRIDE { |
+ base::FilePath result; |
+ if (!ExternalMountPoints::GetSystemInstance()->GetRegisteredPath(fs_name, |
+ &result)) { |
+ return base::FilePath(); |
+ } |
+ return result; |
} |
private: |
// Registers and returns the file system id for the mass storage device |
// specified by |device_id| and |path|. |
- std::string RegisterFileSystemForMassStorage( |
- const std::string& device_id, const base::FilePath& path) { |
+ bool RegisterFileSystemForMassStorage(const std::string& device_id, |
+ const std::string& fs_name, |
+ const base::FilePath& path) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(StorageInfo::IsMassStorageDevice(device_id)); |
@@ -584,57 +679,52 @@ class MediaFileSystemRegistry::MediaFileSystemContextImpl |
// call tree, probably by having it figure out by device id what |
// registration is needed, or having per-device-type handlers at the |
// next higher level. |
- std::string fsid; |
+ bool result = false; |
if (StorageInfo::IsITunesDevice(device_id)) { |
- ImportedMediaGalleryRegistry* imported_registry = |
+ ImportedMediaGalleryRegistry* registry = |
ImportedMediaGalleryRegistry::GetInstance(); |
- fsid = imported_registry->RegisterITunesFilesystemOnUIThread(path); |
+ result = registry->RegisterITunesFilesystemOnUIThread(fs_name, path); |
} else if (StorageInfo::IsPicasaDevice(device_id)) { |
- ImportedMediaGalleryRegistry* imported_registry = |
+ ImportedMediaGalleryRegistry* registry = |
ImportedMediaGalleryRegistry::GetInstance(); |
- fsid = imported_registry->RegisterPicasaFilesystemOnUIThread( |
- path); |
+ result = registry->RegisterPicasaFilesystemOnUIThread(fs_name, path); |
} else if (StorageInfo::IsIPhotoDevice(device_id)) { |
- ImportedMediaGalleryRegistry* imported_registry = |
+ ImportedMediaGalleryRegistry* registry = |
ImportedMediaGalleryRegistry::GetInstance(); |
- fsid = imported_registry->RegisterIPhotoFilesystemOnUIThread( |
- path); |
+ result = registry->RegisterIPhotoFilesystemOnUIThread(fs_name, path); |
} else { |
- std::string fs_name(extension_misc::kMediaFileSystemPathPart); |
- fsid = IsolatedContext::GetInstance()->RegisterFileSystemForPath( |
- fileapi::kFileSystemTypeNativeMedia, path, &fs_name); |
+ result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( |
+ fs_name, fileapi::kFileSystemTypeNativeMedia, |
+ fileapi::FileSystemMountOption(), path); |
} |
- return fsid; |
+ return result; |
} |
- std::string RegisterFileSystemForMTPDevice( |
- const std::string& device_id, const base::FilePath& path) { |
+ bool RegisterFileSystemForMTPDevice(const std::string& device_id, |
+ const std::string fs_name, |
+ const base::FilePath& path) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!StorageInfo::IsMassStorageDevice(device_id)); |
// Sanity checks for |path|. |
CHECK(MediaStorageUtil::CanCreateFileSystem(device_id, path)); |
- std::string fs_name(extension_misc::kMediaFileSystemPathPart); |
- const std::string fsid = |
- IsolatedContext::GetInstance()->RegisterFileSystemForPath( |
- fileapi::kFileSystemTypeDeviceMedia, path, &fs_name); |
- CHECK(!fsid.empty()); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, base::Bind( |
- &MTPDeviceMapService::RegisterMTPFileSystem, |
- base::Unretained(MTPDeviceMapService::GetInstance()), |
- path.value(), fsid)); |
- return fsid; |
+ bool result = ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( |
+ fs_name, fileapi::kFileSystemTypeDeviceMedia, |
+ fileapi::FileSystemMountOption(), path); |
+ CHECK(result); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( |
+ &MTPDeviceMapService::RegisterMTPFileSystem, |
+ base::Unretained(MTPDeviceMapService::GetInstance()), |
+ path.value(), fs_name)); |
+ return result; |
} |
- MediaFileSystemRegistry* registry_; |
- |
DISALLOW_COPY_AND_ASSIGN(MediaFileSystemContextImpl); |
}; |
// Constructor in 'private' section because depends on private class definition. |
MediaFileSystemRegistry::MediaFileSystemRegistry() |
- : file_system_context_(new MediaFileSystemContextImpl(this)) { |
+ : file_system_context_(new MediaFileSystemContextImpl) { |
StorageMonitor::GetInstance()->AddObserver(this); |
} |
@@ -698,6 +788,33 @@ void MediaFileSystemRegistry::OnGalleryRemoved( |
} |
} |
+ExtensionGalleriesHost* MediaFileSystemRegistry::GetExtensionGalleryHost( |
+ Profile* profile, |
+ MediaGalleriesPreferences* preferences, |
+ const std::string& extension_id) { |
+ ExtensionGalleriesHostMap::iterator extension_hosts = |
+ extension_hosts_map_.find(profile); |
+ // GetPreferences(), which had to be called because preferences is an |
+ // argument, ensures that profile is in the map. |
+ DCHECK(extension_hosts != extension_hosts_map_.end()); |
+ if (extension_hosts->second.empty()) |
+ preferences->AddGalleryChangeObserver(this); |
+ |
+ ExtensionGalleriesHost* result = extension_hosts->second[extension_id].get(); |
+ if (!result) { |
+ result = new ExtensionGalleriesHost( |
+ file_system_context_.get(), |
+ profile->GetPath(), |
+ extension_id, |
+ base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty, |
+ base::Unretained(this), |
+ profile, |
+ extension_id)); |
+ extension_hosts_map_[profile][extension_id] = result; |
+ } |
+ return result; |
+} |
+ |
void MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty( |
Profile* profile, const std::string& extension_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |