Index: content/browser/renderer_host/media/media_stream_ui_controller.cc |
diff --git a/content/browser/renderer_host/media/media_stream_ui_controller.cc b/content/browser/renderer_host/media/media_stream_ui_controller.cc |
deleted file mode 100644 |
index 115bfd670950a0cf0660b161491bc9175f64ba70..0000000000000000000000000000000000000000 |
--- a/content/browser/renderer_host/media/media_stream_ui_controller.cc |
+++ /dev/null |
@@ -1,336 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/browser/renderer_host/media/media_stream_ui_controller.h" |
- |
-#include <algorithm> |
- |
-#include "base/bind.h" |
-#include "base/callback.h" |
-#include "base/logging.h" |
-#include "base/message_loop_proxy.h" |
-#include "base/stl_util.h" |
-#include "content/browser/renderer_host/media/media_stream_settings_requester.h" |
-#include "content/browser/renderer_host/render_view_host_delegate.h" |
-#include "content/browser/renderer_host/render_view_host_impl.h" |
-#include "content/common/media/media_stream_options.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/content_browser_client.h" |
-#include "content/public/browser/media_observer.h" |
-#include "content/public/common/media_stream_request.h" |
-#include "googleurl/src/gurl.h" |
-#include "media/base/bind_to_loop.h" |
- |
-namespace content { |
- |
-// UI request contains all data needed to keep track of requests between the |
-// different calls. |
-class MediaStreamRequestForUI : public MediaStreamRequest { |
- public: |
- MediaStreamRequestForUI(int render_pid, |
- int render_vid, |
- const GURL& origin, |
- const StreamOptions& options, |
- MediaStreamRequestType request_type, |
- const std::string& requested_device_id) |
- : MediaStreamRequest(render_pid, render_vid, origin, |
- request_type, requested_device_id, |
- options.audio_type, options.video_type), |
- posted_task(false) { |
- DCHECK(IsAudioMediaType(options.audio_type) || |
- IsVideoMediaType(options.video_type)); |
- } |
- |
- ~MediaStreamRequestForUI() {} |
- |
- // Whether or not a task was posted to make the call to |
- // RequestMediaAccessPermission, to make sure that we never post twice to it. |
- bool posted_task; |
-}; |
- |
-namespace { |
- |
-// Sends the request to the appropriate WebContents. |
-void ProceedMediaAccessPermission(const MediaStreamRequestForUI& request, |
- const MediaResponseCallback& callback) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- // Send the permission request to the web contents. |
- RenderViewHostImpl* host = RenderViewHostImpl::FromID( |
- request.render_process_id, request.render_view_id); |
- |
- // Tab may have gone away. |
- if (!host || !host->GetDelegate()) { |
- callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); |
- return; |
- } |
- |
- host->GetDelegate()->RequestMediaAccessPermission(request, callback); |
-} |
- |
-} // namespace |
- |
-MediaStreamUIController::MediaStreamUIController(SettingsRequester* requester) |
- : requester_(requester), |
- use_fake_ui_(false) { |
- DCHECK(requester_); |
-} |
- |
-MediaStreamUIController::~MediaStreamUIController() { |
- DCHECK(requests_.empty()); |
- DCHECK(stream_indicators_.empty()); |
-} |
- |
-void MediaStreamUIController::MakeUIRequest( |
- const std::string& label, |
- int render_process_id, |
- int render_view_id, |
- const StreamOptions& request_options, |
- const GURL& security_origin, MediaStreamRequestType request_type, |
- const std::string& requested_device_id) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- // Create a new request. |
- if (!requests_.insert( |
- std::make_pair(label, new MediaStreamRequestForUI( |
- render_process_id, render_view_id, security_origin, |
- request_options, request_type, requested_device_id))).second) { |
- NOTREACHED(); |
- } |
- |
- if (use_fake_ui_) { |
- PostRequestToFakeUI(label); |
- return; |
- } |
- |
- // The UI can handle only one request at the time, do not post the |
- // request to the view if the UI is handling any other request. |
- if (IsUIBusy(render_process_id, render_view_id)) |
- return; |
- |
- PostRequestToUI(label); |
-} |
- |
-void MediaStreamUIController::CancelUIRequest(const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- UIRequests::iterator request_iter = requests_.find(label); |
- if (request_iter != requests_.end()) { |
- // Proceed the next pending request for the same page. |
- scoped_ptr<MediaStreamRequestForUI> request(request_iter->second); |
- int render_view_id = request->render_view_id; |
- int render_process_id = request->render_process_id; |
- bool was_posted = request->posted_task; |
- |
- // TODO(xians): Post a cancel request on UI thread to dismiss the infobar |
- // if request has been sent to the UI. |
- // Remove the request from the queue. |
- requests_.erase(request_iter); |
- |
- // Simply return if the canceled request has not been brought to UI. |
- if (!was_posted) |
- return; |
- |
- // Process the next pending request to replace the old infobar on the same |
- // page. |
- ProcessNextRequestForView(render_process_id, render_view_id); |
- } |
- |
- NotifyUIIndicatorDevicesClosed(label); |
-} |
- |
-void MediaStreamUIController::ProcessAccessRequestResponse( |
- const std::string& label, |
- const MediaStreamDevices& devices, |
- scoped_ptr<MediaStreamUI> stream_ui) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- UIRequests::iterator request_iter = requests_.find(label); |
- // Return if the request has been removed. |
- if (request_iter == requests_.end()) { |
- if (stream_ui) { |
- BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, |
- stream_ui.release()); |
- } |
- return; |
- } |
- |
- DCHECK(requester_); |
- scoped_ptr<MediaStreamRequestForUI> request(request_iter->second); |
- requests_.erase(request_iter); |
- |
- // Look for queued requests for the same view. If there is a pending request, |
- // post it for user approval. |
- ProcessNextRequestForView(request->render_process_id, |
- request->render_view_id); |
- |
- if (!devices.empty()) { |
- if (stream_ui) { |
- DCHECK(stream_indicators_.find(label) == stream_indicators_.end()); |
- stream_indicators_[label] = stream_ui.release(); |
- } |
- |
- // Build a list of "full" device objects for the accepted devices. |
- StreamDeviceInfoArray device_list; |
- // TODO(xians): figure out if it is all right to hard code in_use to false, |
- // though DevicesAccepted seems to do so. |
- for (MediaStreamDevices::const_iterator dev = devices.begin(); |
- dev != devices.end(); ++dev) { |
- device_list.push_back(StreamDeviceInfo( |
- dev->type, dev->name, dev->id, |
- dev->sample_rate, dev->channel_layout, false)); |
- } |
- |
- requester_->DevicesAccepted(label, device_list); |
- } else { |
- DCHECK(!stream_ui); |
- requester_->SettingsError(label); |
- } |
-} |
- |
-void MediaStreamUIController::NotifyUIIndicatorDevicesOpened( |
- const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- IndicatorsMap::iterator it = stream_indicators_.find(label); |
- if (it != stream_indicators_.end()) { |
- base::Closure stop_callback = media::BindToLoop( |
- base::MessageLoopProxy::current(), |
- base::Bind(&MediaStreamUIController::OnStopStreamFromUI, |
- base::Unretained(this), label)); |
- |
- // base::Unretained is safe here because the target can be deleted only on |
- // UI thread when posted from IO thread (see |
- // NotifyUIIndicatorDevicesClosed()). |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&MediaStreamUI::OnStarted, |
- base::Unretained(it->second), stop_callback)); |
- } |
-} |
- |
-void MediaStreamUIController::NotifyUIIndicatorDevicesClosed( |
- const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- IndicatorsMap::iterator indicator = stream_indicators_.find(label); |
- if (indicator != stream_indicators_.end()) { |
- BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, indicator->second); |
- stream_indicators_.erase(indicator); |
- } |
-} |
- |
-void MediaStreamUIController::UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- use_fake_ui_ = true; |
- fake_ui_ = fake_ui.Pass(); |
-} |
- |
-bool MediaStreamUIController::IsUIBusy(int render_process_id, |
- int render_view_id) { |
- for (UIRequests::iterator it = requests_.begin(); |
- it != requests_.end(); ++it) { |
- if (it->second->render_process_id == render_process_id && |
- it->second->render_view_id == render_view_id && |
- it->second->posted_task) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-void MediaStreamUIController::ProcessNextRequestForView( |
- int render_process_id, |
- int render_view_id) { |
- std::string next_request_label; |
- for (UIRequests::iterator it = requests_.begin(); it != requests_.end(); |
- ++it) { |
- if (it->second->render_process_id == render_process_id && |
- it->second->render_view_id == render_view_id) { |
- // This request belongs to the given render view. |
- if (!it->second->posted_task) { |
- next_request_label = it->first; |
- break; |
- } |
- } |
- } |
- |
- if (next_request_label.empty()) |
- return; |
- |
- if (fake_ui_) { |
- PostRequestToFakeUI(next_request_label); |
- } else { |
- PostRequestToUI(next_request_label); |
- } |
-} |
- |
-void MediaStreamUIController::PostRequestToUI(const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- UIRequests::iterator request_iter = requests_.find(label); |
- |
- if (request_iter == requests_.end()) { |
- NOTREACHED(); |
- return; |
- } |
- MediaStreamRequestForUI* request = request_iter->second; |
- DCHECK(request != NULL); |
- |
- request->posted_task = true; |
- |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, base::Bind( |
- &ProceedMediaAccessPermission, *request, media::BindToLoop( |
- base::MessageLoopProxy::current(), base::Bind( |
- &MediaStreamUIController::ProcessAccessRequestResponse, |
- base::Unretained(this), label)))); |
-} |
- |
-void MediaStreamUIController::PostRequestToFakeUI(const std::string& label) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK(requester_); |
- UIRequests::iterator request_iter = requests_.find(label); |
- DCHECK(request_iter != requests_.end()); |
- MediaStreamRequestForUI* request = request_iter->second; |
- |
- MediaStreamDevices devices; |
- requester_->GetAvailableDevices(&devices); |
- MediaStreamDevices devices_to_use; |
- bool accepted_audio = false; |
- bool accepted_video = false; |
- // Use the first capture device of the same media type in the list for the |
- // fake UI. |
- for (MediaStreamDevices::const_iterator it = devices.begin(); |
- it != devices.end(); ++it) { |
- if (!accepted_audio && |
- IsAudioMediaType(request->audio_type) && |
- IsAudioMediaType(it->type)) { |
- devices_to_use.push_back(*it); |
- accepted_audio = true; |
- } else if (!accepted_video && |
- IsVideoMediaType(request->video_type) && |
- IsVideoMediaType(it->type)) { |
- devices_to_use.push_back(*it); |
- accepted_video = true; |
- } |
- } |
- |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&MediaStreamUIController::ProcessAccessRequestResponse, |
- base::Unretained(this), label, devices_to_use, |
- base::Passed(&fake_ui_))); |
-} |
- |
-void MediaStreamUIController::OnStopStreamFromUI(const std::string& label) { |
- // It's safe to base::Unretained() here because |requester_| references |
- // MediaStreamManager which always outlives IO thread. |
- // |
- // TODO(sergeyu): Refactor this code to not rely on what |requester_| is. |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&SettingsRequester::StopStreamFromUI, |
- base::Unretained(requester_), label)); |
-} |
- |
-} // namespace content |