Index: chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc |
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc |
index 7b83d03e1965dfab2ae8b9a50270de5671c84f2b..a44055e114b785ddeb9f80aaf5fa2422dbc09263 100644 |
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc |
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc |
@@ -4,21 +4,132 @@ |
#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h" |
-#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api_factory.h" |
+#include "base/bind.h" |
+#include "base/file_path.h" |
+#include "base/location.h" |
+#include "base/string_number_conversions.h" |
+#include "base/values.h" |
+#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_manager.h" |
+#include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_manager_factory.h" |
#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_event_router.h" |
+#include "chrome/browser/extensions/api/media_galleries_private/media_gallery_extension_notification_observer.h" |
#include "chrome/browser/extensions/event_names.h" |
#include "chrome/browser/extensions/event_router.h" |
#include "chrome/browser/extensions/extension_system.h" |
+#include "chrome/browser/media_gallery/media_file_system_registry.h" |
+#include "chrome/browser/media_gallery/media_galleries_preferences.h" |
+#include "chrome/browser/system_monitor/media_storage_util.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_view_host.h" |
namespace extensions { |
+namespace { |
+ |
+typedef base::Callback<void(bool success)> AddGalleryCallback; |
+ |
+// Returns the absolute file path of the gallery specified by the |gallery_id|. |
+// Returns an empty file path if the |gallery_id| is invalid. |
+FilePath GetGalleryAbsolutePath(chrome::MediaGalleryPrefId gallery_id, |
+ const Profile* profile, |
+ const Extension* extension) { |
+ DCHECK(profile); |
+ DCHECK(extension); |
+ chrome::MediaFileSystemRegistry* registry = |
+ g_browser_process->media_file_system_registry(); |
+ DCHECK(registry); |
+ chrome::MediaGalleriesPreferences* preferences = |
+ registry->GetPreferences(const_cast<Profile*>(profile)); |
+ if (!preferences) |
+ return FilePath(); |
+ |
+ const chrome::MediaGalleryPrefIdSet permitted_galleries = |
+ preferences->GalleriesForExtension(*extension); |
+ if (permitted_galleries.empty() || |
+ permitted_galleries.find(gallery_id) == permitted_galleries.end()) |
+ return FilePath(); |
+ |
+ const chrome::MediaGalleriesPrefInfoMap& galleries_info = |
+ preferences->known_galleries(); |
+ return chrome::MediaStorageUtil::FindDevicePathById( |
+ galleries_info.find(gallery_id)->second.device_id); |
+} |
+ |
+// Handles the profile shutdown event on the file thread to clean up |
+// GalleryWatchManagerFactory. |
+void HandleProfileShutdownOnFileThread(const Profile* profile) { |
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
+ GalleryWatchManagerFactory::GetInstance()->OnProfileShutdown(profile); |
+} |
+ |
+// Returns GalleryWatchManager associated with the specified |profile|. Set |
+// |create| to true, to create a GalleryWatchManager if it does not exists. |
+GalleryWatchManager* GetGalleryWatchManagerOnFileThread(const Profile* profile, |
+ bool create) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ if (!create && |
+ !GalleryWatchManagerFactory::GetInstance()->HasForProfile(profile)) |
+ return NULL; |
+ return GalleryWatchManagerFactory::GetInstance()->GetForProfile(profile); |
+} |
+ |
+// Set up gallery watch on the file thread for the extension specified by the |
+// |extension_id|. |
+// |profile| specifies the extension profile. |
+// |gallery_id|specifies the gallery identifier. |
+// |gallery_file_path| specifies the absolute gallery path. |
+// |add_gallery_callback| specifies the callback that is called when the setup |
+// operation is complete. It notifies the extension about the watch request |
+// result. |
+void SetupGalleryWatchOnFileThread( |
+ const Profile* profile, |
+ const std::string& gallery_id, |
+ const FilePath& gallery_file_path, |
+ const std::string& extension_id, |
+ const AddGalleryCallback& add_gallery_callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ bool success = false; |
+ GalleryWatchManager* manager = GetGalleryWatchManagerOnFileThread(profile, |
+ true); |
+ if (manager) { |
+ success = manager->StartGalleryWatch(gallery_id, gallery_file_path, |
+ extension_id); |
+ } |
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(add_gallery_callback, success)); |
+} |
+ |
+// Cancels the gallery watch for the extension specified by the |extension_id| |
+// on the file thread. |
+void RemoveGalleryWatchOnFileThread(const Profile* profile, |
+ const FilePath& gallery_file_path, |
+ const std::string& extension_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ GalleryWatchManager* manager = GetGalleryWatchManagerOnFileThread(profile, |
+ false); |
+ if (!manager) |
+ return; |
+ manager->StopGalleryWatch(gallery_file_path, extension_id); |
+} |
+ |
+} // namespace |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// MediaGalleriesPrivateAPI // |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
MediaGalleriesPrivateAPI::MediaGalleriesPrivateAPI(Profile* profile) |
: profile_(profile) { |
+ DCHECK(profile_); |
+ extension_notification_observer_.reset( |
+ new MediaGalleryExtensionNotificationObserver(profile_)); |
ExtensionSystem::Get(profile_)->event_router()->RegisterObserver( |
this, event_names::kOnAttachEventName); |
- ExtensionSystem::Get(profile_)->event_router()->RegisterObserver( |
+ ExtensionSystem::Get(profile_)->event_router()->RegisterObserver( |
this, event_names::kOnDetachEventName); |
- |
+ ExtensionSystem::Get(profile_)->event_router()->RegisterObserver( |
+ this, event_names::kOnGalleryChangedEventName); |
} |
MediaGalleriesPrivateAPI::~MediaGalleriesPrivateAPI() { |
@@ -26,13 +137,119 @@ MediaGalleriesPrivateAPI::~MediaGalleriesPrivateAPI() { |
void MediaGalleriesPrivateAPI::Shutdown() { |
ExtensionSystem::Get(profile_)->event_router()->UnregisterObserver(this); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&HandleProfileShutdownOnFileThread, profile_)); |
} |
void MediaGalleriesPrivateAPI::OnListenerAdded( |
- const extensions::EventListenerInfo& details) { |
+ const EventListenerInfo& details) { |
media_galleries_private_event_router_.reset( |
new MediaGalleriesPrivateEventRouter(profile_)); |
- ExtensionSystem::Get(profile_)->event_router()->UnregisterObserver(this); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// MediaGalleryWatchFunctionBase // |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+MediaGalleryWatchFunctionBase::MediaGalleryWatchFunctionBase() { |
+} |
+ |
+#if defined (OS_WIN) |
+bool MediaGalleryWatchFunctionBase::RunImpl() { |
+ if (!render_view_host() || !render_view_host()->GetProcess()) |
+ return false; |
+ |
+ // First param is the gallery identifier to watch. |
+ std::string gallery_id; |
+ if (!args_->GetString(0, &gallery_id) || (gallery_id.empty())) |
+ return false; |
+ |
+ chrome::MediaGalleryPrefId gallery_pref_id = 0; |
+ if (!base::StringToUint64(gallery_id, &gallery_pref_id)) { |
+ HandleResponse(gallery_id, false); |
+ return true; |
+ } |
+ |
+ FilePath gallery_file_path( |
+ GetGalleryAbsolutePath(gallery_pref_id, profile_, GetExtension())); |
+ if (gallery_file_path.empty()) { |
+ HandleResponse(gallery_id, false); |
+ return true; |
+ } |
+ |
+ PerformGalleryWatchOperation(gallery_id, gallery_file_path); |
+ return true; |
+} |
+#else |
+bool MediaGalleryWatchFunctionBase::RunImpl() { |
Lei Zhang
2012/12/15 02:00:29
You shouldn't have to write this function twice.
kmadhusu
2012/12/17 23:58:05
Done.
|
+ if (!render_view_host() || !render_view_host()->GetProcess()) |
+ return false; |
+ |
+ // First param is the gallery identifier to watch. |
+ std::string gallery_id; |
+ if (!args_->GetString(0, &gallery_id) || (gallery_id.empty())) |
+ return false; |
+ |
+ // Gallery watch operations are not currently supported on non-windows |
+ // platforms. Please refer to crbug.com/144491 for more details. |
+ HandleResponse(gallery_id, false); |
+ return true; |
+} |
+#endif |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// MediaGalleriesPrivateAddGalleryWatchFunction // |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+void MediaGalleriesPrivateAddGalleryWatchFunction::PerformGalleryWatchOperation( |
+ const std::string& gallery_id, |
+ const FilePath& gallery_watch_path) { |
+ DCHECK(profile_); |
+ content::BrowserThread::PostTask( |
Lei Zhang
2012/12/15 02:00:29
Can you PostTaskAndReplyWithResult() instead?
kmadhusu
2012/12/17 23:58:05
Done.
|
+ content::BrowserThread::FILE, FROM_HERE, |
+ base::Bind( |
+ &SetupGalleryWatchOnFileThread, |
+ profile_, |
+ gallery_id, |
+ gallery_watch_path, |
+ extension_id(), |
+ base::Bind( |
+ &MediaGalleriesPrivateAddGalleryWatchFunction::HandleResponse, |
+ this, |
+ gallery_id))); |
+} |
+ |
+void MediaGalleriesPrivateAddGalleryWatchFunction::HandleResponse( |
+ const std::string& gallery_id, |
+ bool success) { |
+ scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); |
Lei Zhang
2012/12/15 02:00:29
Look for an AddGalleryWatchResult class in out/Deb
kmadhusu
2012/12/17 23:58:05
Done.
|
+ result->SetString("galleryId", gallery_id); |
+ result->SetBoolean("success", success); |
+ SetResult(result.release()); |
+ SendResponse(true); |
+} |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// MediaGalleriesPrivateRemoveGalleryWatchFunction // |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+void MediaGalleriesPrivateRemoveGalleryWatchFunction:: |
+PerformGalleryWatchOperation(const std::string& gallery_id, |
+ const FilePath& gallery_watch_path) { |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&RemoveGalleryWatchOnFileThread, profile_, |
+ gallery_watch_path, extension_id())); |
+ HandleResponse(gallery_id, true); |
+} |
+ |
+void MediaGalleriesPrivateRemoveGalleryWatchFunction::HandleResponse( |
+ const std::string& gallery_id, |
+ bool success) { |
+ SendResponse(true); |
} |
} // namespace extensions |