Chromium Code Reviews| Index: content/browser/renderer_host/media/media_stream_manager.cc |
| diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc |
| index f35795252c46127548d77e93a667a0460b0a487b..5e0a4920dcdecb0fae01b5e7a3ebd06202cd3ca3 100644 |
| --- a/content/browser/renderer_host/media/media_stream_manager.cc |
| +++ b/content/browser/renderer_host/media/media_stream_manager.cc |
| @@ -25,6 +25,7 @@ |
| #endif |
| using content::BrowserThread; |
| +using content::MediaStreamRequest; |
| namespace media_stream { |
| @@ -73,16 +74,8 @@ void DeviceThread::CleanUp() { |
| #endif |
| // TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
| -struct MediaStreamManager::DeviceRequest { |
| - enum RequestState { |
| - STATE_NOT_REQUESTED = 0, |
| - STATE_REQUESTED, |
| - STATE_PENDING_APPROVAL, |
| - STATE_OPENING, |
| - STATE_DONE, |
| - STATE_ERROR |
| - }; |
| - |
| +class MediaStreamManager::DeviceRequest { |
|
no longer working on chromium
2012/10/11 09:07:25
Nice, thanks.
|
| + public: |
| enum RequestType { |
| GENERATE_STREAM = 0, |
| ENUMERATE_DEVICES, |
| @@ -91,10 +84,11 @@ struct MediaStreamManager::DeviceRequest { |
| DeviceRequest() |
| : requester(NULL), |
| - state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), |
| type(GENERATE_STREAM), |
| render_process_id(-1), |
| - render_view_id(-1) { |
| + render_view_id(-1), |
| + state_(content::NUM_MEDIA_TYPES, |
| + MediaStreamRequest::STATE_NOT_REQUESTED) { |
| } |
| DeviceRequest(MediaStreamRequester* requester, |
| @@ -104,11 +98,12 @@ struct MediaStreamManager::DeviceRequest { |
| const GURL& request_security_origin) |
| : requester(requester), |
| options(request_options), |
| - state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), |
| type(GENERATE_STREAM), |
| render_process_id(render_process_id), |
| render_view_id(render_view_id), |
| - security_origin(request_security_origin) { |
| + security_origin(request_security_origin), |
| + state_(content::NUM_MEDIA_TYPES, |
| + MediaStreamRequest::STATE_NOT_REQUESTED) { |
| DCHECK(requester); |
| } |
| @@ -116,15 +111,46 @@ struct MediaStreamManager::DeviceRequest { |
| MediaStreamRequester* requester; |
| StreamOptions options; |
| - std::vector<RequestState> state; |
| RequestType type; |
| int render_process_id; |
| int render_view_id; |
| GURL security_origin; |
| std::string requested_device_id; |
| StreamDeviceInfoArray devices; |
| + |
| + void setState(MediaStreamType stream_type, |
| + MediaStreamRequest::RequestState new_state) { |
| + state_[stream_type] = new_state; |
| + } |
| + |
| + MediaStreamRequest::RequestState getState(MediaStreamType stream_type) const { |
| + return state_[stream_type]; |
| + } |
| + |
| + private: |
| + std::vector<MediaStreamRequest::RequestState> state_; |
| }; |
| +// Helper to update the request state and notify observers. |
| +static void UpdateRequestState( |
|
wjia(left Chromium)
2012/10/11 20:21:07
I guess you need to call this function only when r
justinlin
2012/10/11 21:19:21
Done. Changed the check to just use options.{video
|
| + MediaStreamManager::DeviceRequest* request, |
| + MediaStreamType stream_type, |
| + const MediaStreamRequest::RequestState new_state) { |
| + request->setState(stream_type, new_state); |
| + |
| + content::MediaObserver* media_observer = |
| + content::GetContentClient()->browser()->GetMediaObserver(); |
| + if (media_observer == NULL) |
| + return; |
| + media_observer->OnMediaRequestStateChanged( |
| + request->render_process_id, |
| + request->render_view_id, |
| + content::MediaStreamDevice(stream_type, |
| + request->requested_device_id, |
|
no longer working on chromium
2012/10/11 09:07:25
Do we still notify the observer if requested_devic
justinlin
2012/10/11 19:41:51
Done. We could short-circuit it here with that con
|
| + request->requested_device_id), |
| + new_state); |
| +} |
| + |
| MediaStreamManager::EnumerationCache::EnumerationCache() |
| : valid(false) { |
| } |
| @@ -207,6 +233,7 @@ void MediaStreamManager::GenerateStreamForDevice( |
| security_origin), |
| label); |
| DeviceRequest& request = requests_[*label]; |
| + request.requested_device_id = device_id; |
| // Get user confirmation to use the capture device. |
| device_settings_->RequestCaptureDeviceUsage(*label, |
| @@ -218,20 +245,27 @@ void MediaStreamManager::GenerateStreamForDevice( |
| // |device_id| actually exists. Note that no such MediaStreamProvider API for |
| // this currently exists. Also, we don't have a user-friendly device name for |
| // the infobar UI. |
| + StreamDeviceInfoArray devices; |
| if (content::IsAudioMediaType(options.audio_type)) { |
| - request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL; |
| - device_settings_->AvailableDevices( |
| - *label, options.audio_type, StreamDeviceInfoArray( |
| - 1, StreamDeviceInfo(options.audio_type, device_id, device_id, |
| - false))); |
| + // TODO(justinlin): Updating the state to requested and pending are no-ops |
| + // in terms of the media manager, but these are the state changes we want to |
| + // support in terms of extensions (which is registered as an observer). |
| + UpdateRequestState(&request, options.audio_type, |
|
no longer working on chromium
2012/10/11 09:07:25
Are you sure that you want to update the observer_
justinlin
2012/10/11 19:41:51
We might remove the "requested" state notification
|
| + MediaStreamRequest::STATE_REQUESTED); |
| + UpdateRequestState(&request, options.audio_type, |
| + MediaStreamRequest::STATE_PENDING_APPROVAL); |
| + devices.push_back( |
| + StreamDeviceInfo(options.audio_type, device_id, device_id, false)); |
| } |
| if (content::IsVideoMediaType(options.video_type)) { |
| - request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL; |
| - device_settings_->AvailableDevices( |
| - *label, options.video_type, StreamDeviceInfoArray( |
| - 1, StreamDeviceInfo(options.video_type, device_id, device_id, |
| - false))); |
| + UpdateRequestState(&request, options.video_type, |
| + MediaStreamRequest::STATE_REQUESTED); |
| + UpdateRequestState(&request, options.video_type, |
| + MediaStreamRequest::STATE_PENDING_APPROVAL); |
| + devices.push_back( |
| + StreamDeviceInfo(options.video_type, device_id, device_id, false)); |
| } |
| + DevicesAccepted(*label, devices); |
|
no longer working on chromium
2012/10/11 09:07:25
?? It is bypassing the infobar, don't you need use
justinlin
2012/10/11 19:41:51
Yes, I think we eventually want to add a notificat
wjia(left Chromium)
2012/10/11 20:21:07
you need post a task, instead of calling DevicesAc
justinlin
2012/10/11 21:19:21
Done. Thanks.
|
| } |
| void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
| @@ -245,7 +279,8 @@ void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
| for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
| ++i) { |
| const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| - if (request.state[stream_type] != DeviceRequest::STATE_OPENING) { |
| + if (request.getState(stream_type) != |
| + MediaStreamRequest::STATE_OPENING) { |
| continue; |
| } |
| for (StreamDeviceInfoArray::const_iterator device_it = |
| @@ -280,6 +315,12 @@ void MediaStreamManager::StopGeneratedStream(const std::string& label) { |
| } |
| if (it->second.type == DeviceRequest::GENERATE_STREAM && |
| RequestDone(it->second)) { |
| + // Notify observers that this device is being closed. |
| + for (MediaStreamType i = content::MEDIA_NO_SERVICE; |
| + i != content::NUM_MEDIA_TYPES; ++i) { |
| + if (it->second.getState(i) != MediaStreamRequest::STATE_NOT_REQUESTED) |
| + UpdateRequestState(&it->second, i, MediaStreamRequest::STATE_CLOSING); |
|
no longer working on chromium
2012/10/11 09:07:25
I think I have already asked the question before,
justinlin
2012/10/11 19:41:51
Right, for now probably not. Added short-circuit i
|
| + } |
| NotifyObserverDevicesClosed(&(it->second)); |
| } |
| requests_.erase(it); |
| @@ -319,7 +360,8 @@ void MediaStreamManager::EnumerateDevices( |
| if (cache->valid) { |
| // Cached device list of this type exists. Just send it out. |
| - new_request.state[type] = DeviceRequest::STATE_REQUESTED; |
| + UpdateRequestState(&new_request, type, |
| + MediaStreamRequest::STATE_REQUESTED); |
| AddRequest(new_request, label); |
| // Need to post a task since the requester won't have label till |
| // this function returns. |
| @@ -423,7 +465,8 @@ void MediaStreamManager::StartEnumeration( |
| ++i) { |
| const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| if (Requested(new_request->options, stream_type)) { |
| - new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; |
| + UpdateRequestState(new_request, stream_type, |
| + MediaStreamRequest::STATE_REQUESTED); |
| DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| if (active_enumeration_ref_count_[stream_type] == 0) { |
| ++active_enumeration_ref_count_[stream_type]; |
| @@ -502,7 +545,8 @@ void MediaStreamManager::Opened(MediaStreamType stream_type, |
| return; |
| } |
| - DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); |
| + DCHECK_NE(request->getState(stream_type), |
| + MediaStreamRequest::STATE_REQUESTED); |
| // Check if all devices for this stream type are opened. Update the state if |
| // they are. |
| @@ -516,7 +560,8 @@ void MediaStreamManager::Opened(MediaStreamType stream_type, |
| return; |
| } |
| } |
| - request->state[stream_type] = DeviceRequest::STATE_DONE; |
| + |
| + UpdateRequestState(request, stream_type, MediaStreamRequest::STATE_DONE); |
| if (!RequestDone(*request)) { |
| // This stream_type is done, but not the other type. |
| @@ -583,10 +628,12 @@ void MediaStreamManager::DevicesEnumerated( |
| std::list<std::string> label_list; |
| for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
| ++it) { |
| - if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && |
| + if (it->second.getState(stream_type) == |
| + MediaStreamRequest::STATE_REQUESTED && |
| Requested(it->second.options, stream_type)) { |
| if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) |
| - it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; |
| + UpdateRequestState(&it->second, stream_type, |
| + MediaStreamRequest::STATE_PENDING_APPROVAL); |
| label_list.push_back(it->first); |
| } |
| } |
| @@ -607,8 +654,8 @@ void MediaStreamManager::DevicesEnumerated( |
| device.in_use = false; |
| device.session_id = |
| GetDeviceManager(device_it->stream_type)->Open(device); |
| - request.state[device_it->stream_type] = |
| - DeviceRequest::STATE_OPENING; |
| + UpdateRequestState(&request, device_it->stream_type, |
| + MediaStreamRequest::STATE_OPENING); |
| request.devices.push_back(device); |
| break; |
| } |
| @@ -656,8 +703,9 @@ void MediaStreamManager::Error(MediaStreamType stream_type, |
| // We've found the failing device. Find the error case: |
| // An error should only be reported to the MediaStreamManager if |
| // the request has not been fulfilled yet. |
| - DCHECK(it->second.state[stream_type] != DeviceRequest::STATE_DONE); |
| - if (it->second.state[stream_type] != DeviceRequest::STATE_DONE) { |
| + DCHECK(it->second.getState(stream_type) |
| + != MediaStreamRequest::STATE_DONE); |
| + if (it->second.getState(stream_type) != MediaStreamRequest::STATE_DONE) { |
| // Request is not done, devices are not opened in this case. |
| if (devices.size() <= 1) { |
| // 1. Device not opened and no other devices for this request -> |
| @@ -701,12 +749,14 @@ void MediaStreamManager::DevicesAccepted(const std::string& label, |
| // Set in_use to false to be able to track if this device has been |
| // opened. in_use might be true if the device type can be used in more |
| // than one session. |
| - DCHECK_EQ(request.state[device_it->stream_type], |
| - DeviceRequest::STATE_PENDING_APPROVAL); |
| + DCHECK_EQ(request.getState(device_it->stream_type), |
| + MediaStreamRequest::STATE_PENDING_APPROVAL); |
| device_info.in_use = false; |
| + |
| device_info.session_id = |
| GetDeviceManager(device_info.stream_type)->Open(device_info); |
| - request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING; |
| + UpdateRequestState(&request, device_it->stream_type, |
| + MediaStreamRequest::STATE_OPENING); |
| request.devices.push_back(device_info); |
| if (device_info.stream_type == request.options.audio_type) { |
| @@ -718,10 +768,12 @@ void MediaStreamManager::DevicesAccepted(const std::string& label, |
| // Check whether we've received all stream types requested. |
| if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { |
| - request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR; |
| + UpdateRequestState(&request, request.options.audio_type, |
| + MediaStreamRequest::STATE_ERROR); |
| } |
| if (!found_video && content::IsVideoMediaType(request.options.video_type)) { |
| - request.state[request.options.video_type] = DeviceRequest::STATE_ERROR; |
| + UpdateRequestState(&request, request.options.video_type, |
| + MediaStreamRequest::STATE_ERROR); |
| } |
| } |
| @@ -805,17 +857,19 @@ bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
| content::IsVideoMediaType(request.options.video_type); |
| const bool audio_done = |
| - !requested_audio || |
| - request.state[request.options.audio_type] == DeviceRequest::STATE_DONE || |
| - request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR; |
| + !requested_audio || request.getState(request.options.audio_type) == |
| + MediaStreamRequest::STATE_DONE || |
| + request.getState(request.options.audio_type) == |
| + MediaStreamRequest::STATE_ERROR; |
| if (!audio_done) { |
| return false; |
| } |
| const bool video_done = |
| - !requested_video || |
| - request.state[request.options.video_type] == DeviceRequest::STATE_DONE || |
| - request.state[request.options.video_type] == DeviceRequest::STATE_ERROR; |
| + !requested_video || request.getState(request.options.video_type) == |
| + MediaStreamRequest::STATE_DONE || |
| + request.getState(request.options.video_type) == |
| + MediaStreamRequest::STATE_ERROR; |
| if (!video_done) { |
| return false; |
| } |