blob: 1d8b428ce08ef086d37f5a4d4ed390735b30eeda [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// MediaGalleriesPrivateEventRouter implementation.
#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_event_router.h"
#include <map>
#include "base/strings/utf_string_conversions.h"
#include "base/values.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/profiles/profile.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/common/extensions/api/media_galleries_private.h"
#include "content/public/browser/browser_thread.h"
namespace media_galleries_private = extensions::api::media_galleries_private;
namespace extensions {
namespace {
std::string GetTransientIdForDeviceId(const std::string& device_id) {
StorageMonitor* monitor = StorageMonitor::GetInstance();
return monitor->GetTransientIdForDeviceId(device_id);
}
} // namespace
using media_galleries_private::DeviceAttachmentDetails;
using media_galleries_private::DeviceDetachmentDetails;
using media_galleries_private::GalleryChangeDetails;
MediaGalleriesPrivateEventRouter::MediaGalleriesPrivateEventRouter(
Profile* profile)
: profile_(profile) {
DCHECK(profile_);
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
StorageMonitor::GetInstance()->AddObserver(this);
}
MediaGalleriesPrivateEventRouter::~MediaGalleriesPrivateEventRouter() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
// TODO(gbillock): Remove this check once we have destruction order
// fixed up for profile services and the storage monitor.
if (StorageMonitor::GetInstance())
StorageMonitor::GetInstance()->RemoveObserver(this);
}
void MediaGalleriesPrivateEventRouter::OnGalleryChanged(
MediaGalleryPrefId gallery_id,
const std::set<std::string>& extension_ids) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
EventRouter* router =
extensions::ExtensionSystem::Get(profile_)->event_router();
if (!router->HasEventListener(
media_galleries_private::OnGalleryChanged::kEventName))
return;
for (std::set<std::string>::const_iterator it = extension_ids.begin();
it != extension_ids.end(); ++it) {
GalleryChangeDetails details;
details.gallery_id = gallery_id;
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Append(details.ToValue().release());
scoped_ptr<extensions::Event> event(new extensions::Event(
media_galleries_private::OnGalleryChanged::kEventName,
args.Pass()));
// Use DispatchEventToExtension() instead of BroadcastEvent().
// BroadcastEvent() sends the gallery changed events to all the extensions
// who have added a listener to the onGalleryChanged event. There is a
// chance that an extension might have added an onGalleryChanged() listener
// without calling addGalleryWatch(). Therefore, use
// DispatchEventToExtension() to dispatch the gallery changed event only to
// the watching extensions.
router->DispatchEventToExtension(*it, event.Pass());
}
}
void MediaGalleriesPrivateEventRouter::OnRemovableStorageAttached(
const StorageInfo& info) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
EventRouter* router =
extensions::ExtensionSystem::Get(profile_)->event_router();
if (!router->HasEventListener(
media_galleries_private::OnDeviceAttached::kEventName))
return;
MediaGalleryPrefInfo pref_info;
pref_info.display_name = info.name();
pref_info.device_id = info.device_id();
pref_info.type = MediaGalleryPrefInfo::kAutoDetected;
pref_info.volume_label = info.storage_label();
pref_info.vendor_name = info.vendor_name();
pref_info.model_name = info.model_name();
pref_info.total_size_in_bytes = info.total_size_in_bytes();
pref_info.volume_metadata_valid = true;
DeviceAttachmentDetails details;
details.device_name = UTF16ToUTF8(pref_info.GetGalleryDisplayName());
details.device_id = GetTransientIdForDeviceId(info.device_id());
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Append(details.ToValue().release());
DispatchEvent(
media_galleries_private::OnDeviceAttached::kEventName, args.Pass());
}
void MediaGalleriesPrivateEventRouter::OnRemovableStorageDetached(
const StorageInfo& info) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
EventRouter* router =
extensions::ExtensionSystem::Get(profile_)->event_router();
if (!router->HasEventListener(
media_galleries_private::OnDeviceDetached::kEventName))
return;
DeviceDetachmentDetails details;
details.device_id = GetTransientIdForDeviceId(info.device_id());
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Append(details.ToValue().release());
DispatchEvent(
media_galleries_private::OnDeviceDetached::kEventName, args.Pass());
}
void MediaGalleriesPrivateEventRouter::DispatchEvent(
const std::string& event_name,
scoped_ptr<base::ListValue> event_args) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
EventRouter* router =
extensions::ExtensionSystem::Get(profile_)->event_router();
if (!router)
return;
scoped_ptr<extensions::Event> event(new extensions::Event(
event_name, event_args.Pass()));
event->restrict_to_profile = profile_;
router->BroadcastEvent(event.Pass());
}
} // namespace extensions