Chromium Code Reviews| Index: chrome/browser/media_gallery/media_file_system_registry.cc |
| diff --git a/chrome/browser/media_gallery/media_file_system_registry.cc b/chrome/browser/media_gallery/media_file_system_registry.cc |
| index 2522d806bb38cd9e25ca8354f03d2d24db45eb14..cf1b047d3572358b938365b176077a6e92a7b8d7 100644 |
| --- a/chrome/browser/media_gallery/media_file_system_registry.cc |
| +++ b/chrome/browser/media_gallery/media_file_system_registry.cc |
| @@ -6,28 +6,36 @@ |
| #include "chrome/browser/media_gallery/media_file_system_registry.h" |
| +#include <list> |
| #include <set> |
| +#include "base/callback.h" |
| #include "base/file_path.h" |
| #include "base/path_service.h" |
| +#include "base/stl_util.h" |
| #include "base/system_monitor/system_monitor.h" |
| #include "base/utf_string_conversions.h" |
| +#include "chrome/browser/media_gallery/media_galleries_preferences.h" |
| +#include "chrome/browser/media_gallery/media_galleries_preferences_factory.h" |
| #include "chrome/browser/media_gallery/media_storage_util.h" |
| +#include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/notification_observer.h" |
| +#include "content/public/browser/notification_registrar.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/render_process_host.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/web_contents.h" |
| #include "webkit/fileapi/file_system_types.h" |
| #include "webkit/fileapi/isolated_context.h" |
| #include "webkit/fileapi/media/media_file_system_config.h" |
| #if defined(SUPPORT_MEDIA_FILESYSTEM) |
| #include "webkit/fileapi/media/media_device_map_service.h" |
| - |
| -using fileapi::MediaDeviceMapService; |
| #endif |
| namespace chrome { |
| @@ -37,23 +45,249 @@ static base::LazyInstance<MediaFileSystemRegistry>::Leaky |
| using base::SystemMonitor; |
| using content::BrowserThread; |
| +using content::NavigationController; |
| using content::RenderProcessHost; |
| +using content::WebContents; |
| using fileapi::IsolatedContext; |
| namespace { |
| -bool IsGalleryPermittedForExtension(const extensions::Extension& extension, |
| - const FilePath::StringType& location) { |
| - if (extension.HasAPIPermission( |
| - extensions::APIPermission::kMediaGalleriesAllGalleries)) { |
| - return true; |
| +struct InvalidatedGalleriesInfo { |
| + std::set<ExtensionGalleriesHost*> extension_hosts; |
| + std::set<MediaGalleryPrefId> pref_ids; |
| +}; |
| + |
| +//typedef std::list<InvalidatedGalleryInfo> InvalidatedGalleriesInfo; |
|
Lei Zhang
2012/09/05 06:29:22
Remove debug code?
vandebo (ex-Chrome)
2012/09/05 18:25:48
Done.
|
| + |
| +std::string RegisterFileSystem(std::string device_id, const FilePath& path) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + IsolatedContext* isolated_context = IsolatedContext::GetInstance(); |
| + if (MediaStorageUtil::IsMassStorageDevice(device_id)) { |
| + // Sanity checks for |path|. |
| + CHECK(path.IsAbsolute()); |
| + CHECK(!path.ReferencesParent()); |
| + std::string fs_name(extension_misc::kMediaFileSystemPathPart); |
| + const std::string fsid = isolated_context->RegisterFileSystemForPath( |
| + fileapi::kFileSystemTypeNativeMedia, path, &fs_name); |
| + CHECK(!fsid.empty()); |
| + return fsid; |
| } |
| - // TODO(vandebo) Check with prefs for permission to this gallery. |
| - return false; |
| + |
| + // TODO(kmadhusu) handle MTP devices. |
| + NOTREACHED(); |
| + return std::string(); |
| } |
| } // namespace |
| +// Refcounted only so it can easily be put in map. All instances are owned |
| +// by |MediaFileSystemRegistry::extension_hosts_map_|. |
| +class ExtensionGalleriesHost |
| + : public base::RefCounted<ExtensionGalleriesHost>, |
| + public content::NotificationObserver { |
| + public: |
| + // |no_references_callback| is called when the last RenderViewHost reference |
| + // goes away. RenderViewHost references are added through ReferenceFromRVH(). |
| + explicit ExtensionGalleriesHost(const base::Closure& no_references_callback) |
| + : no_references_callback_(no_references_callback) { |
| + } |
| + |
| + // For each gallery in the list of permitted |galleries|, looks up or creates |
| + // a file system id and returns the information needed for the renderer to |
| + // create those file system objects. |
| + std::vector<MediaFileSystemRegistry::MediaFSInfo> GetMediaFileSystems( |
| + const MediaGalleryPrefIdSet& galleries, |
| + const MediaGalleriesPrefInfoMap& galleries_info) { |
| + std::vector<MediaFileSystemRegistry::MediaFSInfo> result; |
| + for (std::set<MediaGalleryPrefId>::const_iterator id = galleries.begin(); |
| + id != galleries.end(); |
| + ++id) { |
| + // TODO(vandebo) we also need to check that these galleries are attached. |
| + PrefIdFsInfoMap::const_iterator existing_info = pref_id_map_.find(*id); |
| + if (existing_info != pref_id_map_.end()) { |
| + result.push_back(existing_info->second); |
| + continue; |
| + } |
| + const MediaGalleryPrefInfo& gallery_info = |
| + galleries_info.find(*id)->second; |
| + const std::string& device_id = gallery_info.device_id; |
| + // TODO(kmadhusu) handle MTP devices. |
| + DCHECK(MediaStorageUtil::IsMassStorageDevice(device_id)); |
| + FilePath path = MediaStorageUtil::FindDevicePathById(device_id); |
| + CHECK(!path.empty()); |
| + path = path.Append(gallery_info.path); |
| + |
| + MediaFileSystemRegistry::MediaFSInfo new_entry; |
| + new_entry.name = gallery_info.display_name; |
| + new_entry.path = path; |
| + new_entry.fsid = RegisterFileSystem(device_id, path); |
| + result.push_back(new_entry); |
| + pref_id_map_[*id] = new_entry; |
|
Lei Zhang
2012/09/05 06:29:22
You can safely insert() here since we know there's
vandebo (ex-Chrome)
2012/09/05 18:25:48
You'd like me to use insert() here? The syntax is
Lei Zhang
2012/09/05 18:31:01
Meh, ok. I don't know what the STL designers were
|
| + } |
| + |
| + // TODO(vandebo) We need a way of getting notification when permission for |
| + // galleries are revoked (http://crbug.com/145855). For now, invalidate |
| + // any fsid we have that we didn't get this time around. |
| + if (galleries.size() != pref_id_map_.size()) { |
|
Lei Zhang
2012/09/05 06:29:22
The size of |galleries| is never greater than |pre
vandebo (ex-Chrome)
2012/09/05 18:25:48
I think that's true, but this shortcut only works
|
| + MediaGalleryPrefIdSet old_galleries; |
| + for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin(); |
| + it != pref_id_map_.end(); |
| + ++it) { |
| + old_galleries.insert(it->first); |
| + } |
| + MediaGalleryPrefIdSet invalid_galleries; |
| + std::set_difference(old_galleries.begin(), old_galleries.end(), |
| + galleries.begin(), galleries.end(), |
| + std::inserter(invalid_galleries, |
| + invalid_galleries.begin())); |
| + for (MediaGalleryPrefIdSet::const_iterator it = invalid_galleries.begin(); |
| + it != invalid_galleries.end(); |
| + ++it) { |
| + RevokeGalleryByPrefId(*it); |
| + } |
| + } |
| + |
| + return result; |
| + } |
| + |
| + // 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); |
| + if (gallery == pref_id_map_.end()) |
| + return; |
| + |
| + IsolatedContext* isolated_context = IsolatedContext::GetInstance(); |
| + isolated_context->RevokeFileSystem(gallery->second.fsid); |
| + |
| + pref_id_map_.erase(gallery); |
| + } |
| + |
| + // Indicate that the passed |rvh| will reference the file system ids created |
| + // by this class. It is safe to call this multiple times with the same RVH. |
| + void ReferenceFromRVH(const content::RenderViewHost* rvh) { |
| + WebContents* contents = WebContents::FromRenderViewHost(rvh); |
| + if (registrar_.IsRegistered(this, |
| + content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::Source<WebContents>(contents))) { |
| + return; |
| + } |
| + registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::Source<WebContents>(contents)); |
| + registrar_.Add( |
| + this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| + content::Source<NavigationController>(&contents->GetController())); |
| + |
| + RenderProcessHost* rph = contents->GetRenderProcessHost(); |
| + rph_refs_[rph].insert(contents); |
| + if (rph_refs_[rph].size() == 1) { |
| + registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| + content::Source<RenderProcessHost>(rph)); |
| + } |
| + } |
| + |
| + // NotificationObserver implementation. |
| + virtual void Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) OVERRIDE { |
| + switch (type) { |
| + case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
| + OnRendererProcessClosed( |
| + content::Source<RenderProcessHost>(source).ptr()); |
| + break; |
| + } |
| + case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
| + OnWebContentsDestroyedOrNavigated( |
| + content::Source<WebContents>(source).ptr()); |
| + break; |
| + } |
| + case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { |
| + NavigationController* controller = |
| + content::Source<NavigationController>(source).ptr(); |
| + WebContents* contents = controller->GetWebContents(); |
| + OnWebContentsDestroyedOrNavigated(contents); |
| + break; |
| + } |
| + default: { |
| + NOTREACHED(); |
| + break; |
| + } |
| + } |
| + } |
| + |
| + private: |
| + typedef std::map<MediaGalleryPrefId, MediaFileSystemRegistry::MediaFSInfo> |
| + PrefIdFsInfoMap; |
| + typedef std::map<const RenderProcessHost*, std::set<const WebContents*> > |
| + RenderProcessHostRefCount; |
| + |
| + // Private destructor and friend declaration for ref counted implementation. |
| + friend class base::RefCounted<ExtensionGalleriesHost>; |
| + |
| + virtual ~ExtensionGalleriesHost() { |
| + DCHECK(rph_refs_.empty()); |
| + DCHECK(pref_id_map_.empty()); |
| + } |
| + |
| + void OnRendererProcessClosed(const RenderProcessHost* rph) { |
| + RenderProcessHostRefCount::const_iterator rph_info = rph_refs_.find(rph); |
| + DCHECK(rph_info != rph_refs_.end()); |
| + // We're going to remove everything from the set, so we make a copy |
| + // before operating on it. |
| + std::set<const WebContents*> closed_web_contents = rph_info->second; |
| + DCHECK(!closed_web_contents.empty()); |
| + |
| + for (std::set<const WebContents*>::const_iterator it = |
| + closed_web_contents.begin(); |
| + it != closed_web_contents.end(); |
| + ++it) { |
| + OnWebContentsDestroyedOrNavigated(*it); |
| + } |
| + DCHECK(!ContainsKey(rph_refs_, rph)); |
| + } |
| + |
| + void OnWebContentsDestroyedOrNavigated(const WebContents* contents) { |
| + registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::Source<WebContents>(contents)); |
| + registrar_.Remove( |
| + this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| + content::Source<NavigationController>(&contents->GetController())); |
| + |
| + RenderProcessHost* rph = contents->GetRenderProcessHost(); |
| + rph_refs_[rph].erase(contents); |
|
Lei Zhang
2012/09/05 06:29:22
If you just get the iterator once, you can use it
vandebo (ex-Chrome)
2012/09/05 18:25:48
Done.
|
| + if (rph_refs_[rph].empty()) { |
| + registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| + content::Source<RenderProcessHost>(rph)); |
| + rph_refs_.erase(rph); |
| + } |
| + |
| + if (rph_refs_.empty()) { |
| + IsolatedContext* isolated_context = IsolatedContext::GetInstance(); |
| + for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin(); |
| + it != pref_id_map_.end(); |
| + ++it) { |
| + isolated_context->RevokeFileSystem(it->second.fsid); |
| + } |
| + pref_id_map_.clear(); |
| + no_references_callback_.Run(); |
| + } |
| + } |
| + |
| + // A callback to call when the last RVH reference goes away. |
| + base::Closure no_references_callback_; |
| + |
| + // A map from the gallery preferences id to the file system information. |
| + PrefIdFsInfoMap pref_id_map_; |
| + |
| + // The set of render processes and web contents that may have references to |
| + // the file system ids this instance manages. |
| + RenderProcessHostRefCount rph_refs_; |
| + |
| + // A registrar for listening notifications. |
| + content::NotificationRegistrar registrar_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ExtensionGalleriesHost); |
| +}; |
| /****************** |
| * Public methods |
| @@ -64,88 +298,93 @@ MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { |
| return g_media_file_system_registry.Pointer(); |
| } |
| +// TODO(vandebo) We need to make this async so that we check that the |
| +// galleries are attached (requires the file thread). |
| std::vector<MediaFileSystemRegistry::MediaFSInfo> |
| MediaFileSystemRegistry::GetMediaFileSystemsForExtension( |
| - const content::RenderProcessHost* rph, |
| - const extensions::Extension& extension) { |
| + const content::RenderViewHost* rvh, |
| + const extensions::Extension* extension) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - std::vector<MediaFSInfo> results; |
| - std::pair<ChildIdToMediaFSMap::iterator, bool> ret = |
| - media_fs_map_.insert(std::make_pair(rph, MediaPathToFSIDMap())); |
| - ChildIdToMediaFSMap::iterator& child_it = ret.first; |
| - if (ret.second) { |
| - // Never seen a GetMediaFileSystems call from this RPH. Initialize its |
| - // file system mappings. |
| - RegisterForRPHGoneNotifications(rph); |
| - FilePath pictures_path; |
| - // TODO(vandebo) file system galleries need a unique id as well. |
| - if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path) && |
| - IsGalleryPermittedForExtension(extension, pictures_path.value())) { |
| - std::string fsid = RegisterPathAsFileSystem(pictures_path); |
| - child_it->second.insert(std::make_pair(pictures_path, fsid)); |
| - } |
| - } |
| - |
| - // TODO(thestig) Handle overlap between devices and media directories. |
| - SystemMonitor* monitor = SystemMonitor::Get(); |
| - const std::vector<SystemMonitor::RemovableStorageInfo> media_devices = |
| - monitor->GetAttachedRemovableStorage(); |
| - for (size_t i = 0; i < media_devices.size(); ++i) { |
| - MediaStorageUtil::Type type; |
| - MediaStorageUtil::CrackDeviceId(media_devices[i].device_id, &type, NULL); |
| - // TODO(vandebo) Handle MTP devices. |
| - if (type != MediaStorageUtil::MTP_OR_PTP && |
| - IsGalleryPermittedForExtension(extension, media_devices[i].location)) { |
| - device_id_map_.insert(std::make_pair(media_devices[i].device_id, |
| - media_devices[i])); |
| - FilePath path(media_devices[i].location); |
| - const std::string fsid = RegisterPathAsFileSystem(path); |
| - child_it->second.insert(std::make_pair(path, fsid)); |
| - } |
| + Profile* profile = |
| + Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext()); |
| + MediaGalleriesPreferences* preferences = |
| + MediaGalleriesPreferencesFactory::GetForProfile(profile); |
| + MediaGalleryPrefIdSet galleries = |
| + preferences->GalleriesForExtension(*extension); |
| + ExtensionGalleriesHost* extension_host = |
| + extension_hosts_map_[profile][extension->id()].get(); |
| + |
| + // If the extension has no galleries and it didn't have any last time, just |
| + // return the empty list. The second check is needed because of |
| + // http://crbug.com/145855. |
| + if (galleries.empty() && !extension_host) |
| + return std::vector<MediaFileSystemRegistry::MediaFSInfo>(); |
| + |
| + if (!extension_host) { |
| + extension_hosts_map_[profile][extension->id()] = |
| + new ExtensionGalleriesHost( |
| + base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty, |
| + base::Unretained(this), profile, extension->id())); |
| + extension_host = extension_hosts_map_[profile][extension->id()].get(); |
|
Lei Zhang
2012/09/05 06:29:22
you can write this as:
extension_host = new Extens
vandebo (ex-Chrome)
2012/09/05 18:25:48
Done.
|
| } |
| + extension_host->ReferenceFromRVH(rvh); |
| - MediaPathToFSIDMap& child_map = child_it->second; |
| - for (MediaPathToFSIDMap::const_iterator it = child_map.begin(); |
| - it != child_map.end(); |
| - ++it) { |
| - MediaFSInfo entry; |
| - // TODO(vandebo) use a better name, fsid for now. |
| - entry.name = it->second; |
| - entry.fsid = it->second; |
| - entry.path = it->first; |
| - results.push_back(entry); |
| - } |
| - return results; |
| + return extension_host->GetMediaFileSystems(galleries, |
| + preferences->known_galleries()); |
| } |
| +// TODO(vandebo) We also need to listen for the attach event and add newly |
| +// attached media devices to MediaGalleriesPreferences. |
| void MediaFileSystemRegistry::OnRemovableStorageDetached( |
| const std::string& id) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - DeviceIdToInfoMap::iterator it = device_id_map_.find(id); |
| - if (it == device_id_map_.end()) |
| - return; |
| + // Since revoking a gallery in the ExtensionGalleriesHost may cause it |
| + // to be removed from the map and therefore invalidate any iterator pointing |
| + // to it, this code first copies all the invalid gallery ids and the |
| + // extension hosts in which they may appear (per profile) and revoked it in |
| + // a second step. |
| + std::list<InvalidatedGalleriesInfo> invalid_galleries_info; |
|
Lei Zhang
2012/09/05 06:29:22
Does this really need to be a list? You're probabl
vandebo (ex-Chrome)
2012/09/05 18:25:48
Done.
|
| + |
| + for (ExtensionGalleriesHostMap::iterator profile_it = |
| + extension_hosts_map_.begin(); |
| + profile_it != extension_hosts_map_.end(); |
| + ++profile_it) { |
| + MediaGalleriesPreferences* preferences = |
| + MediaGalleriesPreferencesFactory::GetForProfile(profile_it->first); |
| + InvalidatedGalleriesInfo invalid_galleries_in_profile; |
| + invalid_galleries_in_profile.pref_ids = |
| + preferences->LookUpGalleriesByDeviceId(id); |
| + |
| + for (ExtensionHostMap::const_iterator extension_host_it = |
| + profile_it->second.begin(); |
| + extension_host_it != profile_it->second.end(); |
| + ++extension_host_it) { |
| + invalid_galleries_in_profile.extension_hosts.insert( |
| + extension_host_it->second.get()); |
| + } |
| - FilePath path(it->second.location); |
| - RevokeMediaFileSystem(path); |
| - device_id_map_.erase(it); |
| -} |
| + invalid_galleries_info.push_back(invalid_galleries_in_profile); |
| + } |
| -void MediaFileSystemRegistry::Observe( |
| - int type, |
| - const content::NotificationSource& source, |
| - const content::NotificationDetails& details) { |
| - DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED || |
| - type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - const RenderProcessHost* rph = |
| - content::Source<content::RenderProcessHost>(source).ptr(); |
| - ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph); |
| - CHECK(child_it != media_fs_map_.end()); |
| - // No need to revoke the isolated file systems. The RPH will do that. |
| - media_fs_map_.erase(child_it); |
| - UnregisterForRPHGoneNotifications(rph); |
| + // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340. |
|
Lei Zhang
2012/09/05 06:29:22
Does this still apply?
vandebo (ex-Chrome)
2012/09/05 18:25:48
Not sure, but moved it to RevokeGalleryByPrefId.
|
| + for (std::list<InvalidatedGalleriesInfo>::const_iterator per_profile_it = |
| + invalid_galleries_info.begin(); |
| + per_profile_it != invalid_galleries_info.end(); |
| + ++per_profile_it) { |
| + for (std::set<ExtensionGalleriesHost*>::const_iterator extension_host_it = |
| + per_profile_it->extension_hosts.begin(); |
| + extension_host_it != per_profile_it->extension_hosts.end(); |
| + ++extension_host_it) { |
| + for (std::set<MediaGalleryPrefId>::const_iterator pref_id_it = |
| + per_profile_it->pref_ids.begin(); |
| + pref_id_it != per_profile_it->pref_ids.end(); |
| + ++pref_id_it) { |
| + (*extension_host_it)->RevokeGalleryByPrefId(*pref_id_it); |
| + } |
| + } |
| + } |
| } |
| /****************** |
| @@ -157,6 +396,8 @@ MediaFileSystemRegistry::MediaFileSystemRegistry() { |
| SystemMonitor* system_monitor = SystemMonitor::Get(); |
| if (system_monitor) |
| system_monitor->AddDevicesChangedObserver(this); |
| + // TODO(vandebo) We should add all the currently attached media devices |
| + // to MediaGalleriesPreferences here. |
| } |
| MediaFileSystemRegistry::~MediaFileSystemRegistry() { |
| @@ -166,56 +407,18 @@ MediaFileSystemRegistry::~MediaFileSystemRegistry() { |
| system_monitor->RemoveDevicesChangedObserver(this); |
| } |
| -void MediaFileSystemRegistry::RegisterForRPHGoneNotifications( |
| - const content::RenderProcessHost* rph) { |
| - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| - content::Source<RenderProcessHost>(rph)); |
| - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| - content::Source<RenderProcessHost>(rph)); |
| -} |
| - |
| -void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications( |
| - const content::RenderProcessHost* rph) { |
| - registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| - content::Source<RenderProcessHost>(rph)); |
| - registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| - content::Source<RenderProcessHost>(rph)); |
| -} |
| - |
| -std::string MediaFileSystemRegistry::RegisterPathAsFileSystem( |
| - const FilePath& path) { |
| +void MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty( |
| + Profile* profile, const std::string& extension_id) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - // Sanity checks for |path|. |
| - CHECK(path.IsAbsolute()); |
| - CHECK(!path.ReferencesParent()); |
| - |
| - // The directory name is not exposed to the js layer and we simply use |
| - // a fixed name (as we only register a single directory per file system). |
| - std::string register_name(extension_misc::kMediaFileSystemPathPart); |
| - const std::string fsid = |
| - IsolatedContext::GetInstance()->RegisterFileSystemForPath( |
| - fileapi::kFileSystemTypeNativeMedia, path, ®ister_name); |
| - CHECK(!fsid.empty()); |
| - return fsid; |
| -} |
| - |
| -void MediaFileSystemRegistry::RevokeMediaFileSystem(const FilePath& path) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - |
| - IsolatedContext* isolated_context = IsolatedContext::GetInstance(); |
| - isolated_context->RevokeFileSystemByPath(path); |
| - |
| - for (ChildIdToMediaFSMap::iterator child_it = media_fs_map_.begin(); |
| - child_it != media_fs_map_.end(); |
| - ++child_it) { |
| - MediaPathToFSIDMap& child_map = child_it->second; |
| - MediaPathToFSIDMap::iterator media_path_it = child_map.find(path); |
| - if (media_path_it == child_map.end()) |
| - continue; |
| - |
| - child_map.erase(media_path_it); |
| - } |
| + ExtensionGalleriesHostMap::iterator extension_hosts = |
| + extension_hosts_map_.find(profile); |
| + DCHECK(extension_hosts != extension_hosts_map_.end()); |
| + ExtensionHostMap::size_type erase_count = |
| + extension_hosts->second.erase(extension_id); |
| + DCHECK_EQ(1U, erase_count); |
| + if (extension_hosts->second.empty()) |
| + extension_hosts_map_.erase(profile); |
|
Lei Zhang
2012/09/05 06:29:22
You can pass |extension_hosts| here to use the mor
vandebo (ex-Chrome)
2012/09/05 18:25:48
Done.
|
| } |
| } // namespace chrome |