|
| 1 | +// Copyright (c) 2012 Intel Corp |
| 2 | +// Copyright (c) 2012 The Chromium Authors |
| 3 | +// |
| 4 | +// Permission is hereby granted, free of charge, to any person obtaining a copy |
| 5 | +// of this software and associated documentation files (the "Software"), to deal |
| 6 | +// in the Software without restriction, including without limitation the rights |
| 7 | +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co |
| 8 | +// pies of the Software, and to permit persons to whom the Software is furnished |
| 9 | +// to do so, subject to the following conditions: |
| 10 | +// |
| 11 | +// The above copyright notice and this permission notice shall be included in al |
| 12 | +// l copies or substantial portions of the Software. |
| 13 | +// |
| 14 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM |
| 15 | +// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES |
| 16 | +// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS |
| 17 | +// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH |
| 18 | +// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 20 | + |
| 21 | +#include "content/nw/src/media/media_stream_devices_controller.h" |
| 22 | + |
| 23 | +#include "base/logging.h" |
| 24 | +#include "base/values.h" |
| 25 | + |
| 26 | +namespace { |
| 27 | + |
| 28 | +// A predicate that checks if a StreamDeviceInfo object has the same ID as the |
| 29 | +// device ID specified at construction. |
| 30 | +class DeviceIdEquals { |
| 31 | + public: |
| 32 | + explicit DeviceIdEquals(const std::string& device_id) |
| 33 | + : device_id_(device_id) { |
| 34 | + } |
| 35 | + |
| 36 | + bool operator() (const content::MediaStreamDevice& device) { |
| 37 | + return device.device_id == device_id_; |
| 38 | + } |
| 39 | + |
| 40 | + private: |
| 41 | + std::string device_id_; |
| 42 | +}; |
| 43 | + |
| 44 | +// A predicate that checks if a StreamDeviceInfo object has the same device |
| 45 | +// name as the device name specified at construction. |
| 46 | +class DeviceNameEquals { |
| 47 | + public: |
| 48 | + explicit DeviceNameEquals(const std::string& device_name) |
| 49 | + : device_name_(device_name) { |
| 50 | + } |
| 51 | + |
| 52 | + bool operator() (const content::MediaStreamDevice& device) { |
| 53 | + return device.name == device_name_; |
| 54 | + } |
| 55 | + |
| 56 | + private: |
| 57 | + std::string device_name_; |
| 58 | +}; |
| 59 | + |
| 60 | +// Whether |request| contains any device of given |type|. |
| 61 | +bool HasDevice(const content::MediaStreamRequest& request, |
| 62 | + content::MediaStreamDeviceType type) { |
| 63 | + content::MediaStreamDeviceMap::const_iterator device_it = |
| 64 | + request.devices.find(type); |
| 65 | + return device_it != request.devices.end() && !device_it->second.empty(); |
| 66 | +} |
| 67 | + |
| 68 | +const char kAudioKey[] = "audio"; |
| 69 | +const char kVideoKey[] = "video"; |
| 70 | + |
| 71 | +} // namespace |
| 72 | + |
| 73 | +MediaStreamDevicesController::MediaStreamDevicesController( |
| 74 | + const content::MediaStreamRequest* request, |
| 75 | + const content::MediaResponseCallback& callback) |
| 76 | + : request_(*request), |
| 77 | + callback_(callback) { |
| 78 | + has_audio_ = |
| 79 | + HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); |
| 80 | + has_video_ = |
| 81 | + HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
| 82 | +} |
| 83 | + |
| 84 | +MediaStreamDevicesController::~MediaStreamDevicesController() {} |
| 85 | + |
| 86 | +bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { |
| 87 | + // Deny the request and don't show the infobar if there is no devices. |
| 88 | + if (!has_audio_ && !has_video_) { |
| 89 | + // TODO(xians): We should detect this in a early state, and post a callback |
| 90 | + // to tell the users that no device is available. Remove the code and add |
| 91 | + // a DCHECK when this is done. |
| 92 | + Deny(); |
| 93 | + return true; |
| 94 | + } |
| 95 | + |
| 96 | + std::string audio, video; |
| 97 | + GetAlwaysAllowedDevices(&audio, &video); |
| 98 | + Accept(audio, video, true); |
| 99 | + return true; |
| 100 | +} |
| 101 | + |
| 102 | +content::MediaStreamDevices |
| 103 | +MediaStreamDevicesController::GetAudioDevices() const { |
| 104 | + if (!has_audio_) |
| 105 | + return content::MediaStreamDevices(); |
| 106 | + |
| 107 | + content::MediaStreamDeviceMap::const_iterator it = |
| 108 | + request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); |
| 109 | + DCHECK(it != request_.devices.end()); |
| 110 | + return it->second; |
| 111 | +} |
| 112 | + |
| 113 | +content::MediaStreamDevices |
| 114 | +MediaStreamDevicesController::GetVideoDevices() const { |
| 115 | + if (!has_video_) |
| 116 | + return content::MediaStreamDevices(); |
| 117 | + |
| 118 | + content::MediaStreamDeviceMap::const_iterator it = |
| 119 | + request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
| 120 | + DCHECK(it != request_.devices.end()); |
| 121 | + return it->second; |
| 122 | +} |
| 123 | + |
| 124 | +void MediaStreamDevicesController::Accept(const std::string& audio_id, |
| 125 | + const std::string& video_id, |
| 126 | + bool always_allow) { |
| 127 | + content::MediaStreamDevices devices; |
| 128 | + std::string audio_device, video_device; |
| 129 | + if (has_audio_) { |
| 130 | + AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, |
| 131 | + audio_id, &devices, &audio_device); |
| 132 | + } |
| 133 | + if (has_video_) { |
| 134 | + AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, |
| 135 | + video_id, &devices, &video_device); |
| 136 | + } |
| 137 | + DCHECK(!devices.empty()); |
| 138 | + |
| 139 | + callback_.Run(devices); |
| 140 | +} |
| 141 | + |
| 142 | +void MediaStreamDevicesController::Deny() { |
| 143 | + callback_.Run(content::MediaStreamDevices()); |
| 144 | +} |
| 145 | + |
| 146 | +void MediaStreamDevicesController::AddDeviceWithId( |
| 147 | + content::MediaStreamDeviceType type, |
| 148 | + const std::string& id, |
| 149 | + content::MediaStreamDevices* devices, |
| 150 | + std::string* device_name) { |
| 151 | + DCHECK(devices); |
| 152 | + content::MediaStreamDeviceMap::const_iterator device_it = |
| 153 | + request_.devices.find(type); |
| 154 | + if (device_it == request_.devices.end()) |
| 155 | + return; |
| 156 | + |
| 157 | + content::MediaStreamDevices::const_iterator it = std::find_if( |
| 158 | + device_it->second.begin(), device_it->second.end(), DeviceIdEquals(id)); |
| 159 | + if (it == device_it->second.end()) |
| 160 | + return; |
| 161 | + |
| 162 | + devices->push_back(*it); |
| 163 | + *device_name = it->name; |
| 164 | +} |
| 165 | + |
| 166 | +void MediaStreamDevicesController::GetAlwaysAllowedDevices( |
| 167 | + std::string* audio_id, std::string* video_id) { |
| 168 | + DCHECK(audio_id->empty()); |
| 169 | + DCHECK(video_id->empty()); |
| 170 | + if (has_audio_) { |
| 171 | + *audio_id = |
| 172 | + GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); |
| 173 | + } |
| 174 | + if (has_video_) { |
| 175 | + *video_id = |
| 176 | + GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
| 177 | + } |
| 178 | +} |
| 179 | + |
| 180 | +std::string MediaStreamDevicesController::GetDeviceIdByName( |
| 181 | + content::MediaStreamDeviceType type, |
| 182 | + const std::string& name) { |
| 183 | + content::MediaStreamDeviceMap::const_iterator device_it = |
| 184 | + request_.devices.find(type); |
| 185 | + if (device_it != request_.devices.end()) { |
| 186 | + content::MediaStreamDevices::const_iterator it = std::find_if( |
| 187 | + device_it->second.begin(), device_it->second.end(), |
| 188 | + DeviceNameEquals(name)); |
| 189 | + if (it != device_it->second.end()) |
| 190 | + return it->device_id; |
| 191 | + } |
| 192 | + |
| 193 | + // Device is not available, return an empty string. |
| 194 | + return std::string(); |
| 195 | +} |
| 196 | + |
| 197 | +std::string MediaStreamDevicesController::GetFirstDeviceId( |
| 198 | + content::MediaStreamDeviceType type) { |
| 199 | + content::MediaStreamDeviceMap::const_iterator device_it = |
| 200 | + request_.devices.find(type); |
| 201 | + if (device_it != request_.devices.end()) |
| 202 | + return device_it->second.begin()->device_id; |
| 203 | + |
| 204 | + return std::string(); |
| 205 | +} |
0 commit comments