| Index: content/browser/renderer_host/media/media_devices_dispatcher_host.cc
|
| diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
|
| index 948b50255ca89e991a394680d752da8a2fd004f5..cea286fb55e71a06468c55f4d1fccdd8dd0aca44 100644
|
| --- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
|
| +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "content/browser/renderer_host/media/media_devices_dispatcher_host.h"
|
|
|
| +#include <stddef.h>
|
| +
|
| #include <utility>
|
| #include <vector>
|
|
|
| @@ -40,29 +42,49 @@ MediaDeviceInfo TranslateDeviceInfo(bool has_permission,
|
| device_info.group_id));
|
| }
|
|
|
| +MediaDeviceInfoArray TranslateMediaDeviceInfoArray(
|
| + bool has_permission,
|
| + const std::string& device_id_salt,
|
| + const std::string& group_id_salt,
|
| + const url::Origin& security_origin,
|
| + const MediaDeviceInfoArray& input) {
|
| + MediaDeviceInfoArray result;
|
| + for (const auto& device_info : input) {
|
| + result.push_back(TranslateDeviceInfo(has_permission, device_id_salt,
|
| + group_id_salt, security_origin,
|
| + device_info));
|
| + }
|
| + return result;
|
| +}
|
| +
|
| } // namespace
|
|
|
| +struct MediaDevicesDispatcherHost::SubscriptionInfo {
|
| + uint32_t subscription_id;
|
| + url::Origin security_origin;
|
| +};
|
| +
|
| // static
|
| void MediaDevicesDispatcherHost::Create(
|
| int render_process_id,
|
| - int routing_id,
|
| + int render_frame_id,
|
| const std::string& device_id_salt,
|
| MediaStreamManager* media_stream_manager,
|
| ::mojom::MediaDevicesDispatcherHostRequest request) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - mojo::MakeStrongBinding(
|
| - base::MakeUnique<MediaDevicesDispatcherHost>(
|
| - render_process_id, routing_id, device_id_salt, media_stream_manager),
|
| - std::move(request));
|
| + mojo::MakeStrongBinding(base::MakeUnique<MediaDevicesDispatcherHost>(
|
| + render_process_id, render_frame_id,
|
| + device_id_salt, media_stream_manager),
|
| + std::move(request));
|
| }
|
|
|
| MediaDevicesDispatcherHost::MediaDevicesDispatcherHost(
|
| int render_process_id,
|
| - int routing_id,
|
| + int render_frame_id,
|
| const std::string& device_id_salt,
|
| MediaStreamManager* media_stream_manager)
|
| : render_process_id_(render_process_id),
|
| - routing_id_(routing_id),
|
| + render_frame_id_(render_frame_id),
|
| device_id_salt_(device_id_salt),
|
| group_id_salt_(ResourceContext::CreateRandomMediaDeviceIDSalt()),
|
| media_stream_manager_(media_stream_manager),
|
| @@ -72,6 +94,13 @@ MediaDevicesDispatcherHost::MediaDevicesDispatcherHost(
|
|
|
| MediaDevicesDispatcherHost::~MediaDevicesDispatcherHost() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
|
| + if (!device_change_subscriptions_[i].empty()) {
|
| + media_stream_manager_->media_devices_manager()
|
| + ->UnsubscribeDeviceChangeNotifications(
|
| + static_cast<MediaDeviceType>(i), this);
|
| + }
|
| + }
|
| }
|
|
|
| void MediaDevicesDispatcherHost::EnumerateDevices(
|
| @@ -101,18 +130,129 @@ void MediaDevicesDispatcherHost::EnumerateDevices(
|
| devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = request_audio_output;
|
|
|
| permission_checker_.CheckPermissions(
|
| - devices_to_enumerate, render_process_id_, routing_id_, security_origin,
|
| + devices_to_enumerate, render_process_id_, render_frame_id_,
|
| + security_origin,
|
| base::Bind(&MediaDevicesDispatcherHost::DoEnumerateDevices,
|
| weak_factory_.GetWeakPtr(), devices_to_enumerate,
|
| security_origin, client_callback));
|
| }
|
|
|
| +void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications(
|
| + MediaDeviceType type,
|
| + uint32_t subscription_id,
|
| + const url::Origin& security_origin) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(IsValidMediaDeviceType(type));
|
| + if (!MediaStreamManager::IsOriginAllowed(render_process_id_,
|
| + security_origin)) {
|
| + bad_message::ReceivedBadMessage(render_process_id_,
|
| + bad_message::MDDH_UNAUTHORIZED_ORIGIN);
|
| + return;
|
| + }
|
| +
|
| + auto it = std::find_if(device_change_subscriptions_[type].begin(),
|
| + device_change_subscriptions_[type].end(),
|
| + [subscription_id](const SubscriptionInfo& info) {
|
| + return info.subscription_id == subscription_id;
|
| + });
|
| +
|
| + if (it != device_change_subscriptions_[type].end()) {
|
| + bad_message::ReceivedBadMessage(
|
| + render_process_id_, bad_message::MDDH_INVALID_SUBSCRIPTION_REQUEST);
|
| + return;
|
| + }
|
| +
|
| + if (device_change_subscriptions_[type].empty()) {
|
| + media_stream_manager_->media_devices_manager()
|
| + ->SubscribeDeviceChangeNotifications(type, this);
|
| + }
|
| +
|
| + device_change_subscriptions_[type].push_back(
|
| + SubscriptionInfo{subscription_id, security_origin});
|
| +}
|
| +
|
| +void MediaDevicesDispatcherHost::UnsubscribeDeviceChangeNotifications(
|
| + MediaDeviceType type,
|
| + uint32_t subscription_id) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(IsValidMediaDeviceType(type));
|
| + auto it = std::find_if(device_change_subscriptions_[type].begin(),
|
| + device_change_subscriptions_[type].end(),
|
| + [subscription_id](const SubscriptionInfo& info) {
|
| + return info.subscription_id == subscription_id;
|
| + });
|
| +
|
| + if (it == device_change_subscriptions_[type].end()) {
|
| + bad_message::ReceivedBadMessage(
|
| + render_process_id_, bad_message::MDDH_INVALID_UNSUBSCRIPTION_REQUEST);
|
| + return;
|
| + }
|
| +
|
| + device_change_subscriptions_[type].erase(it);
|
| + if (device_change_subscriptions_[type].empty()) {
|
| + media_stream_manager_->media_devices_manager()
|
| + ->UnsubscribeDeviceChangeNotifications(type, this);
|
| + }
|
| +}
|
| +
|
| +void MediaDevicesDispatcherHost::OnDevicesChanged(
|
| + MediaDeviceType type,
|
| + const MediaDeviceInfoArray& device_infos) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + DCHECK(IsValidMediaDeviceType(type));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&MediaDevicesDispatcherHost::NotifyDeviceChangeOnUIThread,
|
| + weak_factory_.GetWeakPtr(), device_change_subscriptions_[type],
|
| + type, device_infos));
|
| +}
|
| +
|
| +void MediaDevicesDispatcherHost::NotifyDeviceChangeOnUIThread(
|
| + const std::vector<SubscriptionInfo>& subscriptions,
|
| + MediaDeviceType type,
|
| + const MediaDeviceInfoArray& device_infos) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + DCHECK(IsValidMediaDeviceType(type));
|
| +
|
| + ::mojom::MediaDevicesListenerPtr media_devices_listener;
|
| + if (device_change_listener_) {
|
| + media_devices_listener = std::move(device_change_listener_);
|
| + } else {
|
| + RenderFrameHost* render_frame_host =
|
| + RenderFrameHost::FromID(render_process_id_, render_frame_id_);
|
| + if (!render_frame_host)
|
| + return;
|
| +
|
| + render_frame_host->GetRemoteInterfaces()->GetInterface(
|
| + mojo::GetProxy(&media_devices_listener));
|
| + if (!media_devices_listener)
|
| + return;
|
| + }
|
| +
|
| + for (const auto& subscription : subscriptions) {
|
| + bool has_permission = permission_checker_.CheckPermissionOnUIThread(
|
| + type, render_process_id_, render_frame_id_,
|
| + subscription.security_origin);
|
| + media_devices_listener->OnDevicesChanged(
|
| + type, subscription.subscription_id,
|
| + TranslateMediaDeviceInfoArray(
|
| + has_permission, device_id_salt_, group_id_salt_,
|
| + subscription.security_origin, device_infos));
|
| + }
|
| +}
|
| +
|
| void MediaDevicesDispatcherHost::SetPermissionChecker(
|
| const MediaDevicesPermissionChecker& permission_checker) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| permission_checker_ = permission_checker;
|
| }
|
|
|
| +void MediaDevicesDispatcherHost::SetDeviceChangeListenerForTesting(
|
| + ::mojom::MediaDevicesListenerPtr listener) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + device_change_listener_ = std::move(listener);
|
| +}
|
| +
|
| void MediaDevicesDispatcherHost::DoEnumerateDevices(
|
| const MediaDevicesManager::BoolDeviceTypes& requested_types,
|
| const url::Origin& security_origin,
|
|
|