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) |