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

Side by Side Diff: content/browser/renderer_host/media/media_stream_manager.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 "content/browser/renderer_host/media/media_stream_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 29 matching lines...) Expand all
40 for (size_t i = 0; i < label.size(); ++i) { 40 for (size_t i = 0; i < label.size(); ++i) {
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); 41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1);
42 label[i] = kAlphabet[random_char]; 42 label[i] = kAlphabet[random_char];
43 } 43 }
44 return label; 44 return label;
45 } 45 }
46 46
47 // Helper to verify if a media stream type is part of options or not. 47 // Helper to verify if a media stream type is part of options or not.
48 static bool Requested(const StreamOptions& options, 48 static bool Requested(const StreamOptions& options,
49 MediaStreamType stream_type) { 49 MediaStreamType stream_type) {
50 return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && 50 return (options.audio_type == stream_type ||
51 options.video) || 51 options.video_type == stream_type);
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE &&
53 options.audio);
54 } 52 }
55 53
56 DeviceThread::DeviceThread(const char* name) 54 DeviceThread::DeviceThread(const char* name)
57 : base::Thread(name) { 55 : base::Thread(name) {
58 } 56 }
59 57
60 DeviceThread::~DeviceThread() { 58 DeviceThread::~DeviceThread() {
61 Stop(); 59 Stop();
62 } 60 }
63 61
(...skipping 19 matching lines...) Expand all
83 }; 81 };
84 82
85 enum RequestType { 83 enum RequestType {
86 GENERATE_STREAM = 0, 84 GENERATE_STREAM = 0,
87 ENUMERATE_DEVICES, 85 ENUMERATE_DEVICES,
88 OPEN_DEVICE 86 OPEN_DEVICE
89 }; 87 };
90 88
91 DeviceRequest() 89 DeviceRequest()
92 : requester(NULL), 90 : requester(NULL),
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 91 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
94 type(GENERATE_STREAM), 92 type(GENERATE_STREAM),
95 render_process_id(-1), 93 render_process_id(-1),
96 render_view_id(-1) { 94 render_view_id(-1) {
97 options.audio = false;
98 options.video = false;
99 } 95 }
100 96
101 DeviceRequest(MediaStreamRequester* requester, 97 DeviceRequest(MediaStreamRequester* requester,
102 const StreamOptions& request_options, 98 const StreamOptions& request_options,
103 int render_process_id, 99 int render_process_id,
104 int render_view_id, 100 int render_view_id,
105 const GURL& request_security_origin) 101 const GURL& request_security_origin)
106 : requester(requester), 102 : requester(requester),
107 options(request_options), 103 options(request_options),
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 104 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
109 type(GENERATE_STREAM), 105 type(GENERATE_STREAM),
110 render_process_id(render_process_id), 106 render_process_id(render_process_id),
111 render_view_id(render_view_id), 107 render_view_id(render_view_id),
112 security_origin(request_security_origin) { 108 security_origin(request_security_origin) {
113 DCHECK(requester); 109 DCHECK(requester);
114 } 110 }
115 111
116 ~DeviceRequest() {} 112 ~DeviceRequest() {}
117 113
118 MediaStreamRequester* requester; 114 MediaStreamRequester* requester;
119 StreamOptions options; 115 StreamOptions options;
120 std::vector<RequestState> state; 116 std::vector<RequestState> state;
121 RequestType type; 117 RequestType type;
122 int render_process_id; 118 int render_process_id;
123 int render_view_id; 119 int render_view_id;
124 GURL security_origin; 120 GURL security_origin;
125 std::string requested_device_id; 121 std::string requested_device_id;
126 StreamDeviceInfoArray audio_devices; 122 StreamDeviceInfoArray devices;
127 StreamDeviceInfoArray video_devices;
128 }; 123 };
129 124
130 MediaStreamManager::EnumerationCache::EnumerationCache() 125 MediaStreamManager::EnumerationCache::EnumerationCache()
131 : valid(false) { 126 : valid(false) {
132 } 127 }
133 128
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { 129 MediaStreamManager::EnumerationCache::~EnumerationCache() {
135 } 130 }
136 131
137 bool MediaStreamManager::always_use_fake_devices_ = false; 132 bool MediaStreamManager::always_use_fake_devices_ = false;
138 133
139 // static 134 // static
140 void MediaStreamManager::AlwaysUseFakeDevice() { 135 void MediaStreamManager::AlwaysUseFakeDevice() {
141 always_use_fake_devices_ = true; 136 always_use_fake_devices_ = true;
142 } 137 }
143 138
144 MediaStreamManager::MediaStreamManager( 139 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
145 AudioInputDeviceManager* audio_input_device_manager,
146 VideoCaptureManager* video_capture_manager)
147 : ALLOW_THIS_IN_INITIALIZER_LIST( 140 : ALLOW_THIS_IN_INITIALIZER_LIST(
148 device_settings_(new MediaStreamDeviceSettings(this))), 141 device_settings_(new MediaStreamDeviceSettings(this))),
149 audio_input_device_manager_(audio_input_device_manager), 142 audio_manager_(audio_manager),
150 video_capture_manager_(video_capture_manager),
151 monitoring_started_(false), 143 monitoring_started_(false),
152 io_loop_(NULL) { 144 io_loop_(NULL) {
145 DCHECK(audio_manager_);
153 memset(active_enumeration_ref_count_, 0, 146 memset(active_enumeration_ref_count_, 0,
154 sizeof(active_enumeration_ref_count_)); 147 sizeof(active_enumeration_ref_count_));
155 } 148 }
156 149
157 MediaStreamManager::~MediaStreamManager() { 150 MediaStreamManager::~MediaStreamManager() {
158 DCHECK(requests_.empty()); 151 DCHECK(requests_.empty());
159 DCHECK(!device_thread_.get()); 152 DCHECK(!device_thread_.get());
160 DCHECK(!io_loop_); 153 DCHECK(!io_loop_);
161 } 154 }
162 155
163 VideoCaptureManager* MediaStreamManager::video_capture_manager() { 156 VideoCaptureManager* MediaStreamManager::video_capture_manager() {
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 EnsureDeviceManagersStarted();
165 DCHECK(video_capture_manager_); 159 DCHECK(video_capture_manager_);
166 EnsureDeviceThreadAndListener();
167 return video_capture_manager_; 160 return video_capture_manager_;
168 } 161 }
169 162
170 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { 163 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
165 EnsureDeviceManagersStarted();
172 DCHECK(audio_input_device_manager_); 166 DCHECK(audio_input_device_manager_);
173 EnsureDeviceThreadAndListener();
174 return audio_input_device_manager_; 167 return audio_input_device_manager_;
175 } 168 }
176 169
177 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 170 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
178 int render_process_id, 171 int render_process_id,
179 int render_view_id, 172 int render_view_id,
180 const StreamOptions& options, 173 const StreamOptions& options,
181 const GURL& security_origin, 174 const GURL& security_origin,
182 std::string* label) { 175 std::string* label) {
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
184 if (always_use_fake_devices_) 177 if (always_use_fake_devices_)
185 UseFakeDevice(); 178 UseFakeDevice();
186 179
187 // Create a new request based on options. 180 // Create a new request based on options.
188 DeviceRequest new_request(requester, options, 181 DeviceRequest new_request(requester, options,
189 render_process_id, 182 render_process_id,
190 render_view_id, 183 render_view_id,
191 security_origin); 184 security_origin);
192 StartEnumeration(&new_request, label); 185 StartEnumeration(&new_request, label);
193 186
194 // Get user confirmation to use capture devices. 187 // Get user confirmation to use capture devices.
195 device_settings_->RequestCaptureDeviceUsage(*label, 188 device_settings_->RequestCaptureDeviceUsage(*label,
196 render_process_id, 189 render_process_id,
197 render_view_id, 190 render_view_id,
198 options, 191 options,
199 security_origin); 192 security_origin);
200 } 193 }
201 194
195 void MediaStreamManager::GenerateStreamForDevice(
196 MediaStreamRequester* requester, int render_process_id, int render_view_id,
197 const StreamOptions& options, const std::string& device_id,
198 const GURL& security_origin, std::string* label) {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
200
201 // Create a new request based on options.
202 AddRequest(DeviceRequest(requester, options,
203 render_process_id, render_view_id,
204 security_origin),
205 label);
206 DeviceRequest& request = requests_[*label];
207
208 // Get user confirmation to use the capture device.
209 device_settings_->RequestCaptureDeviceUsage(*label,
210 render_process_id,
211 render_view_id,
212 options,
213 security_origin);
214 // TODO(miu): We should ask the device manager whether a device with id
215 // |device_id| actually exists. Note that no such MediaStreamProvider API for
216 // this currently exists. Also, we don't have a user-friendly device name for
217 // the infobar UI.
218 if (content::IsAudioMediaType(options.audio_type)) {
219 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL;
220 device_settings_->AvailableDevices(
221 *label, options.audio_type, StreamDeviceInfoArray(
222 1, StreamDeviceInfo(options.audio_type, device_id, device_id,
223 false)));
224 }
225 if (content::IsVideoMediaType(options.video_type)) {
226 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL;
227 device_settings_->AvailableDevices(
228 *label, options.video_type, StreamDeviceInfoArray(
229 1, StreamDeviceInfo(options.video_type, device_id, device_id,
230 false)));
231 }
232 }
233
202 void MediaStreamManager::CancelGenerateStream(const std::string& label) { 234 void MediaStreamManager::CancelGenerateStream(const std::string& label) {
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
204 236
205 DeviceRequests::iterator it = requests_.find(label); 237 DeviceRequests::iterator it = requests_.find(label);
206 if (it != requests_.end()) { 238 if (it != requests_.end()) {
207 // The request isn't complete. 239 // The request isn't complete.
208 if (!RequestDone(it->second)) { 240 if (!RequestDone(it->second)) {
209 DeviceRequest* request = &(it->second); 241 DeviceRequest& request = it->second;
210 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == 242 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
211 DeviceRequest::STATE_OPENING) { 243 ++i) {
212 for (StreamDeviceInfoArray::iterator it = 244 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
213 request->audio_devices.begin(); it != request->audio_devices.end(); 245 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) {
214 ++it) { 246 continue;
215 audio_input_device_manager()->Close(it->session_id);
216 } 247 }
217 } 248 for (StreamDeviceInfoArray::const_iterator device_it =
218 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == 249 request.devices.begin();
219 DeviceRequest::STATE_OPENING) { 250 device_it != request.devices.end(); ++device_it) {
220 for (StreamDeviceInfoArray::iterator it = 251 if (device_it->stream_type == stream_type) {
221 request->video_devices.begin(); it != request->video_devices.end(); 252 GetDeviceManager(stream_type)->Close(device_it->session_id);
222 ++it) { 253 }
223 video_capture_manager()->Close(it->session_id);
224 } 254 }
225 } 255 }
226 requests_.erase(it); 256 requests_.erase(it);
227 } else { 257 } else {
228 StopGeneratedStream(label); 258 StopGeneratedStream(label);
229 } 259 }
230 device_settings_->RemovePendingCaptureRequest(label); 260 device_settings_->RemovePendingCaptureRequest(label);
231 } 261 }
232 } 262 }
233 263
234 void MediaStreamManager::StopGeneratedStream(const std::string& label) { 264 void MediaStreamManager::StopGeneratedStream(const std::string& label) {
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
236 // Find the request and close all open devices for the request. 266 // Find the request and close all open devices for the request.
237 DeviceRequests::iterator it = requests_.find(label); 267 DeviceRequests::iterator it = requests_.find(label);
238 if (it != requests_.end()) { 268 if (it != requests_.end()) {
239 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { 269 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) {
240 StopEnumerateDevices(label); 270 StopEnumerateDevices(label);
241 return; 271 return;
242 } 272 }
243 for (StreamDeviceInfoArray::iterator audio_it = 273 for (StreamDeviceInfoArray::const_iterator device_it =
244 it->second.audio_devices.begin(); 274 it->second.devices.begin();
245 audio_it != it->second.audio_devices.end(); ++audio_it) { 275 device_it != it->second.devices.end(); ++device_it) {
246 audio_input_device_manager()->Close(audio_it->session_id); 276 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id);
247 }
248 for (StreamDeviceInfoArray::iterator video_it =
249 it->second.video_devices.begin();
250 video_it != it->second.video_devices.end(); ++video_it) {
251 video_capture_manager()->Close(video_it->session_id);
252 } 277 }
253 if (it->second.type == DeviceRequest::GENERATE_STREAM && 278 if (it->second.type == DeviceRequest::GENERATE_STREAM &&
254 RequestDone(it->second)) { 279 RequestDone(it->second)) {
255 NotifyObserverDevicesClosed(&(it->second)); 280 NotifyObserverDevicesClosed(&(it->second));
256 } 281 }
257 requests_.erase(it); 282 requests_.erase(it);
258 } 283 }
259 } 284 }
260 285
261 void MediaStreamManager::EnumerateDevices( 286 void MediaStreamManager::EnumerateDevices(
262 MediaStreamRequester* requester, 287 MediaStreamRequester* requester,
263 int render_process_id, 288 int render_process_id,
264 int render_view_id, 289 int render_view_id,
265 MediaStreamType type, 290 MediaStreamType type,
266 const GURL& security_origin, 291 const GURL& security_origin,
267 std::string* label) { 292 std::string* label) {
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
269 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || 294 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
270 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 295 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
271 296
272 // Create a new request. 297 // Create a new request.
273 StreamOptions options; 298 StreamOptions options;
274 EnumerationCache* cache = NULL; 299 EnumerationCache* cache = NULL;
275 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 300 if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
276 options.audio = true; 301 options.audio_type = type;
277 cache = &audio_enumeration_cache_; 302 cache = &audio_enumeration_cache_;
303 } else if (type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
304 options.video_type = type;
305 cache = &video_enumeration_cache_;
278 } else { 306 } else {
279 options.video = true; 307 NOTREACHED();
280 cache = &video_enumeration_cache_; 308 return;
281 } 309 }
282 310
283 DeviceRequest new_request(requester, options, 311 DeviceRequest new_request(requester, options,
284 render_process_id, 312 render_process_id,
285 render_view_id, 313 render_view_id,
286 security_origin); 314 security_origin);
287 new_request.type = DeviceRequest::ENUMERATE_DEVICES; 315 new_request.type = DeviceRequest::ENUMERATE_DEVICES;
288 316
289 if (cache->valid) { 317 if (cache->valid) {
290 // Cached device list of this type exists. Just send it out. 318 // Cached device list of this type exists. Just send it out.
291 new_request.state[type] = DeviceRequest::STATE_REQUESTED; 319 new_request.state[type] = DeviceRequest::STATE_REQUESTED;
292 AddRequest(&new_request, label); 320 AddRequest(new_request, label);
293 // Need to post a task since the requester won't have label till 321 // Need to post a task since the requester won't have label till
294 // this function returns. 322 // this function returns.
295 BrowserThread::PostTask(BrowserThread::IO, 323 BrowserThread::PostTask(BrowserThread::IO,
296 FROM_HERE, 324 FROM_HERE,
297 base::Bind(&MediaStreamManager::SendCachedDeviceList, 325 base::Bind(&MediaStreamManager::SendCachedDeviceList,
298 base::Unretained(this), cache, *label)); 326 base::Unretained(this), cache, *label));
299 } else { 327 } else {
300 StartEnumeration(&new_request, label); 328 StartEnumeration(&new_request, label);
301 StartMonitoring(); 329 StartMonitoring();
302 } 330 }
(...skipping 14 matching lines...) Expand all
317 345
318 void MediaStreamManager::OpenDevice( 346 void MediaStreamManager::OpenDevice(
319 MediaStreamRequester* requester, 347 MediaStreamRequester* requester,
320 int render_process_id, 348 int render_process_id,
321 int render_view_id, 349 int render_view_id,
322 const std::string& device_id, 350 const std::string& device_id,
323 MediaStreamType type, 351 MediaStreamType type,
324 const GURL& security_origin, 352 const GURL& security_origin,
325 std::string* label) { 353 std::string* label) {
326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
355 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
356 type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
327 357
328 // Create a new request. 358 // Create a new request.
329 StreamOptions options; 359 StreamOptions options;
330 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 360 if (content::IsAudioMediaType(type)) {
331 options.audio = true; 361 options.audio_type = type;
332 else 362 } else if (content::IsVideoMediaType(type)) {
333 options.video = true; 363 options.video_type = type;
364 } else {
365 NOTREACHED();
366 return;
367 }
334 368
335 DeviceRequest new_request(requester, options, 369 DeviceRequest new_request(requester, options,
336 render_process_id, 370 render_process_id,
337 render_view_id, 371 render_view_id,
338 security_origin); 372 security_origin);
339 new_request.type = DeviceRequest::OPEN_DEVICE; 373 new_request.type = DeviceRequest::OPEN_DEVICE;
340 new_request.requested_device_id = device_id; 374 new_request.requested_device_id = device_id;
341 375
342 StartEnumeration(&new_request, label); 376 StartEnumeration(&new_request, label);
343 } 377 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 409 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
376 DCHECK_EQ(MessageLoop::current(), io_loop_); 410 DCHECK_EQ(MessageLoop::current(), io_loop_);
377 cache->valid = false; 411 cache->valid = false;
378 } 412 }
379 413
380 void MediaStreamManager::StartEnumeration( 414 void MediaStreamManager::StartEnumeration(
381 DeviceRequest* new_request, 415 DeviceRequest* new_request,
382 std::string* label) { 416 std::string* label) {
383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
384 418
385 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 419 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
386 if (Requested(new_request->options, stream_type)) { 420 ++i) {
387 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; 421 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
388 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 422 if (Requested(new_request->options, stream_type)) {
389 if (!active_enumeration_ref_count_[stream_type]) { 423 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
390 ++active_enumeration_ref_count_[stream_type]; 424 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
391 GetDeviceManager(stream_type)->EnumerateDevices(); 425 if (active_enumeration_ref_count_[stream_type] == 0) {
392 } 426 ++active_enumeration_ref_count_[stream_type];
393 } 427 GetDeviceManager(stream_type)->EnumerateDevices();
394 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 428 }
395 if (Requested(new_request->options, stream_type)) {
396 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
397 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
398 if (!active_enumeration_ref_count_[stream_type]) {
399 ++active_enumeration_ref_count_[stream_type];
400 GetDeviceManager(stream_type)->EnumerateDevices();
401 } 429 }
402 } 430 }
403 431
404 AddRequest(new_request, label); 432 AddRequest(*new_request, label);
405 } 433 }
406 434
407 void MediaStreamManager::AddRequest( 435 void MediaStreamManager::AddRequest(
408 DeviceRequest* new_request, 436 const DeviceRequest& new_request,
409 std::string* label) { 437 std::string* label) {
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 438 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411 439
412 // Create a label for this request and verify it is unique. 440 // Create a label for this request and verify it is unique.
413 std::string request_label; 441 std::string request_label;
414 do { 442 do {
415 request_label = RandomLabel(); 443 request_label = RandomLabel();
416 } while (requests_.find(request_label) != requests_.end()); 444 } while (requests_.find(request_label) != requests_.end());
417 445
418 requests_.insert(std::make_pair(request_label, *new_request)); 446 requests_.insert(std::make_pair(request_label, new_request));
419 447
420 (*label) = request_label; 448 (*label) = request_label;
421 } 449 }
422 450
423 void MediaStreamManager::EnsureDeviceThreadAndListener() { 451 void MediaStreamManager::EnsureDeviceManagersStarted() {
424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
425 if (device_thread_.get()) 453 if (device_thread_.get())
426 return; 454 return;
427 455
428 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); 456 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread"));
429 CHECK(device_thread_->Start()); 457 CHECK(device_thread_->Start());
430 458
459 audio_input_device_manager_ =
460 new media_stream::AudioInputDeviceManager(audio_manager_);
431 audio_input_device_manager_->Register(this, 461 audio_input_device_manager_->Register(this,
432 device_thread_->message_loop_proxy()); 462 device_thread_->message_loop_proxy());
433 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); 463
464 video_capture_manager_ = new media_stream::VideoCaptureManager();
465 video_capture_manager_->Register(this,
466 device_thread_->message_loop_proxy());
434 467
435 // We want to be notified of IO message loop destruction to delete the thread 468 // We want to be notified of IO message loop destruction to delete the thread
436 // and the device managers. 469 // and the device managers.
437 io_loop_ = MessageLoop::current(); 470 io_loop_ = MessageLoop::current();
438 io_loop_->AddDestructionObserver(this); 471 io_loop_->AddDestructionObserver(this);
439 } 472 }
440 473
441 void MediaStreamManager::Opened(MediaStreamType stream_type, 474 void MediaStreamManager::Opened(MediaStreamType stream_type,
442 int capture_session_id) { 475 int capture_session_id) {
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
444 477
445 // Find the request containing this device and mark it as used. 478 // Find the request containing this device and mark it as used.
446 DeviceRequest* request = NULL; 479 DeviceRequest* request = NULL;
447 StreamDeviceInfoArray* devices = NULL; 480 StreamDeviceInfoArray* devices = NULL;
448 std::string label; 481 std::string label;
449 for (DeviceRequests::iterator request_it = requests_.begin(); 482 for (DeviceRequests::iterator request_it = requests_.begin();
450 request_it != requests_.end() && request == NULL; ++request_it) { 483 request_it != requests_.end() && request == NULL; ++request_it) {
451 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 484 devices = &(request_it->second.devices);
452 devices = &(request_it->second.audio_devices);
453 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
454 devices = &(request_it->second.video_devices);
455 } else {
456 NOTREACHED();
457 }
458
459 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 485 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
460 device_it != devices->end(); ++device_it) { 486 device_it != devices->end(); ++device_it) {
461 if (device_it->session_id == capture_session_id) { 487 if (device_it->stream_type == stream_type &&
488 device_it->session_id == capture_session_id) {
462 // We've found the request. 489 // We've found the request.
463 device_it->in_use = true; 490 device_it->in_use = true;
464 label = request_it->first; 491 label = request_it->first;
465 request = &(request_it->second); 492 request = &(request_it->second);
466 break; 493 break;
467 } 494 }
468 } 495 }
469 } 496 }
470 if (request == NULL) { 497 if (request == NULL) {
471 // The request doesn't exist. 498 // The request doesn't exist.
472 return; 499 return;
473 } 500 }
474 501
475 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); 502 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED);
476 503
477 // Check if all devices for this stream type are opened. Update the state if 504 // Check if all devices for this stream type are opened. Update the state if
478 // they are. 505 // they are.
479 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 506 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
480 device_it != devices->end(); ++device_it) { 507 device_it != devices->end(); ++device_it) {
508 if (device_it->stream_type != stream_type) {
509 continue;
510 }
481 if (device_it->in_use == false) { 511 if (device_it->in_use == false) {
482 // Wait for more devices to be opened before we're done. 512 // Wait for more devices to be opened before we're done.
483 return; 513 return;
484 } 514 }
485 } 515 }
486 request->state[stream_type] = DeviceRequest::STATE_DONE; 516 request->state[stream_type] = DeviceRequest::STATE_DONE;
487 517
488 if (!RequestDone(*request)) { 518 if (!RequestDone(*request)) {
489 // This stream_type is done, but not the other type. 519 // This stream_type is done, but not the other type.
490 return; 520 return;
491 } 521 }
492 522
493 switch (request->type) { 523 switch (request->type) {
494 case DeviceRequest::OPEN_DEVICE: 524 case DeviceRequest::OPEN_DEVICE:
495 request->requester->DeviceOpened(label, (*devices)[0]); 525 request->requester->DeviceOpened(label, devices->front());
496 break; 526 break;
497 case DeviceRequest::GENERATE_STREAM: 527 case DeviceRequest::GENERATE_STREAM: {
498 request->requester->StreamGenerated(label, request->audio_devices, 528 // Partition the array of devices into audio vs video.
499 request->video_devices); 529 StreamDeviceInfoArray audio_devices, video_devices;
530 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin();
531 device_it != devices->end(); ++device_it) {
532 if (content::IsAudioMediaType(device_it->stream_type)) {
533 audio_devices.push_back(*device_it);
534 } else if (content::IsVideoMediaType(device_it->stream_type)) {
535 video_devices.push_back(*device_it);
536 } else {
537 NOTREACHED();
538 }
539 }
540
541 request->requester->StreamGenerated(label, audio_devices, video_devices);
500 NotifyObserverDevicesOpened(request); 542 NotifyObserverDevicesOpened(request);
501 break; 543 break;
544 }
502 default: 545 default:
503 NOTREACHED(); 546 NOTREACHED();
547 break;
504 } 548 }
505 } 549 }
506 550
507 void MediaStreamManager::Closed(MediaStreamType stream_type, 551 void MediaStreamManager::Closed(MediaStreamType stream_type,
508 int capture_session_id) { 552 int capture_session_id) {
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
510 } 554 }
511 555
512 void MediaStreamManager::DevicesEnumerated( 556 void MediaStreamManager::DevicesEnumerated(
513 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 557 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
515 559
516 // Only cache device list when there is EnumerateDevices request, since 560 // Only cache the device list when there is an EnumerateDevices request, since
517 // other requests don't turn on device monitoring. 561 // other requests don't turn on device monitoring.
518 bool need_update_clients = false; 562 bool need_update_clients = false;
519 EnumerationCache* cache = 563 EnumerationCache* cache =
520 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? 564 (stream_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
521 &audio_enumeration_cache_ : &video_enumeration_cache_); 565 &audio_enumeration_cache_ : &video_enumeration_cache_);
522 if (HasEnumerationRequest(stream_type) && 566 if (HasEnumerationRequest(stream_type) &&
523 (!cache->valid || 567 (!cache->valid ||
524 devices.size() != cache->devices.size() || 568 devices.size() != cache->devices.size() ||
525 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 569 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
526 media_stream::StreamDeviceInfo::IsEqual))) { 570 media_stream::StreamDeviceInfo::IsEqual))) {
527 cache->valid = true; 571 cache->valid = true;
528 cache->devices = devices; 572 cache->devices = devices;
529 need_update_clients = true; 573 need_update_clients = true;
530 } 574 }
(...skipping 14 matching lines...) Expand all
545 } 589 }
546 for (std::list<std::string>::iterator it = label_list.begin(); 590 for (std::list<std::string>::iterator it = label_list.begin();
547 it != label_list.end(); ++it) { 591 it != label_list.end(); ++it) {
548 DeviceRequest& request = requests_[*it]; 592 DeviceRequest& request = requests_[*it];
549 switch (request.type) { 593 switch (request.type) {
550 case DeviceRequest::ENUMERATE_DEVICES: 594 case DeviceRequest::ENUMERATE_DEVICES:
551 if (need_update_clients) 595 if (need_update_clients)
552 request.requester->DevicesEnumerated(*it, devices); 596 request.requester->DevicesEnumerated(*it, devices);
553 break; 597 break;
554 case DeviceRequest::OPEN_DEVICE: 598 case DeviceRequest::OPEN_DEVICE:
599 DCHECK(!request.requested_device_id.empty());
555 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 600 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
556 device_it != devices.end(); device_it++) { 601 device_it != devices.end(); ++device_it) {
557 if (request.requested_device_id == device_it->device_id) { 602 if (request.requested_device_id == device_it->device_id) {
558 StreamDeviceInfo device = *device_it; 603 StreamDeviceInfo device = *device_it;
559 device.in_use = false; 604 device.in_use = false;
560 device.session_id = 605 device.session_id =
561 GetDeviceManager(device_it->stream_type)->Open(device); 606 GetDeviceManager(device_it->stream_type)->Open(device);
562 request.state[device_it->stream_type] = 607 request.state[device_it->stream_type] =
563 DeviceRequest::STATE_OPENING; 608 DeviceRequest::STATE_OPENING;
564 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 609 request.devices.push_back(device);
565 request.audio_devices.push_back(device);
566 else
567 request.video_devices.push_back(device);
568 break; 610 break;
569 } 611 }
570 } 612 }
571 break; 613 break;
572 default: 614 default:
573 device_settings_->AvailableDevices(*it, stream_type, devices); 615 device_settings_->AvailableDevices(*it, stream_type, devices);
616 break;
574 } 617 }
575 } 618 }
576 label_list.clear(); 619 label_list.clear();
577 --active_enumeration_ref_count_[stream_type]; 620 --active_enumeration_ref_count_[stream_type];
578 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 621 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
579 } 622 }
580 623
581 void MediaStreamManager::Error(MediaStreamType stream_type, 624 void MediaStreamManager::Error(MediaStreamType stream_type,
582 int capture_session_id, 625 int capture_session_id,
583 MediaStreamProviderError error) { 626 MediaStreamProviderError error) {
584 // Find the device for the error call. 627 // Find the device for the error call.
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
629
586 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 630 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
587 ++it) { 631 ++it) {
588 StreamDeviceInfoArray* devices = NULL; 632 StreamDeviceInfoArray& devices = it->second.devices;
589 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
590 devices = &(it->second.audio_devices);
591 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
592 devices = &(it->second.video_devices);
593 } else {
594 NOTREACHED();
595 }
596 633
597 int device_idx = 0; 634 // TODO(miu): BUG. It's possible for the audio (or video) device array in
598 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 635 // the "requester" to become out-of-sync with the order of devices we have
599 device_it != devices->end(); ++device_it, ++device_idx) { 636 // here. See http://crbug.com/147650
600 if (device_it->session_id == capture_session_id) { 637 int audio_device_idx = -1;
601 // We've found the failing device. Find the error case: 638 int video_device_idx = -1;
602 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { 639 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
603 // 1. Already opened -> signal device failure and close device. 640 device_it != devices.end(); ++device_it) {
604 // Use device_idx to signal which of the devices encountered an 641 if (content::IsAudioMediaType(device_it->stream_type)) {
605 // error. 642 ++audio_device_idx;
606 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 643 } else if (content::IsVideoMediaType(device_it->stream_type)) {
607 it->second.requester->AudioDeviceFailed(it->first, device_idx); 644 ++video_device_idx;
608 } else if (stream_type == 645 } else {
609 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 646 NOTREACHED();
610 it->second.requester->VideoDeviceFailed(it->first, device_idx); 647 continue;
611 } 648 }
612 GetDeviceManager(stream_type)->Close(capture_session_id); 649 if (device_it->stream_type != stream_type ||
613 // We don't erase the devices here so that we can update the UI 650 device_it->session_id != capture_session_id) {
614 // properly in StopGeneratedStream(). 651 continue;
615 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; 652 }
653 // We've found the failing device. Find the error case:
654 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) {
655 // 1. Already opened -> signal device failure and close device.
656 // Use device_idx to signal which of the devices encountered an
657 // error.
658 if (content::IsAudioMediaType(stream_type)) {
659 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx);
660 } else if (content::IsVideoMediaType(stream_type)) {
661 it->second.requester->VideoDeviceFailed(it->first, video_device_idx);
616 } else { 662 } else {
617 // Request is not done, devices are not opened in this case. 663 NOTREACHED();
618 if ((it->second.audio_devices.size() + 664 return;
619 it->second.video_devices.size()) <= 1) {
620 // 2. Device not opened and no other devices for this request ->
621 // signal stream error and remove the request.
622 it->second.requester->StreamGenerationFailed(it->first);
623 requests_.erase(it);
624 } else {
625 // 3. Not opened but other devices exists for this request -> remove
626 // device from list, but don't signal an error.
627 devices->erase(device_it);
628 }
629 } 665 }
630 return; 666 GetDeviceManager(stream_type)->Close(capture_session_id);
667 // We don't erase the devices here so that we can update the UI
668 // properly in StopGeneratedStream().
669 it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
670 } else {
671 // Request is not done, devices are not opened in this case.
672 if (devices.size() <= 1) {
673 // 2. Device not opened and no other devices for this request ->
674 // signal stream error and remove the request.
675 it->second.requester->StreamGenerationFailed(it->first);
676 requests_.erase(it);
677 } else {
678 // 3. Not opened but other devices exists for this request -> remove
679 // device from list, but don't signal an error.
680 devices.erase(device_it); // NOTE: This invalidates device_it!
681 }
631 } 682 }
683 return;
632 } 684 }
633 } 685 }
634 } 686 }
635 687
636 void MediaStreamManager::DevicesAccepted(const std::string& label, 688 void MediaStreamManager::DevicesAccepted(const std::string& label,
637 const StreamDeviceInfoArray& devices) { 689 const StreamDeviceInfoArray& devices) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
639 DeviceRequests::iterator request_it = requests_.find(label); 691 DeviceRequests::iterator request_it = requests_.find(label);
640 if (request_it != requests_.end()) { 692 if (request_it == requests_.end()) {
641 if (devices.empty()) { 693 return;
642 // No available devices or user didn't accept device usage. 694 }
643 request_it->second.requester->StreamGenerationFailed(request_it->first); 695
644 requests_.erase(request_it); 696 DeviceRequest& request = request_it->second;
645 return; 697
698 if (devices.empty()) {
699 // No available devices or user didn't accept device usage.
700 request.requester->StreamGenerationFailed(request_it->first);
701 requests_.erase(request_it);
702 return;
703 }
704
705 // Process all newly-accepted devices for this request.
706 bool found_audio = false, found_video = false;
707 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
708 device_it != devices.end(); ++device_it) {
709 StreamDeviceInfo device_info = *device_it; // Make a copy.
710
711 // Set in_use to false to be able to track if this device has been
712 // opened. in_use might be true if the device type can be used in more
713 // than one session.
714 DCHECK_EQ(request.state[device_it->stream_type],
715 DeviceRequest::STATE_PENDING_APPROVAL);
716 device_info.in_use = false;
717 device_info.session_id =
718 GetDeviceManager(device_info.stream_type)->Open(device_info);
719 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING;
720 request.devices.push_back(device_info);
721
722 if (device_info.stream_type == request.options.audio_type) {
723 found_audio = true;
724 } else if (device_info.stream_type == request.options.video_type) {
725 found_video = true;
646 } 726 }
727 }
647 728
648 // Loop through all device types for this request. 729 // Check whether we've received all stream types requested.
649 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 730 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) {
650 device_it != devices.end(); ++device_it) { 731 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR;
651 StreamDeviceInfo device_info = *device_it; 732 }
652 733 if (!found_video && content::IsVideoMediaType(request.options.video_type)) {
653 // Set in_use to false to be able to track if this device has been 734 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR;
654 // opened. in_use might be true if the device type can be used in more
655 // than one session.
656 DCHECK_EQ(request_it->second.state[device_it->stream_type],
657 DeviceRequest::STATE_PENDING_APPROVAL);
658 device_info.in_use = false;
659 device_info.session_id =
660 GetDeviceManager(device_info.stream_type)->Open(device_info);
661 request_it->second.state[device_it->stream_type] =
662 DeviceRequest::STATE_OPENING;
663 if (device_info.stream_type ==
664 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
665 request_it->second.audio_devices.push_back(device_info);
666 } else if (device_info.stream_type ==
667 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
668 request_it->second.video_devices.push_back(device_info);
669 } else {
670 NOTREACHED();
671 }
672 }
673 // Check if we received all stream types requested.
674 MediaStreamType stream_type =
675 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
676 if (Requested(request_it->second.options, stream_type) &&
677 request_it->second.audio_devices.size() == 0) {
678 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
679 }
680 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
681 if (Requested(request_it->second.options, stream_type) &&
682 request_it->second.video_devices.size() == 0) {
683 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
684 }
685 return;
686 } 735 }
687 } 736 }
688 737
689 void MediaStreamManager::SettingsError(const std::string& label) { 738 void MediaStreamManager::SettingsError(const std::string& label) {
690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
691 // Erase this request and report an error. 740 // Erase this request and report an error.
692 DeviceRequests::iterator it = requests_.find(label); 741 DeviceRequests::iterator it = requests_.find(label);
693 if (it != requests_.end()) { 742 if (it != requests_.end()) {
694 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); 743 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM);
695 it->second.requester->StreamGenerationFailed(label); 744 it->second.requester->StreamGenerationFailed(label);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 DevicesFromRequest(request, &closed_devices); 792 DevicesFromRequest(request, &closed_devices);
744 if (closed_devices.empty()) 793 if (closed_devices.empty())
745 return; 794 return;
746 media_observer->OnCaptureDevicesClosed(request->render_process_id, 795 media_observer->OnCaptureDevicesClosed(request->render_process_id,
747 request->render_view_id, 796 request->render_view_id,
748 closed_devices); 797 closed_devices);
749 } 798 }
750 799
751 void MediaStreamManager::DevicesFromRequest( 800 void MediaStreamManager::DevicesFromRequest(
752 DeviceRequest* request, content::MediaStreamDevices* devices) { 801 DeviceRequest* request, content::MediaStreamDevices* devices) {
753 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); 802 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin();
754 for (; it != request->audio_devices.end(); ++it) { 803 it != request->devices.end(); ++it) {
755 devices->push_back( 804 devices->push_back(content::MediaStreamDevice(
756 content::MediaStreamDevice( 805 it->stream_type, it->device_id, it->name));
757 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
758 it->device_id,
759 it->name));
760 }
761 for (it = request->video_devices.begin(); it != request->video_devices.end();
762 ++it) {
763 devices->push_back(
764 content::MediaStreamDevice(
765 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
766 it->device_id,
767 it->name));
768 } 806 }
769 } 807 }
770 808
771 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 809 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
772 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
773 // Check if all devices are opened.
774 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
775 if (Requested(request.options, stream_type)) {
776 if (request.state[stream_type] != DeviceRequest::STATE_DONE &&
777 request.state[stream_type] != DeviceRequest::STATE_ERROR) {
778 return false;
779 }
780 811
781 for (StreamDeviceInfoArray::const_iterator it = 812 const bool requested_audio =
782 request.audio_devices.begin(); it != request.audio_devices.end(); 813 content::IsAudioMediaType(request.options.audio_type);
783 ++it) { 814 const bool requested_video =
784 if (it->in_use == false) { 815 content::IsVideoMediaType(request.options.video_type);
785 return false; 816
786 } 817 const bool audio_done =
787 } 818 !requested_audio ||
819 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE ||
820 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR;
821 if (!audio_done) {
822 return false;
788 } 823 }
789 824
790 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 825 const bool video_done =
791 if (Requested(request.options, stream_type)) { 826 !requested_video ||
792 if (request.state[stream_type] != DeviceRequest::STATE_DONE && 827 request.state[request.options.video_type] == DeviceRequest::STATE_DONE ||
793 request.state[stream_type] != DeviceRequest::STATE_ERROR) { 828 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR;
829 if (!video_done) {
830 return false;
831 }
832
833 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
834 it != request.devices.end(); ++it) {
835 if (it->in_use == false) {
794 return false; 836 return false;
795 } 837 }
796
797 for (StreamDeviceInfoArray::const_iterator it =
798 request.video_devices.begin(); it != request.video_devices.end();
799 ++it) {
800 if (it->in_use == false) {
801 return false;
802 }
803 }
804 } 838 }
805 839
806 return true; 840 return true;
807 } 841 }
808 842
809 // Called to get media capture device manager of specified type.
810 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 843 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
811 MediaStreamType stream_type) { 844 MediaStreamType stream_type) {
812 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 845 if (content::IsVideoMediaType(stream_type)) {
813 return video_capture_manager(); 846 return video_capture_manager();
814 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 847 } else if (content::IsAudioMediaType(stream_type)) {
815 return audio_input_device_manager(); 848 return audio_input_device_manager();
816 } 849 }
817 NOTREACHED(); 850 NOTREACHED();
818 return NULL; 851 return NULL;
819 } 852 }
820 853
821 void MediaStreamManager::OnDevicesChanged( 854 void MediaStreamManager::OnDevicesChanged(
822 base::SystemMonitor::DeviceType device_type) { 855 base::SystemMonitor::DeviceType device_type) {
823 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 856 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
857
858 // NOTE: This method is only called in response to physical audio/video device
859 // changes (from the operating system).
860
824 MediaStreamType stream_type; 861 MediaStreamType stream_type;
825 EnumerationCache* cache; 862 EnumerationCache* cache;
826 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 863 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
827 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 864 stream_type = content::MEDIA_DEVICE_AUDIO_CAPTURE;
828 cache = &audio_enumeration_cache_; 865 cache = &audio_enumeration_cache_;
829 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 866 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
830 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 867 stream_type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
831 cache = &video_enumeration_cache_; 868 cache = &video_enumeration_cache_;
832 } else { 869 } else {
833 return; // Uninteresting device change. 870 return; // Uninteresting device change.
834 } 871 }
835 872
836 if (!HasEnumerationRequest(stream_type)) { 873 if (!HasEnumerationRequest(stream_type)) {
837 // There is no request for that type, No need to enumerate devices. 874 // There is no request for that type, No need to enumerate devices.
838 // Therefore, invalidate the cache of that type. 875 // Therefore, invalidate the cache of that type.
839 ClearEnumerationCache(cache); 876 ClearEnumerationCache(cache);
840 return; 877 return;
(...skipping 24 matching lines...) Expand all
865 it != requests_.end(); ++it) { 902 it != requests_.end(); ++it) {
866 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && 903 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES &&
867 Requested(it->second.options, stream_type)) { 904 Requested(it->second.options, stream_type)) {
868 return true; 905 return true;
869 } 906 }
870 } 907 }
871 return false; 908 return false;
872 } 909 }
873 910
874 } // namespace media_stream 911 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698