OLD | NEW |
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/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "content/public/browser/media_observer.h" | 22 #include "content/public/browser/media_observer.h" |
23 #include "content/public/browser/media_request_state.h" | 23 #include "content/public/browser/media_request_state.h" |
24 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
25 #include "content/public/common/media_stream_request.h" | 25 #include "content/public/common/media_stream_request.h" |
26 #include "googleurl/src/gurl.h" | 26 #include "googleurl/src/gurl.h" |
27 | 27 |
28 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
29 #include "base/win/scoped_com_initializer.h" | 29 #include "base/win/scoped_com_initializer.h" |
30 #endif | 30 #endif |
31 | 31 |
32 using content::BrowserThread; | |
33 using content::MediaStreamRequest; | |
34 | |
35 namespace { | 32 namespace { |
36 const char kExtensionScheme[] = "chrome-extension"; | 33 const char kExtensionScheme[] = "chrome-extension"; |
37 } // namespace | 34 } // namespace |
38 | 35 |
39 namespace media_stream { | 36 namespace content { |
40 | 37 |
41 // Creates a random label used to identify requests. | 38 // Creates a random label used to identify requests. |
42 static std::string RandomLabel() { | 39 static std::string RandomLabel() { |
43 // An earlier PeerConnection spec, | 40 // An earlier PeerConnection spec, |
44 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the | 41 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the |
45 // MediaStream::label alphabet as containing 36 characters from | 42 // MediaStream::label alphabet as containing 36 characters from |
46 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, | 43 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, |
47 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. | 44 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. |
48 // Here we use a safe subset. | 45 // Here we use a safe subset. |
49 static const char kAlphabet[] = "0123456789" | 46 static const char kAlphabet[] = "0123456789" |
(...skipping 22 matching lines...) Expand all Loading... |
72 GENERATE_STREAM, | 69 GENERATE_STREAM, |
73 ENUMERATE_DEVICES, | 70 ENUMERATE_DEVICES, |
74 OPEN_DEVICE | 71 OPEN_DEVICE |
75 }; | 72 }; |
76 | 73 |
77 DeviceRequest() | 74 DeviceRequest() |
78 : requester(NULL), | 75 : requester(NULL), |
79 type(GENERATE_STREAM), | 76 type(GENERATE_STREAM), |
80 render_process_id(-1), | 77 render_process_id(-1), |
81 render_view_id(-1), | 78 render_view_id(-1), |
82 state_(content::NUM_MEDIA_TYPES, | 79 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { |
83 content::MEDIA_REQUEST_STATE_NOT_REQUESTED) { | |
84 } | 80 } |
85 | 81 |
86 DeviceRequest(MediaStreamRequester* requester, | 82 DeviceRequest(MediaStreamRequester* requester, |
87 const StreamOptions& request_options, | 83 const StreamOptions& request_options, |
88 RequestType request_type, | 84 RequestType request_type, |
89 int render_process_id, | 85 int render_process_id, |
90 int render_view_id, | 86 int render_view_id, |
91 const GURL& request_security_origin) | 87 const GURL& request_security_origin) |
92 : requester(requester), | 88 : requester(requester), |
93 options(request_options), | 89 options(request_options), |
94 type(request_type), | 90 type(request_type), |
95 render_process_id(render_process_id), | 91 render_process_id(render_process_id), |
96 render_view_id(render_view_id), | 92 render_view_id(render_view_id), |
97 security_origin(request_security_origin), | 93 security_origin(request_security_origin), |
98 state_(content::NUM_MEDIA_TYPES, | 94 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { |
99 content::MEDIA_REQUEST_STATE_NOT_REQUESTED) { | |
100 } | 95 } |
101 | 96 |
102 ~DeviceRequest() {} | 97 ~DeviceRequest() {} |
103 | 98 |
104 // Update the request state and notify observers. | 99 // Update the request state and notify observers. |
105 void setState(MediaStreamType stream_type, | 100 void setState(MediaStreamType stream_type, MediaRequestState new_state) { |
106 content::MediaRequestState new_state) { | |
107 state_[stream_type] = new_state; | 101 state_[stream_type] = new_state; |
108 | 102 |
109 if (options.video_type != content::MEDIA_TAB_VIDEO_CAPTURE && | 103 if (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
110 options.audio_type != content::MEDIA_TAB_AUDIO_CAPTURE) | 104 options.audio_type != MEDIA_TAB_AUDIO_CAPTURE) |
111 return; | 105 return; |
112 | 106 |
113 content::MediaObserver* media_observer = | 107 MediaObserver* media_observer = |
114 content::GetContentClient()->browser()->GetMediaObserver(); | 108 GetContentClient()->browser()->GetMediaObserver(); |
115 if (media_observer == NULL) | 109 if (media_observer == NULL) |
116 return; | 110 return; |
117 | 111 |
118 media_observer->OnMediaRequestStateChanged( | 112 media_observer->OnMediaRequestStateChanged( |
119 render_process_id, render_view_id, | 113 render_process_id, render_view_id, |
120 content::MediaStreamDevice(stream_type, | 114 MediaStreamDevice( |
121 requested_device_id, | 115 stream_type, requested_device_id, requested_device_id), new_state); |
122 requested_device_id), | |
123 new_state); | |
124 } | 116 } |
125 | 117 |
126 content::MediaRequestState getState(MediaStreamType stream_type) const { | 118 MediaRequestState getState(MediaStreamType stream_type) const { |
127 return state_[stream_type]; | 119 return state_[stream_type]; |
128 } | 120 } |
129 | 121 |
130 MediaStreamRequester* requester; // Can be NULL. | 122 MediaStreamRequester* requester; // Can be NULL. |
131 StreamOptions options; | 123 StreamOptions options; |
132 RequestType type; | 124 RequestType type; |
133 int render_process_id; | 125 int render_process_id; |
134 int render_view_id; | 126 int render_view_id; |
135 GURL security_origin; | 127 GURL security_origin; |
136 std::string requested_device_id; | 128 std::string requested_device_id; |
137 StreamDeviceInfoArray devices; | 129 StreamDeviceInfoArray devices; |
138 | 130 |
139 // Callback to the requester which audio/video devices have been selected. | 131 // Callback to the requester which audio/video devices have been selected. |
140 // It can be null if the requester has no interest to know the result. | 132 // It can be null if the requester has no interest to know the result. |
141 // Currently it is only used by |DEVICE_ACCESS| type. | 133 // Currently it is only used by |DEVICE_ACCESS| type. |
142 media_stream::MediaRequestResponseCallback callback; | 134 MediaRequestResponseCallback callback; |
143 | 135 |
144 private: | 136 private: |
145 std::vector<content::MediaRequestState> state_; | 137 std::vector<MediaRequestState> state_; |
146 }; | 138 }; |
147 | 139 |
148 MediaStreamManager::EnumerationCache::EnumerationCache() | 140 MediaStreamManager::EnumerationCache::EnumerationCache() |
149 : valid(false) { | 141 : valid(false) { |
150 } | 142 } |
151 | 143 |
152 MediaStreamManager::EnumerationCache::~EnumerationCache() { | 144 MediaStreamManager::EnumerationCache::~EnumerationCache() { |
153 } | 145 } |
154 | 146 |
155 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) | 147 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) |
156 : ALLOW_THIS_IN_INITIALIZER_LIST( | 148 : ALLOW_THIS_IN_INITIALIZER_LIST( |
157 ui_controller_(new content::MediaStreamUIController(this))), | 149 ui_controller_(new MediaStreamUIController(this))), |
158 audio_manager_(audio_manager), | 150 audio_manager_(audio_manager), |
159 monitoring_started_(false), | 151 monitoring_started_(false), |
160 io_loop_(NULL) { | 152 io_loop_(NULL) { |
161 DCHECK(audio_manager_); | 153 DCHECK(audio_manager_); |
162 memset(active_enumeration_ref_count_, 0, | 154 memset(active_enumeration_ref_count_, 0, |
163 sizeof(active_enumeration_ref_count_)); | 155 sizeof(active_enumeration_ref_count_)); |
164 } | 156 } |
165 | 157 |
166 MediaStreamManager::~MediaStreamManager() { | 158 MediaStreamManager::~MediaStreamManager() { |
167 DCHECK(requests_.empty()); | 159 DCHECK(requests_.empty()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 render_process_id, render_view_id, | 236 render_process_id, render_view_id, |
245 security_origin), | 237 security_origin), |
246 label); | 238 label); |
247 DeviceRequest& request = requests_[*label]; | 239 DeviceRequest& request = requests_[*label]; |
248 request.requested_device_id = device_id; | 240 request.requested_device_id = device_id; |
249 | 241 |
250 // Get user confirmation to use the capture device. | 242 // Get user confirmation to use the capture device. |
251 PostRequestToUI(*label); | 243 PostRequestToUI(*label); |
252 | 244 |
253 if (!security_origin.SchemeIs(kExtensionScheme) || | 245 if (!security_origin.SchemeIs(kExtensionScheme) || |
254 (options.audio_type != content::MEDIA_TAB_AUDIO_CAPTURE && | 246 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
255 options.audio_type != content::MEDIA_NO_SERVICE) || | 247 options.audio_type != MEDIA_NO_SERVICE) || |
256 (options.video_type != content::MEDIA_TAB_VIDEO_CAPTURE && | 248 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
257 options.video_type != content::MEDIA_NO_SERVICE)) { | 249 options.video_type != MEDIA_NO_SERVICE)) { |
258 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; | 250 LOG(ERROR) << "Invalid request or used tab capture outside extension API."; |
259 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 251 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
260 base::Bind(&MediaStreamManager::CancelRequest, | 252 base::Bind(&MediaStreamManager::CancelRequest, |
261 base::Unretained(this), *label)); | 253 base::Unretained(this), *label)); |
262 return; | 254 return; |
263 } | 255 } |
264 | 256 |
265 // TODO(miu): We should ask the device manager whether a device with id | 257 // TODO(miu): We should ask the device manager whether a device with id |
266 // |device_id| actually exists. Note that no such MediaStreamProvider API for | 258 // |device_id| actually exists. Note that no such MediaStreamProvider API for |
267 // this currently exists. Also, we don't have a user-friendly device name for | 259 // this currently exists. Also, we don't have a user-friendly device name for |
268 // the infobar UI. | 260 // the infobar UI. |
269 if (content::IsAudioMediaType(options.audio_type)) { | 261 if (IsAudioMediaType(options.audio_type)) { |
270 // TODO(justinlin): Updating the state to requested and pending are no-ops | 262 // TODO(justinlin): Updating the state to requested and pending are no-ops |
271 // in terms of the media manager, but these are the state changes we want to | 263 // in terms of the media manager, but these are the state changes we want to |
272 // support in terms of extensions (which is registered as an observer). | 264 // support in terms of extensions (which is registered as an observer). |
273 request.setState(options.audio_type, | 265 request.setState(options.audio_type, MEDIA_REQUEST_STATE_REQUESTED); |
274 content::MEDIA_REQUEST_STATE_REQUESTED); | 266 request.setState(options.audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
275 request.setState(options.audio_type, | |
276 content::MEDIA_REQUEST_STATE_PENDING_APPROVAL); | |
277 ui_controller_->AddAvailableDevicesToRequest( | 267 ui_controller_->AddAvailableDevicesToRequest( |
278 *label, options.audio_type, StreamDeviceInfoArray( | 268 *label, options.audio_type, StreamDeviceInfoArray( |
279 1, StreamDeviceInfo(options.audio_type, device_id, device_id, | 269 1, StreamDeviceInfo(options.audio_type, device_id, device_id, |
280 false))); | 270 false))); |
281 } | 271 } |
282 if (content::IsVideoMediaType(options.video_type)) { | 272 if (IsVideoMediaType(options.video_type)) { |
283 request.setState(options.video_type, | 273 request.setState(options.video_type, MEDIA_REQUEST_STATE_REQUESTED); |
284 content::MEDIA_REQUEST_STATE_REQUESTED); | 274 request.setState(options.video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
285 request.setState(options.video_type, | |
286 content::MEDIA_REQUEST_STATE_PENDING_APPROVAL); | |
287 ui_controller_->AddAvailableDevicesToRequest( | 275 ui_controller_->AddAvailableDevicesToRequest( |
288 *label, options.video_type, StreamDeviceInfoArray( | 276 *label, options.video_type, StreamDeviceInfoArray( |
289 1, StreamDeviceInfo(options.video_type, device_id, device_id, | 277 1, StreamDeviceInfo(options.video_type, device_id, device_id, |
290 false))); | 278 false))); |
291 } | 279 } |
292 } | 280 } |
293 | 281 |
294 void MediaStreamManager::CancelRequest(const std::string& label) { | 282 void MediaStreamManager::CancelRequest(const std::string& label) { |
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
296 | 284 |
297 DeviceRequests::iterator it = requests_.find(label); | 285 DeviceRequests::iterator it = requests_.find(label); |
298 if (it != requests_.end()) { | 286 if (it != requests_.end()) { |
299 // The request isn't complete, notify the UI immediately. | 287 // The request isn't complete, notify the UI immediately. |
300 ui_controller_->CancelUIRequest(label); | 288 ui_controller_->CancelUIRequest(label); |
301 | 289 |
302 if (!RequestDone(it->second)) { | 290 if (!RequestDone(it->second)) { |
303 // TODO(xians): update the |state| to STATE_DONE to trigger a state | 291 // TODO(xians): update the |state| to STATE_DONE to trigger a state |
304 // changed notification to UI before deleting the request? | 292 // changed notification to UI before deleting the request? |
305 DeviceRequest& request = it->second; | 293 DeviceRequest& request = it->second; |
306 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 294 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; |
307 ++i) { | 295 ++i) { |
308 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 296 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
309 if (request.getState(stream_type) != | 297 if (request.getState(stream_type) != MEDIA_REQUEST_STATE_OPENING) { |
310 content::MEDIA_REQUEST_STATE_OPENING) { | |
311 continue; | 298 continue; |
312 } | 299 } |
313 for (StreamDeviceInfoArray::const_iterator device_it = | 300 for (StreamDeviceInfoArray::const_iterator device_it = |
314 request.devices.begin(); | 301 request.devices.begin(); |
315 device_it != request.devices.end(); ++device_it) { | 302 device_it != request.devices.end(); ++device_it) { |
316 if (device_it->stream_type == stream_type) { | 303 if (device_it->stream_type == stream_type) { |
317 GetDeviceManager(stream_type)->Close(device_it->session_id); | 304 GetDeviceManager(stream_type)->Close(device_it->session_id); |
318 } | 305 } |
319 } | 306 } |
320 } | 307 } |
(...skipping 16 matching lines...) Expand all Loading... |
337 return; | 324 return; |
338 } | 325 } |
339 for (StreamDeviceInfoArray::const_iterator device_it = | 326 for (StreamDeviceInfoArray::const_iterator device_it = |
340 it->second.devices.begin(); | 327 it->second.devices.begin(); |
341 device_it != it->second.devices.end(); ++device_it) { | 328 device_it != it->second.devices.end(); ++device_it) { |
342 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id); | 329 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id); |
343 } | 330 } |
344 if (it->second.type == DeviceRequest::GENERATE_STREAM && | 331 if (it->second.type == DeviceRequest::GENERATE_STREAM && |
345 RequestDone(it->second)) { | 332 RequestDone(it->second)) { |
346 // Notify observers that this device is being closed. | 333 // Notify observers that this device is being closed. |
347 for (int i = content::MEDIA_NO_SERVICE + 1; | 334 for (int i = MEDIA_NO_SERVICE + 1; i != NUM_MEDIA_TYPES; ++i) { |
348 i != content::NUM_MEDIA_TYPES; ++i) { | |
349 if (it->second.getState(static_cast<MediaStreamType>(i)) != | 335 if (it->second.getState(static_cast<MediaStreamType>(i)) != |
350 content::MEDIA_REQUEST_STATE_NOT_REQUESTED) | 336 MEDIA_REQUEST_STATE_NOT_REQUESTED) |
351 it->second.setState(static_cast<MediaStreamType>(i), | 337 it->second.setState(static_cast<MediaStreamType>(i), |
352 content::MEDIA_REQUEST_STATE_CLOSING); | 338 MEDIA_REQUEST_STATE_CLOSING); |
353 } | 339 } |
354 NotifyDevicesClosed(it->second); | 340 NotifyDevicesClosed(it->second); |
355 } | 341 } |
356 | 342 |
357 // If request isn't complete, notify the UI on the cancellation. And it | 343 // If request isn't complete, notify the UI on the cancellation. And it |
358 // is also safe to call CancelUIRequest if the request has been done. | 344 // is also safe to call CancelUIRequest if the request has been done. |
359 ui_controller_->CancelUIRequest(label); | 345 ui_controller_->CancelUIRequest(label); |
360 | 346 |
361 // Delete the request now. | 347 // Delete the request now. |
362 requests_.erase(it); | 348 requests_.erase(it); |
363 } | 349 } |
364 } | 350 } |
365 | 351 |
366 void MediaStreamManager::EnumerateDevices( | 352 void MediaStreamManager::EnumerateDevices( |
367 MediaStreamRequester* requester, | 353 MediaStreamRequester* requester, |
368 int render_process_id, | 354 int render_process_id, |
369 int render_view_id, | 355 int render_view_id, |
370 MediaStreamType type, | 356 MediaStreamType type, |
371 const GURL& security_origin, | 357 const GURL& security_origin, |
372 std::string* label) { | 358 std::string* label) { |
373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
374 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || | 360 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
375 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); | 361 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
376 | 362 |
377 // Create a new request. | 363 // Create a new request. |
378 StreamOptions options; | 364 StreamOptions options; |
379 EnumerationCache* cache = NULL; | 365 EnumerationCache* cache = NULL; |
380 if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { | 366 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { |
381 options.audio_type = type; | 367 options.audio_type = type; |
382 cache = &audio_enumeration_cache_; | 368 cache = &audio_enumeration_cache_; |
383 } else if (type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { | 369 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
384 options.video_type = type; | 370 options.video_type = type; |
385 cache = &video_enumeration_cache_; | 371 cache = &video_enumeration_cache_; |
386 } else { | 372 } else { |
387 NOTREACHED(); | 373 NOTREACHED(); |
388 return; | 374 return; |
389 } | 375 } |
390 | 376 |
391 DeviceRequest new_request(requester, options, | 377 DeviceRequest new_request(requester, options, |
392 DeviceRequest::ENUMERATE_DEVICES, | 378 DeviceRequest::ENUMERATE_DEVICES, |
393 render_process_id, | 379 render_process_id, |
394 render_view_id, | 380 render_view_id, |
395 security_origin); | 381 security_origin); |
396 | 382 |
397 if (cache->valid) { | 383 if (cache->valid) { |
398 // Cached device list of this type exists. Just send it out. | 384 // Cached device list of this type exists. Just send it out. |
399 new_request.setState(type, content::MEDIA_REQUEST_STATE_REQUESTED); | 385 new_request.setState(type, MEDIA_REQUEST_STATE_REQUESTED); |
400 AddRequest(new_request, label); | 386 AddRequest(new_request, label); |
401 // Need to post a task since the requester won't have label till | 387 // Need to post a task since the requester won't have label till |
402 // this function returns. | 388 // this function returns. |
403 BrowserThread::PostTask(BrowserThread::IO, | 389 BrowserThread::PostTask(BrowserThread::IO, |
404 FROM_HERE, | 390 FROM_HERE, |
405 base::Bind(&MediaStreamManager::SendCachedDeviceList, | 391 base::Bind(&MediaStreamManager::SendCachedDeviceList, |
406 base::Unretained(this), cache, *label)); | 392 base::Unretained(this), cache, *label)); |
407 } else { | 393 } else { |
408 StartEnumeration(&new_request, label); | 394 StartEnumeration(&new_request, label); |
409 StartMonitoring(); | 395 StartMonitoring(); |
(...skipping 15 matching lines...) Expand all Loading... |
425 | 411 |
426 void MediaStreamManager::OpenDevice( | 412 void MediaStreamManager::OpenDevice( |
427 MediaStreamRequester* requester, | 413 MediaStreamRequester* requester, |
428 int render_process_id, | 414 int render_process_id, |
429 int render_view_id, | 415 int render_view_id, |
430 const std::string& device_id, | 416 const std::string& device_id, |
431 MediaStreamType type, | 417 MediaStreamType type, |
432 const GURL& security_origin, | 418 const GURL& security_origin, |
433 std::string* label) { | 419 std::string* label) { |
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
435 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || | 421 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
436 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); | 422 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
437 | 423 |
438 // Create a new request. | 424 // Create a new request. |
439 StreamOptions options; | 425 StreamOptions options; |
440 if (content::IsAudioMediaType(type)) { | 426 if (IsAudioMediaType(type)) { |
441 options.audio_type = type; | 427 options.audio_type = type; |
442 } else if (content::IsVideoMediaType(type)) { | 428 } else if (IsVideoMediaType(type)) { |
443 options.video_type = type; | 429 options.video_type = type; |
444 } else { | 430 } else { |
445 NOTREACHED(); | 431 NOTREACHED(); |
446 return; | 432 return; |
447 } | 433 } |
448 | 434 |
449 DeviceRequest new_request(requester, options, | 435 DeviceRequest new_request(requester, options, |
450 DeviceRequest::OPEN_DEVICE, | 436 DeviceRequest::OPEN_DEVICE, |
451 render_process_id, | 437 render_process_id, |
452 render_view_id, | 438 render_view_id, |
453 security_origin); | 439 security_origin); |
454 new_request.requested_device_id = device_id; | 440 new_request.requested_device_id = device_id; |
455 | 441 |
456 StartEnumeration(&new_request, label); | 442 StartEnumeration(&new_request, label); |
457 } | 443 } |
458 | 444 |
459 void MediaStreamManager::NotifyUIDevicesOpened( | 445 void MediaStreamManager::NotifyUIDevicesOpened( |
460 int render_process_id, | 446 int render_process_id, |
461 int render_view_id, | 447 int render_view_id, |
462 const content::MediaStreamDevices& devices) { | 448 const MediaStreamDevices& devices) { |
463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
464 ui_controller_->NotifyUIIndicatorDevicesOpened(render_process_id, | 450 ui_controller_->NotifyUIIndicatorDevicesOpened(render_process_id, |
465 render_view_id, | 451 render_view_id, |
466 devices); | 452 devices); |
467 } | 453 } |
468 | 454 |
469 void MediaStreamManager::NotifyUIDevicesClosed( | 455 void MediaStreamManager::NotifyUIDevicesClosed( |
470 int render_process_id, | 456 int render_process_id, |
471 int render_view_id, | 457 int render_view_id, |
472 const content::MediaStreamDevices& devices) { | 458 const MediaStreamDevices& devices) { |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
474 ui_controller_->NotifyUIIndicatorDevicesClosed(render_process_id, | 460 ui_controller_->NotifyUIIndicatorDevicesClosed(render_process_id, |
475 render_view_id, | 461 render_view_id, |
476 devices); | 462 devices); |
477 } | 463 } |
478 | 464 |
479 void MediaStreamManager::SendCachedDeviceList( | 465 void MediaStreamManager::SendCachedDeviceList( |
480 EnumerationCache* cache, | 466 EnumerationCache* cache, |
481 const std::string& label) { | 467 const std::string& label) { |
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 26 matching lines...) Expand all Loading... |
509 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 495 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
510 DCHECK_EQ(MessageLoop::current(), io_loop_); | 496 DCHECK_EQ(MessageLoop::current(), io_loop_); |
511 cache->valid = false; | 497 cache->valid = false; |
512 } | 498 } |
513 | 499 |
514 void MediaStreamManager::StartEnumeration( | 500 void MediaStreamManager::StartEnumeration( |
515 DeviceRequest* new_request, | 501 DeviceRequest* new_request, |
516 std::string* label) { | 502 std::string* label) { |
517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
518 | 504 |
519 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 505 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; |
520 ++i) { | 506 ++i) { |
521 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 507 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
522 if (Requested(new_request->options, stream_type)) { | 508 if (Requested(new_request->options, stream_type)) { |
523 new_request->setState(stream_type, | 509 new_request->setState(stream_type, MEDIA_REQUEST_STATE_REQUESTED); |
524 content::MEDIA_REQUEST_STATE_REQUESTED); | |
525 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 510 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
526 if (active_enumeration_ref_count_[stream_type] == 0) { | 511 if (active_enumeration_ref_count_[stream_type] == 0) { |
527 ++active_enumeration_ref_count_[stream_type]; | 512 ++active_enumeration_ref_count_[stream_type]; |
528 GetDeviceManager(stream_type)->EnumerateDevices(); | 513 GetDeviceManager(stream_type)->EnumerateDevices(); |
529 } | 514 } |
530 } | 515 } |
531 } | 516 } |
532 | 517 |
533 AddRequest(*new_request, label); | 518 AddRequest(*new_request, label); |
534 } | 519 } |
(...skipping 30 matching lines...) Expand all Loading... |
565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
566 if (device_thread_.get()) | 551 if (device_thread_.get()) |
567 return; | 552 return; |
568 | 553 |
569 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); | 554 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); |
570 #if defined(OS_WIN) | 555 #if defined(OS_WIN) |
571 device_thread_->init_com_with_mta(true); | 556 device_thread_->init_com_with_mta(true); |
572 #endif | 557 #endif |
573 CHECK(device_thread_->Start()); | 558 CHECK(device_thread_->Start()); |
574 | 559 |
575 audio_input_device_manager_ = | 560 audio_input_device_manager_ = new AudioInputDeviceManager(audio_manager_); |
576 new media_stream::AudioInputDeviceManager(audio_manager_); | |
577 audio_input_device_manager_->Register(this, | 561 audio_input_device_manager_->Register(this, |
578 device_thread_->message_loop_proxy()); | 562 device_thread_->message_loop_proxy()); |
579 | 563 |
580 video_capture_manager_ = new media_stream::VideoCaptureManager(); | 564 video_capture_manager_ = new VideoCaptureManager(); |
581 video_capture_manager_->Register(this, | 565 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); |
582 device_thread_->message_loop_proxy()); | |
583 | 566 |
584 // We want to be notified of IO message loop destruction to delete the thread | 567 // We want to be notified of IO message loop destruction to delete the thread |
585 // and the device managers. | 568 // and the device managers. |
586 io_loop_ = MessageLoop::current(); | 569 io_loop_ = MessageLoop::current(); |
587 io_loop_->AddDestructionObserver(this); | 570 io_loop_->AddDestructionObserver(this); |
588 } | 571 } |
589 | 572 |
590 void MediaStreamManager::Opened(MediaStreamType stream_type, | 573 void MediaStreamManager::Opened(MediaStreamType stream_type, |
591 int capture_session_id) { | 574 int capture_session_id) { |
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 15 matching lines...) Expand all Loading... |
608 request = &(request_it->second); | 591 request = &(request_it->second); |
609 break; | 592 break; |
610 } | 593 } |
611 } | 594 } |
612 } | 595 } |
613 if (request == NULL) { | 596 if (request == NULL) { |
614 // The request doesn't exist. | 597 // The request doesn't exist. |
615 return; | 598 return; |
616 } | 599 } |
617 | 600 |
618 DCHECK_NE(request->getState(stream_type), | 601 DCHECK_NE(request->getState(stream_type), MEDIA_REQUEST_STATE_REQUESTED); |
619 content::MEDIA_REQUEST_STATE_REQUESTED); | |
620 | 602 |
621 // Check if all devices for this stream type are opened. Update the state if | 603 // Check if all devices for this stream type are opened. Update the state if |
622 // they are. | 604 // they are. |
623 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 605 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
624 device_it != devices->end(); ++device_it) { | 606 device_it != devices->end(); ++device_it) { |
625 if (device_it->stream_type != stream_type) { | 607 if (device_it->stream_type != stream_type) { |
626 continue; | 608 continue; |
627 } | 609 } |
628 if (device_it->in_use == false) { | 610 if (device_it->in_use == false) { |
629 // Wait for more devices to be opened before we're done. | 611 // Wait for more devices to be opened before we're done. |
630 return; | 612 return; |
631 } | 613 } |
632 } | 614 } |
633 | 615 |
634 request->setState(stream_type, content::MEDIA_REQUEST_STATE_DONE); | 616 request->setState(stream_type, MEDIA_REQUEST_STATE_DONE); |
635 | 617 |
636 if (!RequestDone(*request)) { | 618 if (!RequestDone(*request)) { |
637 // This stream_type is done, but not the other type. | 619 // This stream_type is done, but not the other type. |
638 return; | 620 return; |
639 } | 621 } |
640 | 622 |
641 switch (request->type) { | 623 switch (request->type) { |
642 case DeviceRequest::OPEN_DEVICE: | 624 case DeviceRequest::OPEN_DEVICE: |
643 request->requester->DeviceOpened(label, devices->front()); | 625 request->requester->DeviceOpened(label, devices->front()); |
644 break; | 626 break; |
645 case DeviceRequest::GENERATE_STREAM: { | 627 case DeviceRequest::GENERATE_STREAM: { |
646 // Partition the array of devices into audio vs video. | 628 // Partition the array of devices into audio vs video. |
647 StreamDeviceInfoArray audio_devices, video_devices; | 629 StreamDeviceInfoArray audio_devices, video_devices; |
648 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin(); | 630 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin(); |
649 device_it != devices->end(); ++device_it) { | 631 device_it != devices->end(); ++device_it) { |
650 if (content::IsAudioMediaType(device_it->stream_type)) { | 632 if (IsAudioMediaType(device_it->stream_type)) { |
651 audio_devices.push_back(*device_it); | 633 audio_devices.push_back(*device_it); |
652 } else if (content::IsVideoMediaType(device_it->stream_type)) { | 634 } else if (IsVideoMediaType(device_it->stream_type)) { |
653 video_devices.push_back(*device_it); | 635 video_devices.push_back(*device_it); |
654 } else { | 636 } else { |
655 NOTREACHED(); | 637 NOTREACHED(); |
656 } | 638 } |
657 } | 639 } |
658 | 640 |
659 request->requester->StreamGenerated(label, audio_devices, video_devices); | 641 request->requester->StreamGenerated(label, audio_devices, video_devices); |
660 NotifyDevicesOpened(*request); | 642 NotifyDevicesOpened(*request); |
661 break; | 643 break; |
662 } | 644 } |
663 default: | 645 default: |
664 NOTREACHED(); | 646 NOTREACHED(); |
665 break; | 647 break; |
666 } | 648 } |
667 } | 649 } |
668 | 650 |
669 void MediaStreamManager::Closed(MediaStreamType stream_type, | 651 void MediaStreamManager::Closed(MediaStreamType stream_type, |
670 int capture_session_id) { | 652 int capture_session_id) { |
671 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 653 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
672 } | 654 } |
673 | 655 |
674 void MediaStreamManager::DevicesEnumerated( | 656 void MediaStreamManager::DevicesEnumerated( |
675 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { | 657 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 658 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
677 | 659 |
678 // Only cache the device list when there is an EnumerateDevices request, since | 660 // Only cache the device list when there is an EnumerateDevices request, since |
679 // other requests don't turn on device monitoring. | 661 // other requests don't turn on device monitoring. |
680 bool need_update_clients = false; | 662 bool need_update_clients = false; |
681 EnumerationCache* cache = | 663 EnumerationCache* cache = (stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
682 (stream_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ? | |
683 &audio_enumeration_cache_ : &video_enumeration_cache_); | 664 &audio_enumeration_cache_ : &video_enumeration_cache_); |
684 if (HasEnumerationRequest(stream_type) && | 665 if (HasEnumerationRequest(stream_type) && |
685 (!cache->valid || | 666 (!cache->valid || |
686 devices.size() != cache->devices.size() || | 667 devices.size() != cache->devices.size() || |
687 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), | 668 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), |
688 media_stream::StreamDeviceInfo::IsEqual))) { | 669 StreamDeviceInfo::IsEqual))) { |
689 cache->valid = true; | 670 cache->valid = true; |
690 cache->devices = devices; | 671 cache->devices = devices; |
691 need_update_clients = true; | 672 need_update_clients = true; |
692 } | 673 } |
693 | 674 |
694 // Publish the result for all requests waiting for device list(s). | 675 // Publish the result for all requests waiting for device list(s). |
695 // Find the requests waiting for this device list, store their labels and | 676 // Find the requests waiting for this device list, store their labels and |
696 // release the iterator before calling device settings. We might get a call | 677 // release the iterator before calling device settings. We might get a call |
697 // back from device_settings that will need to iterate through devices. | 678 // back from device_settings that will need to iterate through devices. |
698 std::list<std::string> label_list; | 679 std::list<std::string> label_list; |
699 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 680 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
700 ++it) { | 681 ++it) { |
701 if (it->second.getState(stream_type) == | 682 if (it->second.getState(stream_type) == |
702 content::MEDIA_REQUEST_STATE_REQUESTED && | 683 MEDIA_REQUEST_STATE_REQUESTED && |
703 Requested(it->second.options, stream_type)) { | 684 Requested(it->second.options, stream_type)) { |
704 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) | 685 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) |
705 it->second.setState(stream_type, | 686 it->second.setState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
706 content::MEDIA_REQUEST_STATE_PENDING_APPROVAL); | |
707 label_list.push_back(it->first); | 687 label_list.push_back(it->first); |
708 } | 688 } |
709 } | 689 } |
710 for (std::list<std::string>::iterator it = label_list.begin(); | 690 for (std::list<std::string>::iterator it = label_list.begin(); |
711 it != label_list.end(); ++it) { | 691 it != label_list.end(); ++it) { |
712 DeviceRequest& request = requests_[*it]; | 692 DeviceRequest& request = requests_[*it]; |
713 switch (request.type) { | 693 switch (request.type) { |
714 case DeviceRequest::ENUMERATE_DEVICES: | 694 case DeviceRequest::ENUMERATE_DEVICES: |
715 if (need_update_clients) | 695 if (need_update_clients) |
716 request.requester->DevicesEnumerated(*it, devices); | 696 request.requester->DevicesEnumerated(*it, devices); |
717 break; | 697 break; |
718 case DeviceRequest::OPEN_DEVICE: | 698 case DeviceRequest::OPEN_DEVICE: |
719 DCHECK(!request.requested_device_id.empty()); | 699 DCHECK(!request.requested_device_id.empty()); |
720 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 700 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
721 device_it != devices.end(); ++device_it) { | 701 device_it != devices.end(); ++device_it) { |
722 if (request.requested_device_id == device_it->device_id) { | 702 if (request.requested_device_id == device_it->device_id) { |
723 StreamDeviceInfo device = *device_it; | 703 StreamDeviceInfo device = *device_it; |
724 device.in_use = false; | 704 device.in_use = false; |
725 device.session_id = | 705 device.session_id = |
726 GetDeviceManager(device_it->stream_type)->Open(device); | 706 GetDeviceManager(device_it->stream_type)->Open(device); |
727 request.setState(device_it->stream_type, | 707 request.setState(device_it->stream_type, |
728 content::MEDIA_REQUEST_STATE_OPENING); | 708 MEDIA_REQUEST_STATE_OPENING); |
729 request.devices.push_back(device); | 709 request.devices.push_back(device); |
730 break; | 710 break; |
731 } | 711 } |
732 } | 712 } |
733 break; | 713 break; |
734 default: | 714 default: |
735 ui_controller_->AddAvailableDevicesToRequest(*it, stream_type, | 715 ui_controller_->AddAvailableDevicesToRequest(*it, stream_type, |
736 devices); | 716 devices); |
737 break; | 717 break; |
738 } | 718 } |
(...skipping 13 matching lines...) Expand all Loading... |
752 ++it) { | 732 ++it) { |
753 StreamDeviceInfoArray& devices = it->second.devices; | 733 StreamDeviceInfoArray& devices = it->second.devices; |
754 | 734 |
755 // TODO(miu): BUG. It's possible for the audio (or video) device array in | 735 // TODO(miu): BUG. It's possible for the audio (or video) device array in |
756 // the "requester" to become out-of-sync with the order of devices we have | 736 // the "requester" to become out-of-sync with the order of devices we have |
757 // here. See http://crbug.com/147650 | 737 // here. See http://crbug.com/147650 |
758 int audio_device_idx = -1; | 738 int audio_device_idx = -1; |
759 int video_device_idx = -1; | 739 int video_device_idx = -1; |
760 for (StreamDeviceInfoArray::iterator device_it = devices.begin(); | 740 for (StreamDeviceInfoArray::iterator device_it = devices.begin(); |
761 device_it != devices.end(); ++device_it) { | 741 device_it != devices.end(); ++device_it) { |
762 if (content::IsAudioMediaType(device_it->stream_type)) { | 742 if (IsAudioMediaType(device_it->stream_type)) { |
763 ++audio_device_idx; | 743 ++audio_device_idx; |
764 } else if (content::IsVideoMediaType(device_it->stream_type)) { | 744 } else if (IsVideoMediaType(device_it->stream_type)) { |
765 ++video_device_idx; | 745 ++video_device_idx; |
766 } else { | 746 } else { |
767 NOTREACHED(); | 747 NOTREACHED(); |
768 continue; | 748 continue; |
769 } | 749 } |
770 if (device_it->stream_type != stream_type || | 750 if (device_it->stream_type != stream_type || |
771 device_it->session_id != capture_session_id) { | 751 device_it->session_id != capture_session_id) { |
772 continue; | 752 continue; |
773 } | 753 } |
774 // We've found the failing device. Find the error case: | 754 // We've found the failing device. Find the error case: |
775 // An error should only be reported to the MediaStreamManager if | 755 // An error should only be reported to the MediaStreamManager if |
776 // the request has not been fulfilled yet. | 756 // the request has not been fulfilled yet. |
777 DCHECK(it->second.getState(stream_type) != | 757 DCHECK(it->second.getState(stream_type) != MEDIA_REQUEST_STATE_DONE); |
778 content::MEDIA_REQUEST_STATE_DONE); | 758 if (it->second.getState(stream_type) != MEDIA_REQUEST_STATE_DONE) { |
779 if (it->second.getState(stream_type) != | |
780 content::MEDIA_REQUEST_STATE_DONE) { | |
781 // Request is not done, devices are not opened in this case. | 759 // Request is not done, devices are not opened in this case. |
782 if (devices.size() <= 1) { | 760 if (devices.size() <= 1) { |
783 // 1. Device not opened and no other devices for this request -> | 761 // 1. Device not opened and no other devices for this request -> |
784 // signal stream error and remove the request. | 762 // signal stream error and remove the request. |
785 if (it->second.requester) | 763 if (it->second.requester) |
786 it->second.requester->StreamGenerationFailed(it->first); | 764 it->second.requester->StreamGenerationFailed(it->first); |
787 | 765 |
788 requests_.erase(it); | 766 requests_.erase(it); |
789 } else { | 767 } else { |
790 // 2. Not opened but other devices exists for this request -> remove | 768 // 2. Not opened but other devices exists for this request -> remove |
(...skipping 13 matching lines...) Expand all Loading... |
804 DeviceRequests::iterator request_it = requests_.find(label); | 782 DeviceRequests::iterator request_it = requests_.find(label); |
805 if (request_it == requests_.end()) { | 783 if (request_it == requests_.end()) { |
806 return; | 784 return; |
807 } | 785 } |
808 | 786 |
809 DeviceRequest& request = request_it->second; | 787 DeviceRequest& request = request_it->second; |
810 | 788 |
811 if (request.type == DeviceRequest::DEVICE_ACCESS) { | 789 if (request.type == DeviceRequest::DEVICE_ACCESS) { |
812 if (!request.callback.is_null()) { | 790 if (!request.callback.is_null()) { |
813 // Map the devices to MediaStreamDevices. | 791 // Map the devices to MediaStreamDevices. |
814 content::MediaStreamDevices selected_devices; | 792 MediaStreamDevices selected_devices; |
815 for (StreamDeviceInfoArray::const_iterator it = devices.begin(); | 793 for (StreamDeviceInfoArray::const_iterator it = devices.begin(); |
816 it != devices.end(); ++it) { | 794 it != devices.end(); ++it) { |
817 selected_devices.push_back(content::MediaStreamDevice( | 795 selected_devices.push_back(MediaStreamDevice( |
818 it->stream_type, it->device_id, it->name)); | 796 it->stream_type, it->device_id, it->name)); |
819 } | 797 } |
820 | 798 |
821 request.callback.Run(label, selected_devices); | 799 request.callback.Run(label, selected_devices); |
822 } | 800 } |
823 | 801 |
824 // Delete the request since it is done. | 802 // Delete the request since it is done. |
825 requests_.erase(request_it); | 803 requests_.erase(request_it); |
826 return; | 804 return; |
827 } | 805 } |
828 | 806 |
829 // Process all newly-accepted devices for this request. | 807 // Process all newly-accepted devices for this request. |
830 bool found_audio = false, found_video = false; | 808 bool found_audio = false, found_video = false; |
831 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 809 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
832 device_it != devices.end(); ++device_it) { | 810 device_it != devices.end(); ++device_it) { |
833 StreamDeviceInfo device_info = *device_it; // Make a copy. | 811 StreamDeviceInfo device_info = *device_it; // Make a copy. |
834 | 812 |
835 // Set in_use to false to be able to track if this device has been | 813 // Set in_use to false to be able to track if this device has been |
836 // opened. in_use might be true if the device type can be used in more | 814 // opened. in_use might be true if the device type can be used in more |
837 // than one session. | 815 // than one session. |
838 DCHECK_EQ(request.getState(device_it->stream_type), | 816 DCHECK_EQ(request.getState(device_it->stream_type), |
839 content::MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 817 MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
840 device_info.in_use = false; | 818 device_info.in_use = false; |
841 | 819 |
842 device_info.session_id = | 820 device_info.session_id = |
843 GetDeviceManager(device_info.stream_type)->Open(device_info); | 821 GetDeviceManager(device_info.stream_type)->Open(device_info); |
844 request.setState(device_it->stream_type, | 822 request.setState(device_it->stream_type, MEDIA_REQUEST_STATE_OPENING); |
845 content::MEDIA_REQUEST_STATE_OPENING); | |
846 request.devices.push_back(device_info); | 823 request.devices.push_back(device_info); |
847 | 824 |
848 if (device_info.stream_type == request.options.audio_type) { | 825 if (device_info.stream_type == request.options.audio_type) { |
849 found_audio = true; | 826 found_audio = true; |
850 } else if (device_info.stream_type == request.options.video_type) { | 827 } else if (device_info.stream_type == request.options.video_type) { |
851 found_video = true; | 828 found_video = true; |
852 } | 829 } |
853 } | 830 } |
854 | 831 |
855 // Check whether we've received all stream types requested. | 832 // Check whether we've received all stream types requested. |
856 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { | 833 if (!found_audio && IsAudioMediaType(request.options.audio_type)) { |
857 request.setState(request.options.audio_type, | 834 request.setState(request.options.audio_type, MEDIA_REQUEST_STATE_ERROR); |
858 content::MEDIA_REQUEST_STATE_ERROR); | |
859 } | 835 } |
860 if (!found_video && content::IsVideoMediaType(request.options.video_type)) { | 836 if (!found_video && IsVideoMediaType(request.options.video_type)) { |
861 request.setState(request.options.video_type, | 837 request.setState(request.options.video_type, MEDIA_REQUEST_STATE_ERROR); |
862 content::MEDIA_REQUEST_STATE_ERROR); | |
863 } | 838 } |
864 } | 839 } |
865 | 840 |
866 void MediaStreamManager::SettingsError(const std::string& label) { | 841 void MediaStreamManager::SettingsError(const std::string& label) { |
867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
868 // Erase this request and report an error. | 843 // Erase this request and report an error. |
869 DeviceRequests::iterator it = requests_.find(label); | 844 DeviceRequests::iterator it = requests_.find(label); |
870 if (it == requests_.end()) | 845 if (it == requests_.end()) |
871 return; | 846 return; |
872 | 847 |
873 // Notify the users about the request result. | 848 // Notify the users about the request result. |
874 DeviceRequest& request = it->second; | 849 DeviceRequest& request = it->second; |
875 if (request.requester) | 850 if (request.requester) |
876 it->second.requester->StreamGenerationFailed(label); | 851 it->second.requester->StreamGenerationFailed(label); |
877 | 852 |
878 if (request.type == DeviceRequest::DEVICE_ACCESS) | 853 if (request.type == DeviceRequest::DEVICE_ACCESS) |
879 request.callback.Run(label, content::MediaStreamDevices()); | 854 request.callback.Run(label, MediaStreamDevices()); |
880 | 855 |
881 requests_.erase(it); | 856 requests_.erase(it); |
882 } | 857 } |
883 | 858 |
884 void MediaStreamManager::UseFakeDevice() { | 859 void MediaStreamManager::UseFakeDevice() { |
885 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 860 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
886 video_capture_manager()->UseFakeDevice(); | 861 video_capture_manager()->UseFakeDevice(); |
887 ui_controller_->UseFakeUI(); | 862 ui_controller_->UseFakeUI(); |
888 } | 863 } |
889 | 864 |
890 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 865 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
891 DCHECK_EQ(MessageLoop::current(), io_loop_); | 866 DCHECK_EQ(MessageLoop::current(), io_loop_); |
892 DCHECK(requests_.empty()); | 867 DCHECK(requests_.empty()); |
893 if (device_thread_.get()) { | 868 if (device_thread_.get()) { |
894 StopMonitoring(); | 869 StopMonitoring(); |
895 | 870 |
896 video_capture_manager_->Unregister(); | 871 video_capture_manager_->Unregister(); |
897 audio_input_device_manager_->Unregister(); | 872 audio_input_device_manager_->Unregister(); |
898 device_thread_.reset(); | 873 device_thread_.reset(); |
899 } | 874 } |
900 | 875 |
901 audio_input_device_manager_ = NULL; | 876 audio_input_device_manager_ = NULL; |
902 video_capture_manager_ = NULL; | 877 video_capture_manager_ = NULL; |
903 io_loop_ = NULL; | 878 io_loop_ = NULL; |
904 ui_controller_.reset(); | 879 ui_controller_.reset(); |
905 } | 880 } |
906 | 881 |
907 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { | 882 void MediaStreamManager::NotifyDevicesOpened(const DeviceRequest& request) { |
908 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 883 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
909 content::MediaStreamDevices opened_devices; | 884 MediaStreamDevices opened_devices; |
910 DevicesFromRequest(request, &opened_devices); | 885 DevicesFromRequest(request, &opened_devices); |
911 if (opened_devices.empty()) | 886 if (opened_devices.empty()) |
912 return; | 887 return; |
913 | 888 |
914 NotifyUIDevicesOpened(request.render_process_id, | 889 NotifyUIDevicesOpened(request.render_process_id, |
915 request.render_view_id, | 890 request.render_view_id, |
916 opened_devices); | 891 opened_devices); |
917 } | 892 } |
918 | 893 |
919 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { | 894 void MediaStreamManager::NotifyDevicesClosed(const DeviceRequest& request) { |
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
921 content::MediaStreamDevices closed_devices; | 896 MediaStreamDevices closed_devices; |
922 DevicesFromRequest(request, &closed_devices); | 897 DevicesFromRequest(request, &closed_devices); |
923 if (closed_devices.empty()) | 898 if (closed_devices.empty()) |
924 return; | 899 return; |
925 | 900 |
926 NotifyUIDevicesClosed(request.render_process_id, | 901 NotifyUIDevicesClosed(request.render_process_id, |
927 request.render_view_id, | 902 request.render_view_id, |
928 closed_devices); | 903 closed_devices); |
929 } | 904 } |
930 | 905 |
931 void MediaStreamManager::DevicesFromRequest( | 906 void MediaStreamManager::DevicesFromRequest( |
932 const DeviceRequest& request, content::MediaStreamDevices* devices) { | 907 const DeviceRequest& request, MediaStreamDevices* devices) { |
933 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 908 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
934 it != request.devices.end(); ++it) { | 909 it != request.devices.end(); ++it) { |
935 devices->push_back(content::MediaStreamDevice( | 910 devices->push_back(MediaStreamDevice( |
936 it->stream_type, it->device_id, it->name)); | 911 it->stream_type, it->device_id, it->name)); |
937 } | 912 } |
938 } | 913 } |
939 | 914 |
940 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 915 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 916 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
942 | 917 |
943 const bool requested_audio = | 918 const bool requested_audio = IsAudioMediaType(request.options.audio_type); |
944 content::IsAudioMediaType(request.options.audio_type); | 919 const bool requested_video = IsVideoMediaType(request.options.video_type); |
945 const bool requested_video = | |
946 content::IsVideoMediaType(request.options.video_type); | |
947 | 920 |
948 const bool audio_done = | 921 const bool audio_done = |
949 !requested_audio || | 922 !requested_audio || |
950 request.getState(request.options.audio_type) == | 923 request.getState(request.options.audio_type) == |
951 content::MEDIA_REQUEST_STATE_DONE || | 924 MEDIA_REQUEST_STATE_DONE || |
952 request.getState(request.options.audio_type) == | 925 request.getState(request.options.audio_type) == |
953 content::MEDIA_REQUEST_STATE_ERROR; | 926 MEDIA_REQUEST_STATE_ERROR; |
954 if (!audio_done) { | 927 if (!audio_done) { |
955 return false; | 928 return false; |
956 } | 929 } |
957 | 930 |
958 const bool video_done = | 931 const bool video_done = |
959 !requested_video || | 932 !requested_video || |
960 request.getState(request.options.video_type) == | 933 request.getState(request.options.video_type) == |
961 content::MEDIA_REQUEST_STATE_DONE || | 934 MEDIA_REQUEST_STATE_DONE || |
962 request.getState(request.options.video_type) == | 935 request.getState(request.options.video_type) == |
963 content::MEDIA_REQUEST_STATE_ERROR; | 936 MEDIA_REQUEST_STATE_ERROR; |
964 if (!video_done) { | 937 if (!video_done) { |
965 return false; | 938 return false; |
966 } | 939 } |
967 | 940 |
968 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 941 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
969 it != request.devices.end(); ++it) { | 942 it != request.devices.end(); ++it) { |
970 if (it->in_use == false) { | 943 if (it->in_use == false) { |
971 return false; | 944 return false; |
972 } | 945 } |
973 } | 946 } |
974 | 947 |
975 return true; | 948 return true; |
976 } | 949 } |
977 | 950 |
978 MediaStreamProvider* MediaStreamManager::GetDeviceManager( | 951 MediaStreamProvider* MediaStreamManager::GetDeviceManager( |
979 MediaStreamType stream_type) { | 952 MediaStreamType stream_type) { |
980 if (content::IsVideoMediaType(stream_type)) { | 953 if (IsVideoMediaType(stream_type)) { |
981 return video_capture_manager(); | 954 return video_capture_manager(); |
982 } else if (content::IsAudioMediaType(stream_type)) { | 955 } else if (IsAudioMediaType(stream_type)) { |
983 return audio_input_device_manager(); | 956 return audio_input_device_manager(); |
984 } | 957 } |
985 NOTREACHED(); | 958 NOTREACHED(); |
986 return NULL; | 959 return NULL; |
987 } | 960 } |
988 | 961 |
989 void MediaStreamManager::OnDevicesChanged( | 962 void MediaStreamManager::OnDevicesChanged( |
990 base::SystemMonitor::DeviceType device_type) { | 963 base::SystemMonitor::DeviceType device_type) { |
991 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
992 | 965 |
993 // NOTE: This method is only called in response to physical audio/video device | 966 // NOTE: This method is only called in response to physical audio/video device |
994 // changes (from the operating system). | 967 // changes (from the operating system). |
995 | 968 |
996 MediaStreamType stream_type; | 969 MediaStreamType stream_type; |
997 EnumerationCache* cache; | 970 EnumerationCache* cache; |
998 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { | 971 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { |
999 stream_type = content::MEDIA_DEVICE_AUDIO_CAPTURE; | 972 stream_type = MEDIA_DEVICE_AUDIO_CAPTURE; |
1000 cache = &audio_enumeration_cache_; | 973 cache = &audio_enumeration_cache_; |
1001 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { | 974 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { |
1002 stream_type = content::MEDIA_DEVICE_VIDEO_CAPTURE; | 975 stream_type = MEDIA_DEVICE_VIDEO_CAPTURE; |
1003 cache = &video_enumeration_cache_; | 976 cache = &video_enumeration_cache_; |
1004 } else { | 977 } else { |
1005 return; // Uninteresting device change. | 978 return; // Uninteresting device change. |
1006 } | 979 } |
1007 | 980 |
1008 if (!HasEnumerationRequest(stream_type)) { | 981 if (!HasEnumerationRequest(stream_type)) { |
1009 // There is no request for that type, No need to enumerate devices. | 982 // There is no request for that type, No need to enumerate devices. |
1010 // Therefore, invalidate the cache of that type. | 983 // Therefore, invalidate the cache of that type. |
1011 ClearEnumerationCache(cache); | 984 ClearEnumerationCache(cache); |
1012 return; | 985 return; |
(...skipping 23 matching lines...) Expand all Loading... |
1036 for (DeviceRequests::iterator it = requests_.begin(); | 1009 for (DeviceRequests::iterator it = requests_.begin(); |
1037 it != requests_.end(); ++it) { | 1010 it != requests_.end(); ++it) { |
1038 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | 1011 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
1039 Requested(it->second.options, stream_type)) { | 1012 Requested(it->second.options, stream_type)) { |
1040 return true; | 1013 return true; |
1041 } | 1014 } |
1042 } | 1015 } |
1043 return false; | 1016 return false; |
1044 } | 1017 } |
1045 | 1018 |
1046 } // namespace media_stream | 1019 } // namespace content |
OLD | NEW |