Chromium Code Reviews| 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 |