Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: chrome/browser/media/media_stream_devices_controller.cc

Issue 10912004: Begin adding support for tab mirroring via the MediaStream audio/video capturing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: REBASE Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media/media_stream_devices_controller.h" 5 #include "chrome/browser/media/media_stream_devices_controller.h"
6 6
7 #include "base/values.h" 7 #include "base/values.h"
8 #include "chrome/browser/content_settings/content_settings_provider.h" 8 #include "chrome/browser/content_settings/content_settings_provider.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h" 9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/prefs/scoped_user_pref_update.h" 10 #include "chrome/browser/prefs/scoped_user_pref_update.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/common/content_settings.h" 13 #include "chrome/common/content_settings.h"
14 #include "chrome/common/pref_names.h" 14 #include "chrome/common/pref_names.h"
15 #include "content/public/common/media_stream_request.h"
15 16
16 using content::BrowserThread; 17 using content::BrowserThread;
17 18
18 namespace { 19 namespace {
19 20
20 // A predicate that checks if a StreamDeviceInfo object has the same ID as the
21 // device ID specified at construction.
22 class DeviceIdEquals {
23 public:
24 explicit DeviceIdEquals(const std::string& device_id)
25 : device_id_(device_id) {
26 }
27
28 bool operator() (const content::MediaStreamDevice& device) {
29 return device.device_id == device_id_;
30 }
31
32 private:
33 std::string device_id_;
34 };
35
36 // A predicate that checks if a StreamDeviceInfo object has the same device 21 // A predicate that checks if a StreamDeviceInfo object has the same device
37 // name as the device name specified at construction. 22 // name as the device name specified at construction.
38 class DeviceNameEquals { 23 class DeviceNameEquals {
39 public: 24 public:
40 explicit DeviceNameEquals(const std::string& device_name) 25 explicit DeviceNameEquals(const std::string& device_name)
41 : device_name_(device_name) { 26 : device_name_(device_name) {
42 } 27 }
43 28
44 bool operator() (const content::MediaStreamDevice& device) { 29 bool operator() (const content::MediaStreamDevice& device) {
45 return device.name == device_name_; 30 return device.name == device_name_;
46 } 31 }
47 32
48 private: 33 private:
49 std::string device_name_; 34 std::string device_name_;
50 }; 35 };
51 36
52 // Whether |request| contains any device of given |type|.
53 bool HasDevice(const content::MediaStreamRequest& request,
54 content::MediaStreamDeviceType type) {
55 content::MediaStreamDeviceMap::const_iterator device_it =
56 request.devices.find(type);
57 return device_it != request.devices.end() && !device_it->second.empty();
58 }
59
60 const char kAudioKey[] = "audio"; 37 const char kAudioKey[] = "audio";
61 const char kVideoKey[] = "video"; 38 const char kVideoKey[] = "video";
62 39
63 } // namespace 40 } // namespace
64 41
65 MediaStreamDevicesController::MediaStreamDevicesController( 42 MediaStreamDevicesController::MediaStreamDevicesController(
66 Profile* profile, 43 Profile* profile,
67 const content::MediaStreamRequest* request, 44 const content::MediaStreamRequest* request,
68 const content::MediaResponseCallback& callback) 45 const content::MediaResponseCallback& callback)
69 : profile_(profile), 46 : has_audio_(false),
47 has_video_(false),
48 profile_(profile),
70 request_(*request), 49 request_(*request),
71 callback_(callback) { 50 callback_(callback) {
72 has_audio_ = 51 for (content::MediaStreamDeviceMap::const_iterator it =
73 HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); 52 request_.devices.begin();
74 has_video_ = 53 it != request_.devices.end(); ++it) {
75 HasDevice(request_, content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 54 if (content::IsAudioMediaType(it->first)) {
55 has_audio_ |= !it->second.empty();
56 } else if (content::IsVideoMediaType(it->first)) {
57 has_video_ |= !it->second.empty();
58 }
59 }
76 } 60 }
77 61
78 MediaStreamDevicesController::~MediaStreamDevicesController() {} 62 MediaStreamDevicesController::~MediaStreamDevicesController() {}
79 63
80 bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { 64 bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
81 // Deny the request if the security origin is empty, this happens with 65 // Deny the request if the security origin is empty, this happens with
82 // file access without |--allow-file-access-from-files| flag. 66 // file access without |--allow-file-access-from-files| flag.
83 if (request_.security_origin.is_empty()) { 67 if (request_.security_origin.is_empty()) {
84 Deny(); 68 Deny();
85 return true; 69 return true;
(...skipping 25 matching lines...) Expand all
111 return false; 95 return false;
112 } 96 }
113 97
114 // Dismiss the infobar by selecting the "always allowed" devices. 98 // Dismiss the infobar by selecting the "always allowed" devices.
115 Accept(audio, video, false); 99 Accept(audio, video, false);
116 return true; 100 return true;
117 } 101 }
118 102
119 content::MediaStreamDevices 103 content::MediaStreamDevices
120 MediaStreamDevicesController::GetAudioDevices() const { 104 MediaStreamDevicesController::GetAudioDevices() const {
121 if (!has_audio_) 105 content::MediaStreamDevices all_audio_devices;
122 return content::MediaStreamDevices(); 106 if (has_audio_)
123 107 FindSubsetOfDevices(&content::IsAudioMediaType, &all_audio_devices);
124 content::MediaStreamDeviceMap::const_iterator it = 108 return all_audio_devices;
125 request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
126 DCHECK(it != request_.devices.end());
127 return it->second;
128 } 109 }
129 110
130 content::MediaStreamDevices 111 content::MediaStreamDevices
131 MediaStreamDevicesController::GetVideoDevices() const { 112 MediaStreamDevicesController::GetVideoDevices() const {
132 if (!has_video_) 113 content::MediaStreamDevices all_video_devices;
133 return content::MediaStreamDevices(); 114 if (has_video_)
134 115 FindSubsetOfDevices(&content::IsVideoMediaType, &all_video_devices);
135 content::MediaStreamDeviceMap::const_iterator it = 116 return all_video_devices;
136 request_.devices.find(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
137 DCHECK(it != request_.devices.end());
138 return it->second;
139 } 117 }
140 118
141 const GURL& MediaStreamDevicesController::GetSecurityOrigin() const { 119 const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
142 return request_.security_origin; 120 return request_.security_origin.spec();
121 }
122
123 bool MediaStreamDevicesController::IsSafeToAlwaysAllowAudio() const {
124 return IsSafeToAlwaysAllow(
125 &content::IsAudioMediaType, content::MEDIA_DEVICE_AUDIO_CAPTURE);
126 }
127
128 bool MediaStreamDevicesController::IsSafeToAlwaysAllowVideo() const {
129 return IsSafeToAlwaysAllow(
130 &content::IsVideoMediaType, content::MEDIA_DEVICE_VIDEO_CAPTURE);
143 } 131 }
144 132
145 void MediaStreamDevicesController::Accept(const std::string& audio_id, 133 void MediaStreamDevicesController::Accept(const std::string& audio_id,
146 const std::string& video_id, 134 const std::string& video_id,
147 bool always_allow) { 135 bool always_allow) {
148 content::MediaStreamDevices devices; 136 content::MediaStreamDevices devices;
149 std::string audio_device, video_device; 137 std::string audio_device_name, video_device_name;
150 if (has_audio_) { 138
151 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, 139 const content::MediaStreamDevice* const audio_device =
152 audio_id, &devices, &audio_device); 140 FindFirstDeviceWithIdInSubset(&content::IsAudioMediaType, audio_id);
141 if (audio_device) {
142 if (audio_device->type != content::MEDIA_DEVICE_AUDIO_CAPTURE)
143 always_allow = false; // Override for virtual audio device type.
144 devices.push_back(*audio_device);
145 audio_device_name = audio_device->name;
153 } 146 }
154 if (has_video_) { 147
155 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, 148 const content::MediaStreamDevice* const video_device =
156 video_id, &devices, &video_device); 149 FindFirstDeviceWithIdInSubset(&content::IsVideoMediaType, video_id);
150 if (video_device) {
151 if (video_device->type != content::MEDIA_DEVICE_VIDEO_CAPTURE)
152 always_allow = false; // Override for virtual video device type.
153 devices.push_back(*video_device);
154 video_device_name = video_device->name;
157 } 155 }
156
158 DCHECK(!devices.empty()); 157 DCHECK(!devices.empty());
159 158
160 if (always_allow) 159 if (always_allow)
161 AlwaysAllowOriginAndDevices(audio_device, video_device); 160 AlwaysAllowOriginAndDevices(audio_device_name, video_device_name);
162 161
163 callback_.Run(devices); 162 callback_.Run(devices);
164 } 163 }
165 164
166 void MediaStreamDevicesController::Deny() { 165 void MediaStreamDevicesController::Deny() {
167 callback_.Run(content::MediaStreamDevices()); 166 callback_.Run(content::MediaStreamDevices());
168 } 167 }
169 168
170 void MediaStreamDevicesController::AddDeviceWithId( 169 bool MediaStreamDevicesController::IsSafeToAlwaysAllow(
171 content::MediaStreamDeviceType type, 170 FilterByDeviceTypeFunc is_included,
172 const std::string& id, 171 content::MediaStreamDeviceType device_type) const {
173 content::MediaStreamDevices* devices, 172 DCHECK(device_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
174 std::string* device_name) { 173 device_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
175 DCHECK(devices);
176 content::MediaStreamDeviceMap::const_iterator device_it =
177 request_.devices.find(type);
178 if (device_it == request_.devices.end())
179 return;
180 174
181 content::MediaStreamDevices::const_iterator it = std::find_if( 175 if (!request_.security_origin.SchemeIsSecure())
182 device_it->second.begin(), device_it->second.end(), DeviceIdEquals(id)); 176 return false;
183 if (it == device_it->second.end())
184 return;
185 177
186 devices->push_back(*it); 178 // If non-physical devices are available for the choosing, then it's not safe.
187 *device_name = it->name; 179 bool safe_devices_found = false;
180 for (content::MediaStreamDeviceMap::const_iterator it =
181 request_.devices.begin();
182 it != request_.devices.end(); ++it) {
183 if (it->first != device_type && is_included(it->first))
184 return false;
185 safe_devices_found = true;
186 }
187
188 return safe_devices_found;
188 } 189 }
189 190
190 bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() { 191 bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() {
191 return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent( 192 return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
192 request_.security_origin, request_.security_origin, 193 request_.security_origin, request_.security_origin,
193 CONTENT_SETTINGS_TYPE_MEDIASTREAM); 194 CONTENT_SETTINGS_TYPE_MEDIASTREAM);
194 } 195 }
195 196
196 bool MediaStreamDevicesController::IsMediaDeviceBlocked() { 197 bool MediaStreamDevicesController::IsMediaDeviceBlocked() {
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 26 matching lines...) Expand all
224 } 225 }
225 226
226 void MediaStreamDevicesController::GetAlwaysAllowedDevices( 227 void MediaStreamDevicesController::GetAlwaysAllowedDevices(
227 std::string* audio_id, std::string* video_id) { 228 std::string* audio_id, std::string* video_id) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 DCHECK(audio_id->empty()); 230 DCHECK(audio_id->empty());
230 DCHECK(video_id->empty()); 231 DCHECK(video_id->empty());
231 // If the request is from internal objects like chrome://URLs, use the first 232 // If the request is from internal objects like chrome://URLs, use the first
232 // devices on the lists. 233 // devices on the lists.
233 if (ShouldAlwaysAllowOrigin()) { 234 if (ShouldAlwaysAllowOrigin()) {
234 if (has_audio_) { 235 if (has_audio_)
235 *audio_id = 236 *audio_id = GetFirstDeviceId(content::MEDIA_DEVICE_AUDIO_CAPTURE);
236 GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE); 237 if (has_video_)
237 } 238 *video_id = GetFirstDeviceId(content::MEDIA_DEVICE_VIDEO_CAPTURE);
238 if (has_video_) {
239 *video_id =
240 GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
241 }
242 return; 239 return;
243 } 240 }
244 241
245 // "Always allowed" option is only available for secure connection. 242 // "Always allowed" option is only available for secure connection.
246 if (!request_.security_origin.SchemeIsSecure()) 243 if (!request_.security_origin.SchemeIsSecure())
247 return; 244 return;
248 245
249 // Checks the media exceptions to get the "always allowed" devices. 246 // Checks the media exceptions to get the "always allowed" devices.
250 scoped_ptr<Value> value( 247 scoped_ptr<Value> value(
251 profile_->GetHostContentSettingsMap()->GetWebsiteSetting( 248 profile_->GetHostContentSettingsMap()->GetWebsiteSetting(
252 request_.security_origin, 249 request_.security_origin,
253 request_.security_origin, 250 request_.security_origin,
254 CONTENT_SETTINGS_TYPE_MEDIASTREAM, 251 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
255 NO_RESOURCE_IDENTIFIER, 252 NO_RESOURCE_IDENTIFIER,
256 NULL)); 253 NULL));
257 if (!value.get()) { 254 if (!value.get()) {
258 NOTREACHED(); 255 NOTREACHED();
259 return; 256 return;
260 } 257 }
261 258
262 const DictionaryValue* value_dict = NULL; 259 const DictionaryValue* value_dict = NULL;
263 if (!value->GetAsDictionary(&value_dict) || value_dict->empty()) 260 if (!value->GetAsDictionary(&value_dict) || value_dict->empty())
264 return; 261 return;
265 262
266 std::string audio_name, video_name; 263 std::string audio_name, video_name;
267 value_dict->GetString(kAudioKey, &audio_name); 264 value_dict->GetString(kAudioKey, &audio_name);
268 value_dict->GetString(kVideoKey, &video_name); 265 value_dict->GetString(kVideoKey, &video_name);
269 266
270 if (has_audio_ && !audio_name.empty()) { 267 if (has_audio_ && !audio_name.empty())
271 *audio_id = GetDeviceIdByName( 268 *audio_id = GetDeviceIdByName(content::MEDIA_DEVICE_AUDIO_CAPTURE,
272 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, audio_name); 269 audio_name);
273 } 270 if (has_video_ && !video_name.empty())
274 if (has_video_ && !video_name.empty()) { 271 *video_id = GetDeviceIdByName(content::MEDIA_DEVICE_VIDEO_CAPTURE,
275 *video_id = GetDeviceIdByName( 272 video_name);
276 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, video_name);
277 }
278 } 273 }
279 274
280 std::string MediaStreamDevicesController::GetDeviceIdByName( 275 std::string MediaStreamDevicesController::GetDeviceIdByName(
281 content::MediaStreamDeviceType type, 276 content::MediaStreamDeviceType type,
282 const std::string& name) { 277 const std::string& name) {
283 content::MediaStreamDeviceMap::const_iterator device_it = 278 content::MediaStreamDeviceMap::const_iterator device_it =
284 request_.devices.find(type); 279 request_.devices.find(type);
285 if (device_it != request_.devices.end()) { 280 if (device_it != request_.devices.end()) {
286 content::MediaStreamDevices::const_iterator it = std::find_if( 281 content::MediaStreamDevices::const_iterator it = std::find_if(
287 device_it->second.begin(), device_it->second.end(), 282 device_it->second.begin(), device_it->second.end(),
288 DeviceNameEquals(name)); 283 DeviceNameEquals(name));
289 if (it != device_it->second.end()) 284 if (it != device_it->second.end())
290 return it->device_id; 285 return it->device_id;
291 } 286 }
292 287
293 // Device is not available, return an empty string. 288 // Device is not available, return an empty string.
294 return std::string(); 289 return std::string();
295 } 290 }
296 291
297 std::string MediaStreamDevicesController::GetFirstDeviceId( 292 std::string MediaStreamDevicesController::GetFirstDeviceId(
298 content::MediaStreamDeviceType type) { 293 content::MediaStreamDeviceType type) {
299 content::MediaStreamDeviceMap::const_iterator device_it = 294 content::MediaStreamDeviceMap::const_iterator device_it =
300 request_.devices.find(type); 295 request_.devices.find(type);
301 if (device_it != request_.devices.end()) 296 if (device_it != request_.devices.end())
302 return device_it->second.begin()->device_id; 297 return device_it->second.begin()->device_id;
303 298
304 return std::string(); 299 return std::string();
305 } 300 }
301
302 void MediaStreamDevicesController::FindSubsetOfDevices(
303 FilterByDeviceTypeFunc is_included,
304 content::MediaStreamDevices* out) const {
305 for (content::MediaStreamDeviceMap::const_iterator it =
306 request_.devices.begin();
307 it != request_.devices.end(); ++it) {
308 if (is_included(it->first))
309 out->insert(out->end(), it->second.begin(), it->second.end());
310 }
311 }
312
313 const content::MediaStreamDevice*
314 MediaStreamDevicesController::FindFirstDeviceWithIdInSubset(
315 FilterByDeviceTypeFunc is_included,
316 const std::string& device_id) const {
317 for (content::MediaStreamDeviceMap::const_iterator it =
318 request_.devices.begin();
319 it != request_.devices.end(); ++it) {
320 if (!is_included(it->first)) continue;
321 for (content::MediaStreamDevices::const_iterator device_it =
322 it->second.begin();
323 device_it != it->second.end(); ++device_it) {
324 const content::MediaStreamDevice& candidate = *device_it;
325 if (candidate.device_id == device_id)
326 return &candidate;
327 }
328 }
329 return NULL;
330 }
OLDNEW
« no previous file with comments | « chrome/browser/media/media_stream_devices_controller.h ('k') | chrome/browser/media/media_stream_devices_menu_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698