| Index: chrome/browser/media/media_stream_devices_controller.cc
|
| diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc
|
| index c85af1e9423980d4d0d61632103e53d60569dfd1..b301c56c73df5e9b50b7a653ec93320976eedc6e 100644
|
| --- a/chrome/browser/media/media_stream_devices_controller.cc
|
| +++ b/chrome/browser/media/media_stream_devices_controller.cc
|
| @@ -12,27 +12,12 @@
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/common/content_settings.h"
|
| #include "chrome/common/pref_names.h"
|
| +#include "content/public/common/media_stream_request.h"
|
|
|
| using content::BrowserThread;
|
|
|
| namespace {
|
|
|
| -// A predicate that checks if a StreamDeviceInfo object has the same ID as the
|
| -// device ID specified at construction.
|
| -class DeviceIdEquals {
|
| - public:
|
| - explicit DeviceIdEquals(const std::string& device_id)
|
| - : device_id_(device_id) {
|
| - }
|
| -
|
| - bool operator() (const content::MediaStreamDevice& device) {
|
| - return device.device_id == device_id_;
|
| - }
|
| -
|
| - private:
|
| - std::string device_id_;
|
| -};
|
| -
|
| // A predicate that checks if a StreamDeviceInfo object has the same device
|
| // name as the device name specified at construction.
|
| class DeviceNameEquals {
|
| @@ -49,14 +34,6 @@ class DeviceNameEquals {
|
| std::string device_name_;
|
| };
|
|
|
| -// Whether |request| contains any device of given |type|.
|
| -bool HasDevice(const content::MediaStreamRequest& request,
|
| - content::MediaStreamDeviceType type) {
|
| - content::MediaStreamDeviceMap::const_iterator device_it =
|
| - request.devices.find(type);
|
| - return device_it != request.devices.end() && !device_it->second.empty();
|
| -}
|
| -
|
| const char kAudioKey[] = "audio";
|
| const char kVideoKey[] = "video";
|
|
|
| @@ -69,10 +46,17 @@ MediaStreamDevicesController::MediaStreamDevicesController(
|
| : profile_(profile),
|
| request_(*request),
|
| callback_(callback) {
|
| - has_audio_ =
|
| - HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
|
| - has_video_ =
|
| - HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
|
| + has_audio_ = false;
|
| + has_video_ = false;
|
| + for (content::MediaStreamDeviceMap::const_iterator it =
|
| + request_.devices.begin();
|
| + it != request_.devices.end(); ++it) {
|
| + if (content::IsAudioMediaType(it->first)) {
|
| + has_audio_ |= !it->second.empty();
|
| + } else if (content::IsVideoMediaType(it->first)) {
|
| + has_video_ |= !it->second.empty();
|
| + }
|
| + }
|
| }
|
|
|
| MediaStreamDevicesController::~MediaStreamDevicesController() {}
|
| @@ -118,47 +102,66 @@ bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
|
|
|
| content::MediaStreamDevices
|
| MediaStreamDevicesController::GetAudioDevices() const {
|
| - if (!has_audio_)
|
| - return content::MediaStreamDevices();
|
| -
|
| - content::MediaStreamDeviceMap::const_iterator it =
|
| - request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
|
| - DCHECK(it != request_.devices.end());
|
| - return it->second;
|
| + content::MediaStreamDevices all_audio_devices;
|
| + if (has_audio_) {
|
| + FindSubsetOfDevices(&content::IsAudioMediaType, &all_audio_devices);
|
| + }
|
| + return all_audio_devices;
|
| }
|
|
|
| content::MediaStreamDevices
|
| MediaStreamDevicesController::GetVideoDevices() const {
|
| - if (!has_video_)
|
| - return content::MediaStreamDevices();
|
| + content::MediaStreamDevices all_video_devices;
|
| + if (has_video_) {
|
| + FindSubsetOfDevices(&content::IsVideoMediaType, &all_video_devices);
|
| + }
|
| + return all_video_devices;
|
| +}
|
| +
|
| +const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
|
| + return request_.security_origin.spec();
|
| +}
|
|
|
| - content::MediaStreamDeviceMap::const_iterator it =
|
| - request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
|
| - DCHECK(it != request_.devices.end());
|
| - return it->second;
|
| +bool MediaStreamDevicesController::IsSafeToAlwaysAllowAudio() const {
|
| + return IsSafeToAlwaysAllow(
|
| + &content::IsAudioMediaType, content::MEDIA_DEVICE_AUDIO_CAPTURE);
|
| }
|
|
|
| -const GURL& MediaStreamDevicesController::GetSecurityOrigin() const {
|
| - return request_.security_origin;
|
| +bool MediaStreamDevicesController::IsSafeToAlwaysAllowVideo() const {
|
| + return IsSafeToAlwaysAllow(
|
| + &content::IsVideoMediaType, content::MEDIA_DEVICE_VIDEO_CAPTURE);
|
| }
|
|
|
| void MediaStreamDevicesController::Accept(const std::string& audio_id,
|
| const std::string& video_id,
|
| bool always_allow) {
|
| content::MediaStreamDevices devices;
|
| - std::string audio_device, video_device;
|
| - if (has_audio_) {
|
| - AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
|
| - audio_id, &devices, &audio_device);
|
| + std::string audio_device_name, video_device_name;
|
| +
|
| + const content::MediaStreamDevice* const audio_device =
|
| + FindFirstDeviceWithIdInSubset(&content::IsAudioMediaType, audio_id);
|
| + if (audio_device) {
|
| + if (audio_device->type != content::MEDIA_DEVICE_AUDIO_CAPTURE) {
|
| + always_allow = false; // override for virtual audio device type
|
| + }
|
| + devices.push_back(*audio_device);
|
| + audio_device_name = audio_device->name;
|
| }
|
| - if (has_video_) {
|
| - AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
|
| - video_id, &devices, &video_device);
|
| +
|
| + const content::MediaStreamDevice* const video_device =
|
| + FindFirstDeviceWithIdInSubset(&content::IsVideoMediaType, video_id);
|
| + if (video_device) {
|
| + if (video_device->type != content::MEDIA_DEVICE_VIDEO_CAPTURE) {
|
| + always_allow = false; // override for virtual video device type
|
| + }
|
| + devices.push_back(*video_device);
|
| + video_device_name = video_device->name;
|
| }
|
| +
|
| DCHECK(!devices.empty());
|
|
|
| if (always_allow)
|
| - AlwaysAllowOriginAndDevices(audio_device, video_device);
|
| + AlwaysAllowOriginAndDevices(audio_device_name, video_device_name);
|
|
|
| callback_.Run(devices);
|
| }
|
| @@ -167,24 +170,28 @@ void MediaStreamDevicesController::Deny() {
|
| callback_.Run(content::MediaStreamDevices());
|
| }
|
|
|
| -void MediaStreamDevicesController::AddDeviceWithId(
|
| - content::MediaStreamDeviceType type,
|
| - const std::string& id,
|
| - content::MediaStreamDevices* devices,
|
| - std::string* device_name) {
|
| - DCHECK(devices);
|
| - content::MediaStreamDeviceMap::const_iterator device_it =
|
| - request_.devices.find(type);
|
| - if (device_it == request_.devices.end())
|
| - return;
|
| +bool MediaStreamDevicesController::IsSafeToAlwaysAllow(
|
| + FilterByDeviceTypeFunc is_included,
|
| + content::MediaStreamDeviceType device_type) const {
|
| + DCHECK(device_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
|
| + device_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
|
|
|
| - content::MediaStreamDevices::const_iterator it = std::find_if(
|
| - device_it->second.begin(), device_it->second.end(), DeviceIdEquals(id));
|
| - if (it == device_it->second.end())
|
| - return;
|
| + if (!request_.security_origin.SchemeIsSecure()) {
|
| + return false;
|
| + }
|
|
|
| - devices->push_back(*it);
|
| - *device_name = it->name;
|
| + // If non-physical devices are available for the choosing, then it's not safe.
|
| + bool safe_devices_found = false;
|
| + for (content::MediaStreamDeviceMap::const_iterator it =
|
| + request_.devices.begin();
|
| + it != request_.devices.end(); ++it) {
|
| + if (it->first != device_type && is_included(it->first)) {
|
| + return false;
|
| + }
|
| + safe_devices_found = true;
|
| + }
|
| +
|
| + return safe_devices_found;
|
| }
|
|
|
| bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() {
|
| @@ -232,12 +239,10 @@ void MediaStreamDevicesController::GetAlwaysAllowedDevices(
|
| // devices on the lists.
|
| if (ShouldAlwaysAllowOrigin()) {
|
| if (has_audio_) {
|
| - *audio_id =
|
| - GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
|
| + *audio_id = GetFirstDeviceId(content::MEDIA_DEVICE_AUDIO_CAPTURE);
|
| }
|
| if (has_video_) {
|
| - *video_id =
|
| - GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
|
| + *video_id = GetFirstDeviceId(content::MEDIA_DEVICE_VIDEO_CAPTURE);
|
| }
|
| return;
|
| }
|
| @@ -269,11 +274,11 @@ void MediaStreamDevicesController::GetAlwaysAllowedDevices(
|
|
|
| if (has_audio_ && !audio_name.empty()) {
|
| *audio_id = GetDeviceIdByName(
|
| - content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, audio_name);
|
| + content::MEDIA_DEVICE_AUDIO_CAPTURE, audio_name);
|
| }
|
| if (has_video_ && !video_name.empty()) {
|
| *video_id = GetDeviceIdByName(
|
| - content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, video_name);
|
| + content::MEDIA_DEVICE_VIDEO_CAPTURE, video_name);
|
| }
|
| }
|
|
|
| @@ -303,3 +308,37 @@ std::string MediaStreamDevicesController::GetFirstDeviceId(
|
|
|
| return std::string();
|
| }
|
| +
|
| +void MediaStreamDevicesController::FindSubsetOfDevices(
|
| + FilterByDeviceTypeFunc is_included,
|
| + content::MediaStreamDevices* out) const {
|
| + for (content::MediaStreamDeviceMap::const_iterator it =
|
| + request_.devices.begin();
|
| + it != request_.devices.end(); ++it) {
|
| + if (is_included(it->first)) {
|
| + out->insert(out->end(), it->second.begin(), it->second.end());
|
| + }
|
| + }
|
| +}
|
| +
|
| +const content::MediaStreamDevice*
|
| +MediaStreamDevicesController::FindFirstDeviceWithIdInSubset(
|
| + FilterByDeviceTypeFunc is_included,
|
| + const std::string& device_id) const {
|
| + for (content::MediaStreamDeviceMap::const_iterator it =
|
| + request_.devices.begin();
|
| + it != request_.devices.end(); ++it) {
|
| + if (!is_included(it->first)) {
|
| + continue;
|
| + }
|
| + for (content::MediaStreamDevices::const_iterator device_it =
|
| + it->second.begin();
|
| + device_it != it->second.end(); ++device_it) {
|
| + const content::MediaStreamDevice& candidate = *device_it;
|
| + if (candidate.device_id == device_id) {
|
| + return &candidate;
|
| + }
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
|
|