| 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 200b4f31a3647d81cc823b1e590cdf6b3c7c6414..25595b66010d8211ca64558fcd84707444bdb0e1 100644
|
| --- a/chrome/browser/media_galleries/media_file_system_registry.cc
|
| +++ b/chrome/browser/media_galleries/media_file_system_registry.cc
|
| @@ -37,6 +37,7 @@
|
| #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/render_view_host_observer.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "webkit/fileapi/file_system_types.h"
|
| #include "webkit/fileapi/isolated_context.h"
|
| @@ -409,19 +410,67 @@ class ExtensionGalleriesHost
|
| DISALLOW_COPY_AND_ASSIGN(ExtensionGalleriesHost);
|
| };
|
|
|
| +// This self-deleting transaction object contains the state needed to
|
| +// asynchronously initialize the storage monitor if needed when an
|
| +// extension calles |GetMediaFileSystemsForExtension|. Specifically,
|
| +// it tracks if the RenderViewHost with which it was initialized was
|
| +// destroyed, and if so, it eats the callback.
|
| +// When it receives the OnPreferences callback, it deletes itself.
|
| +class GetPreferencesTransaction : public content::RenderViewHostObserver {
|
| + public:
|
| + GetPreferencesTransaction(
|
| + content::RenderViewHost* rvh,
|
| + base::Callback<void(MediaGalleriesPreferences::Vendor*)> callback)
|
| + : content::RenderViewHostObserver(rvh),
|
| + callback_(callback) {}
|
| + virtual ~GetPreferencesTransaction() {}
|
| +
|
| + virtual void RenderViewHostDestroyed(content::RenderViewHost* rvh) OVERRIDE {
|
| + callback_.Reset();
|
| + }
|
| +
|
| + void OnPreferences(MediaGalleriesPreferences::Vendor* vendor) {
|
| + if (!callback_.is_null())
|
| + callback_.Run(vendor);
|
| +
|
| + delete this;
|
| + }
|
| +
|
| + private:
|
| + base::Callback<void(MediaGalleriesPreferences::Vendor*)> callback_;
|
| +};
|
| +
|
| /******************
|
| * Public methods
|
| ******************/
|
|
|
| void MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
|
| - const content::RenderViewHost* rvh,
|
| + content::RenderViewHost* rvh,
|
| const extensions::Extension* extension,
|
| const MediaFileSystemsCallback& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| + // This object is self-deleting when it receives the callback
|
| + // from GetPreferencesAsync.
|
| + GetPreferencesTransaction* transaction = new GetPreferencesTransaction(
|
| + rvh,
|
| + base::Bind(
|
| + &MediaFileSystemRegistry::GetMediaFileSystemsWithPreferences,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + rvh, extension, callback));
|
| + GetPreferencesAsync(
|
| + base::Bind(&GetPreferencesTransaction::OnPreferences,
|
| + base::Unretained(transaction)));
|
| +}
|
| +
|
| +void MediaFileSystemRegistry::GetMediaFileSystemsWithPreferences(
|
| + const content::RenderViewHost* rvh,
|
| + const extensions::Extension* extension,
|
| + const MediaFileSystemsCallback& callback,
|
| + MediaGalleriesPreferences::Vendor* vendor) {
|
| Profile* profile =
|
| Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
|
| - MediaGalleriesPreferences* preferences = GetPreferences(profile);
|
| + MediaGalleriesPreferences* preferences = vendor->GetPreferences(profile);
|
| MediaGalleryPrefIdSet galleries =
|
| preferences->GalleriesForExtension(*extension);
|
|
|
| @@ -456,6 +505,33 @@ void MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
|
| callback);
|
| }
|
|
|
| +void MediaFileSystemRegistry::GetPreferencesAsync(
|
| + base::Callback<void(MediaGalleriesPreferences::Vendor*)> callback) {
|
| + StorageMonitor* monitor = StorageMonitor::GetInstance();
|
| + // TODO(gbillock): Make sure tests all have a test storage monitor
|
| + // and eliminate the checks here and elsewhere.
|
| + if (!monitor) {
|
| + callback.Run(this);
|
| + return;
|
| + }
|
| +
|
| + if (monitor->IsInitialized()) {
|
| + callback.Run(this);
|
| + return;
|
| + }
|
| +
|
| + monitor->Initialize(
|
| + base::Bind(&MediaFileSystemRegistry::OnStorageMonitorInitialized,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| +
|
| + // TODO(gbillock): set a timeout here to bail out of init?
|
| +}
|
| +
|
| +void MediaFileSystemRegistry::OnStorageMonitorInitialized(
|
| + base::Callback<void(MediaGalleriesPreferences::Vendor*)> callback) {
|
| + callback.Run(this);
|
| +}
|
| +
|
| MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences(
|
| Profile* profile) {
|
| MediaGalleriesPreferences* preferences =
|
| @@ -468,10 +544,12 @@ MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences(
|
| extension_hosts_map_[profile] = ExtensionHostMap();
|
|
|
| // TODO(gbillock): Move this stanza to MediaGalleriesPreferences init code.
|
| + // Or better, just make sure tests have a storage monitor.
|
| // StorageMonitor may be NULL in unit tests.
|
| StorageMonitor* monitor = StorageMonitor::GetInstance();
|
| if (!monitor)
|
| return preferences;
|
| + DCHECK(monitor->IsInitialized());
|
| std::vector<StorageInfo> existing_devices = monitor->GetAttachedStorage();
|
| for (size_t i = 0; i < existing_devices.size(); i++) {
|
| if (!StorageInfo::IsMediaDevice(existing_devices[i].device_id))
|
| @@ -616,7 +694,8 @@ class MediaFileSystemRegistry::MediaFileSystemContextImpl
|
| };
|
|
|
| MediaFileSystemRegistry::MediaFileSystemRegistry()
|
| - : file_system_context_(new MediaFileSystemContextImpl(this)) {
|
| + : file_system_context_(new MediaFileSystemContextImpl(this)),
|
| + weak_ptr_factory_(this) {
|
| // StorageMonitor may be NULL in unit tests.
|
| StorageMonitor* monitor = StorageMonitor::GetInstance();
|
| if (monitor)
|
|
|