summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc52
-rw-r--r--chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h4
-rw-r--r--chrome/browser/extensions/api/tab_capture/tab_capture_api.cc44
-rw-r--r--chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc12
-rw-r--r--chrome/browser/extensions/api/tab_capture/tab_capture_performancetest.cc2
-rw-r--r--chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc406
-rw-r--r--chrome/browser/extensions/api/tab_capture/tab_capture_registry.h71
-rw-r--r--chrome/browser/media/desktop_streams_registry.cc11
-rw-r--r--chrome/browser/media/desktop_streams_registry.h12
-rw-r--r--chrome/browser/media/media_capture_devices_dispatcher.cc57
-rw-r--r--chrome/browser/media/media_capture_devices_dispatcher.h14
-rw-r--r--chrome/browser/ui/ash/media_delegate_chromeos.cc4
-rw-r--r--chrome/browser/ui/ash/media_delegate_chromeos.h4
-rw-r--r--chrome/test/data/extensions/api_test/tab_capture/api_tests.js60
-rw-r--r--chrome/test/data/extensions/api_test/tab_capture/manifest.json2
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.cc9
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.h8
-rw-r--r--content/browser/media/capture/web_contents_audio_input_stream.cc39
-rw-r--r--content/browser/media/capture/web_contents_audio_input_stream.h2
-rw-r--r--content/browser/media/capture/web_contents_capture_util.cc30
-rw-r--r--content/browser/media/capture/web_contents_capture_util.h11
-rw-r--r--content/browser/media/capture/web_contents_tracker.cc19
-rw-r--r--content/browser/media/capture/web_contents_tracker.h27
-rw-r--r--content/browser/media/capture/web_contents_video_capture_device.cc41
-rw-r--r--content/browser/media/capture/web_contents_video_capture_device.h20
-rw-r--r--content/browser/media/capture/web_contents_video_capture_device_unittest.cc16
-rw-r--r--content/browser/renderer_host/media/DEPS8
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter.cc2
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter.h10
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter_unittest.cc4
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host.cc61
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host.h30
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc47
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.cc105
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.h24
-rw-r--r--content/browser/renderer_host/media/media_stream_manager_unittest.cc8
-rw-r--r--content/browser/renderer_host/media/media_stream_requester.h14
-rw-r--r--content/browser/renderer_host/media/media_stream_ui_proxy.cc40
-rw-r--r--content/browser/renderer_host/media/media_stream_ui_proxy.h10
-rw-r--r--content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc19
-rw-r--r--content/browser/renderer_host/media/mock_media_observer.h4
-rw-r--r--content/browser/renderer_host/media/video_capture_host_unittest.cc20
-rw-r--r--content/browser/renderer_host/render_view_host_delegate.h8
-rw-r--r--content/browser/speech/speech_recognition_dispatcher_host.cc9
-rw-r--r--content/browser/speech/speech_recognition_dispatcher_host.h1
-rw-r--r--content/browser/speech/speech_recognition_manager_impl.cc2
-rw-r--r--content/common/media/media_stream_messages.h14
-rw-r--r--content/common/media/media_stream_options.cc12
-rw-r--r--content/public/browser/media_observer.h4
-rw-r--r--content/public/browser/speech_recognition_session_context.cc1
-rw-r--r--content/public/browser/speech_recognition_session_context.h1
-rw-r--r--content/public/common/media_stream_request.cc4
-rw-r--r--content/public/common/media_stream_request.h8
-rw-r--r--content/public/renderer/render_frame_observer.h4
-rw-r--r--content/renderer/media/media_stream_audio_source.cc18
-rw-r--r--content/renderer/media/media_stream_audio_source.h8
-rw-r--r--content/renderer/media/media_stream_dispatcher.cc52
-rw-r--r--content/renderer/media/media_stream_dispatcher.h16
-rw-r--r--content/renderer/media/media_stream_dispatcher_unittest.cc2
-rw-r--r--content/renderer/media/media_stream_impl.cc153
-rw-r--r--content/renderer/media/media_stream_impl.h51
-rw-r--r--content/renderer/media/media_stream_impl_unittest.cc30
-rw-r--r--content/renderer/media/webrtc_audio_renderer.cc14
-rw-r--r--content/renderer/media/webrtc_local_audio_renderer.cc12
-rw-r--r--content/renderer/pepper/pepper_audio_input_host.cc24
-rw-r--r--content/renderer/pepper/pepper_media_device_manager.cc58
-rw-r--r--content/renderer/pepper/pepper_media_device_manager.h21
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input.cc57
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input.h11
-rw-r--r--content/renderer/pepper/pepper_platform_video_capture.cc43
-rw-r--r--content/renderer/pepper/pepper_platform_video_capture.h9
-rw-r--r--content/renderer/pepper/pepper_video_capture_host.cc15
-rw-r--r--content/renderer/render_frame_impl.cc41
-rw-r--r--content/renderer/render_frame_impl.h17
-rw-r--r--content/renderer/render_view_impl.cc7
-rw-r--r--content/renderer/render_view_impl.h9
-rw-r--r--content/shell/renderer/test_runner/web_test_proxy.h3
77 files changed, 1071 insertions, 1051 deletions
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
index 91f5c76..7904696 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/tabs.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -52,9 +53,7 @@ void DesktopCaptureChooseDesktopMediaFunction::SetPickerFactoryForTests(
}
DesktopCaptureChooseDesktopMediaFunction::
- DesktopCaptureChooseDesktopMediaFunction()
- : render_process_id_(0),
- render_view_id_(0) {
+ DesktopCaptureChooseDesktopMediaFunction() {
}
DesktopCaptureChooseDesktopMediaFunction::
@@ -90,8 +89,8 @@ bool DesktopCaptureChooseDesktopMediaFunction::RunAsync() {
DesktopCaptureRequestsRegistry::GetInstance()->AddRequest(
render_view_host()->GetProcess()->GetID(), request_id_, this);
- gfx::NativeWindow parent_window = NULL;
- content::RenderViewHost* render_view = NULL;
+ // |web_contents| is the WebContents for which the stream is created, and will
+ // also be used to determine where to show the picker's UI.
content::WebContents* web_contents = NULL;
base::string16 target_name;
if (params->target_tab) {
@@ -120,37 +119,21 @@ bool DesktopCaptureChooseDesktopMediaFunction::RunAsync() {
error_ = kInvalidTabIdError;
return false;
}
+ DCHECK(web_contents);
- GURL current_origin_ =
- web_contents->GetLastCommittedURL().GetOrigin();
- if (current_origin_ != origin_) {
+ if (origin_ != web_contents->GetLastCommittedURL().GetOrigin()) {
error_ = kTabUrlChangedError;
return false;
}
-
- // Register to be notified when the tab is closed.
- Observe(web_contents);
-
- render_view = web_contents->GetRenderViewHost();
- parent_window = web_contents->GetTopLevelNativeWindow();
} else {
origin_ = GetExtension()->url();
target_name = base::UTF8ToUTF16(GetExtension()->name());
- render_view = render_view_host();
-
- web_contents = GetAssociatedWebContents();
- if (web_contents) {
- parent_window = web_contents->GetTopLevelNativeWindow();
- } else {
-#if defined(USE_ASH)
- if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
- parent_window = ash::Shell::GetPrimaryRootWindow();
-#endif
- }
+ web_contents = content::WebContents::FromRenderViewHost(render_view_host());
+ DCHECK(web_contents);
}
- render_process_id_ = render_view->GetProcess()->GetID();
- render_view_id_ = render_view->GetRoutingID();
+ // Register to be notified when the tab is closed.
+ Observe(web_contents);
bool show_screens = false;
bool show_windows = false;
@@ -181,6 +164,8 @@ bool DesktopCaptureChooseDesktopMediaFunction::RunAsync() {
return false;
}
+ const gfx::NativeWindow parent_window =
+ web_contents->GetTopLevelNativeWindow();
scoped_ptr<DesktopMediaList> media_list;
if (g_picker_factory) {
media_list = g_picker_factory->CreateModel(
@@ -234,13 +219,20 @@ void DesktopCaptureChooseDesktopMediaFunction::WebContentsDestroyed() {
void DesktopCaptureChooseDesktopMediaFunction::OnPickerDialogResults(
content::DesktopMediaID source) {
std::string result;
- if (source.type != content::DesktopMediaID::TYPE_NONE) {
+ if (source.type != content::DesktopMediaID::TYPE_NONE &&
+ web_contents()) {
DesktopStreamsRegistry* registry =
MediaCaptureDevicesDispatcher::GetInstance()->
GetDesktopStreamsRegistry();
+ // TODO(miu): Once render_frame_host() is being set, we should register the
+ // exact RenderFrame requesting the stream, not the main RenderFrame. With
+ // that change, also update
+ // MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest().
+ // http://crbug.com/304341
+ content::RenderFrameHost* const main_frame = web_contents()->GetMainFrame();
result = registry->RegisterStream(
- render_process_id_,
- render_view_id_,
+ main_frame->GetProcess()->GetID(),
+ main_frame->GetRoutingID(),
origin_,
source,
GetExtension()->name());
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
index 7c3af4b..475edf9 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
@@ -58,9 +58,7 @@ class DesktopCaptureChooseDesktopMediaFunction
int request_id_;
- // Parameters of the tab the stream is requested for.
- int render_process_id_;
- int render_view_id_;
+ // URL of page that desktop capture was requested for.
GURL origin_;
scoped_ptr<DesktopMediaPicker> picker_;
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
index c88fbc9..82f528d 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
@@ -16,12 +16,12 @@
#include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
#include "chrome/browser/extensions/extension_renderer_state.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sessions/session_tab_helper.h"
+#include "chrome/browser/sessions/session_id.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/features/simple_feature.h"
@@ -85,12 +85,11 @@ bool TabCaptureCaptureFunction::RunSync() {
const Extension* extension = GetExtension();
const std::string& extension_id = extension->id();
- const int tab_id = SessionID::IdForTab(target_contents);
-
// Make sure either we have been granted permission to capture through an
// extension icon click or our extension is whitelisted.
if (!extension->permissions_data()->HasAPIPermissionForTab(
- tab_id, APIPermission::kTabCaptureForTab) &&
+ SessionID::IdForTab(target_contents),
+ APIPermission::kTabCaptureForTab) &&
CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kWhitelistedExtensionID) != extension_id &&
!SimpleFeature::IsIdInList(
@@ -102,10 +101,6 @@ bool TabCaptureCaptureFunction::RunSync() {
return false;
}
- content::RenderViewHost* const rvh = target_contents->GetRenderViewHost();
- int render_process_id = rvh->GetProcess()->GetID();
- int routing_id = rvh->GetRoutingID();
-
// Create a constraints vector. We will modify all the constraints in this
// vector to append our chrome specific constraints.
std::vector<MediaStreamConstraint*> constraints;
@@ -131,8 +126,13 @@ bool TabCaptureCaptureFunction::RunSync() {
}
// Device id we use for Tab Capture.
- std::string device_id =
- base::StringPrintf("%i:%i", render_process_id, routing_id);
+ content::RenderFrameHost* const main_frame = target_contents->GetMainFrame();
+ // TODO(miu): We should instead use a "randomly generated device ID" scheme,
+ // like that employed by the desktop capture API. http://crbug.com/163100
+ const std::string device_id = base::StringPrintf(
+ "web-contents-media-stream://%i:%i",
+ main_frame->GetProcess()->GetID(),
+ main_frame->GetRoutingID());
// Append chrome specific tab constraints.
for (std::vector<MediaStreamConstraint*>::iterator it = constraints.begin();
@@ -144,11 +144,7 @@ bool TabCaptureCaptureFunction::RunSync() {
extensions::TabCaptureRegistry* registry =
extensions::TabCaptureRegistry::Get(GetProfile());
- if (!registry->AddRequest(render_process_id,
- routing_id,
- extension_id,
- tab_id,
- tab_capture::TAB_CAPTURE_STATE_NONE)) {
+ if (!registry->AddRequest(target_contents, extension_id)) {
error_ = kCapturingSameTab;
return false;
}
@@ -166,19 +162,9 @@ bool TabCaptureCaptureFunction::RunSync() {
bool TabCaptureGetCapturedTabsFunction::RunSync() {
extensions::TabCaptureRegistry* registry =
extensions::TabCaptureRegistry::Get(GetProfile());
-
- const TabCaptureRegistry::RegistryCaptureInfo& captured_tabs =
- registry->GetCapturedTabs(GetExtension()->id());
-
- base::ListValue *list = new base::ListValue();
- for (TabCaptureRegistry::RegistryCaptureInfo::const_iterator it =
- captured_tabs.begin(); it != captured_tabs.end(); ++it) {
- scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo());
- info->tab_id = it->first;
- info->status = it->second;
- list->Append(info->ToValue().release());
- }
-
+ base::ListValue* const list = new base::ListValue();
+ if (registry)
+ registry->GetCapturedTabs(GetExtension()->id(), list);
SetResult(list);
return true;
}
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
index 9af7934..bbca11a 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -11,8 +11,8 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
#include "chrome/common/chrome_version_info.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/switches.h"
@@ -119,11 +119,11 @@ IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_GetUserMediaTest) {
content::PAGE_TRANSITION_LINK, false);
content::WebContents* web_contents = browser()->OpenURL(params);
- content::RenderViewHost* const rvh = web_contents->GetRenderViewHost();
- int render_process_id = rvh->GetProcess()->GetID();
- int routing_id = rvh->GetRoutingID();
-
- listener.Reply(base::StringPrintf("%i:%i", render_process_id, routing_id));
+ content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
+ ASSERT_TRUE(main_frame);
+ listener.Reply(base::StringPrintf("web-contents-media-stream://%i:%i",
+ main_frame->GetProcess()->GetID(),
+ main_frame->GetRoutingID()));
ResultCatcher catcher;
catcher.RestrictToProfile(browser()->profile());
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_performancetest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_performancetest.cc
index 2159f52..c76694c 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_performancetest.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_performancetest.cc
@@ -21,8 +21,6 @@
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/test_switches.h"
#include "chrome/test/base/tracing.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_switches.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/features/base_feature_provider.h"
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
index 1526b7d..fa2cc8b 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -5,14 +5,11 @@
#include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
#include "base/lazy_instance.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
+#include "base/values.h"
+#include "chrome/browser/sessions/session_id.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/event_router.h"
@@ -26,89 +23,123 @@ namespace extensions {
namespace tab_capture = api::tab_capture;
-class FullscreenObserver : public content::WebContentsObserver {
+// Stores values associated with a tab capture request, maintains lifecycle
+// state, and monitors WebContents for fullscreen transition events and
+// destruction.
+class TabCaptureRegistry::LiveRequest : public content::WebContentsObserver {
public:
- FullscreenObserver(TabCaptureRequest* request,
- const TabCaptureRegistry* registry);
- virtual ~FullscreenObserver() {}
+ LiveRequest(content::WebContents* target_contents,
+ const std::string& extension_id,
+ TabCaptureRegistry* registry)
+ : content::WebContentsObserver(target_contents),
+ extension_id_(extension_id),
+ registry_(registry),
+ capture_state_(tab_capture::TAB_CAPTURE_STATE_NONE),
+ is_verified_(false),
+ // TODO(miu): This initial value for |is_fullscreened_| is a faulty
+ // assumption. http://crbug.com/350491
+ is_fullscreened_(false),
+ render_process_id_(-1),
+ render_frame_id_(-1) {
+ DCHECK(web_contents());
+ DCHECK(registry_);
+ }
- private:
- // content::WebContentsObserver implementation.
- virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE;
- virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE;
+ virtual ~LiveRequest() {}
- TabCaptureRequest* request_;
- const TabCaptureRegistry* registry_;
+ // Accessors.
+ const content::WebContents* target_contents() const {
+ return content::WebContentsObserver::web_contents();
+ }
+ const std::string& extension_id() const {
+ return extension_id_;
+ }
+ TabCaptureState capture_state() const {
+ return capture_state_;
+ }
+ bool is_verified() const {
+ return is_verified_;
+ }
- DISALLOW_COPY_AND_ASSIGN(FullscreenObserver);
-};
+ void SetIsVerified() {
+ DCHECK(!is_verified_);
+ is_verified_ = true;
+ }
-// Holds all the state related to a tab capture stream.
-struct TabCaptureRequest {
- TabCaptureRequest(int render_process_id,
- int render_view_id,
- const std::string& extension_id,
- int tab_id,
- TabCaptureState status);
- ~TabCaptureRequest();
-
- const int render_process_id;
- const int render_view_id;
- const std::string extension_id;
- const int tab_id;
- TabCaptureState status;
- TabCaptureState last_status;
- bool fullscreen;
- scoped_ptr<FullscreenObserver> fullscreen_observer;
-};
+ // TODO(miu): See TODO(miu) in VerifyRequest() below.
+ void SetOriginallyTargettedRenderFrameID(int render_process_id,
+ int render_frame_id) {
+ DCHECK_GT(render_frame_id, 0);
+ DCHECK_EQ(render_frame_id_, -1); // Setting ID only once.
+ render_process_id_ = render_process_id;
+ render_frame_id_ = render_frame_id;
+ }
-FullscreenObserver::FullscreenObserver(
- TabCaptureRequest* request,
- const TabCaptureRegistry* registry)
- : request_(request),
- registry_(registry) {
- content::RenderViewHost* const rvh =
- content::RenderViewHost::FromID(request->render_process_id,
- request->render_view_id);
- Observe(rvh ? content::WebContents::FromRenderViewHost(rvh) : NULL);
-}
+ bool WasOriginallyTargettingRenderFrameID(int render_process_id,
+ int render_frame_id) const {
+ return render_process_id_ == render_process_id &&
+ render_frame_id_ == render_frame_id;
+ }
-void FullscreenObserver::DidShowFullscreenWidget(
- int routing_id) {
- request_->fullscreen = true;
- registry_->DispatchStatusChangeEvent(request_);
-}
+ void UpdateCaptureState(TabCaptureState next_capture_state) {
+ // This method can get duplicate calls if both audio and video were
+ // requested, so return early to avoid duplicate dispatching of status
+ // change events.
+ if (capture_state_ == next_capture_state)
+ return;
-void FullscreenObserver::DidDestroyFullscreenWidget(
- int routing_id) {
- request_->fullscreen = false;
- registry_->DispatchStatusChangeEvent(request_);
-}
+ capture_state_ = next_capture_state;
+ registry_->DispatchStatusChangeEvent(this);
+ }
-TabCaptureRequest::TabCaptureRequest(
- int render_process_id,
- int render_view_id,
- const std::string& extension_id,
- const int tab_id,
- TabCaptureState status)
- : render_process_id(render_process_id),
- render_view_id(render_view_id),
- extension_id(extension_id),
- tab_id(tab_id),
- status(status),
- last_status(status),
- fullscreen(false) {
-}
+ void GetCaptureInfo(tab_capture::CaptureInfo* info) const {
+ info->tab_id = SessionID::IdForTab(web_contents());
+ info->status = capture_state_;
+ info->fullscreen = is_fullscreened_;
+ }
-TabCaptureRequest::~TabCaptureRequest() {
-}
+ protected:
+ virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE {
+ is_fullscreened_ = true;
+ if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
+ registry_->DispatchStatusChangeEvent(this);
+ }
+
+ virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE {
+ is_fullscreened_ = false;
+ if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
+ registry_->DispatchStatusChangeEvent(this);
+ }
+
+ virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) OVERRIDE {
+ is_fullscreened_ = entered_fullscreen;
+ if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
+ registry_->DispatchStatusChangeEvent(this);
+ }
+
+ virtual void WebContentsDestroyed() OVERRIDE {
+ registry_->KillRequest(this); // Deletes |this|.
+ }
+
+ private:
+ const std::string extension_id_;
+ TabCaptureRegistry* const registry_;
+ TabCaptureState capture_state_;
+ bool is_verified_;
+ bool is_fullscreened_;
+
+ // These reference the originally targetted RenderFrameHost by its ID. The
+ // RenderFrameHost may have gone away long before a LiveRequest closes, but
+ // calls to OnRequestUpdate() will always refer to this request by this ID.
+ int render_process_id_;
+ int render_frame_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(LiveRequest);
+};
TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context)
: browser_context_(context), extension_registry_observer_(this) {
MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
- registrar_.Add(this,
- chrome::NOTIFICATION_FULLSCREEN_CHANGED,
- content::NotificationService::AllSources());
extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
}
@@ -130,53 +161,18 @@ TabCaptureRegistry::GetFactoryInstance() {
return g_factory.Pointer();
}
-const TabCaptureRegistry::RegistryCaptureInfo
- TabCaptureRegistry::GetCapturedTabs(const std::string& extension_id) const {
+void TabCaptureRegistry::GetCapturedTabs(
+ const std::string& extension_id,
+ base::ListValue* list_of_capture_info) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RegistryCaptureInfo list;
- for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin();
+ DCHECK(list_of_capture_info);
+ list_of_capture_info->Clear();
+ for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
it != requests_.end(); ++it) {
- if ((*it)->extension_id == extension_id) {
- list.push_back(std::make_pair((*it)->tab_id, (*it)->status));
- }
- }
- return list;
-}
-
-void TabCaptureRegistry::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type);
- FullscreenController* fullscreen_controller =
- content::Source<FullscreenController>(source).ptr();
- const bool is_fullscreen = *content::Details<bool>(details).ptr();
- for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin();
- it != requests_.end();
- ++it) {
- // If we are exiting fullscreen mode, we only need to check if any of
- // the requests had the fullscreen flag toggled previously. The
- // fullscreen controller no longer has the reference to the fullscreen
- // web_contents here.
- if (!is_fullscreen) {
- if ((*it)->fullscreen) {
- (*it)->fullscreen = false;
- DispatchStatusChangeEvent(*it);
- break;
- }
- continue;
- }
-
- // If we are entering fullscreen mode, find whether the web_contents we
- // are capturing entered fullscreen mode.
- content::RenderViewHost* const rvh = content::RenderViewHost::FromID(
- (*it)->render_process_id, (*it)->render_view_id);
- if (rvh &&
- fullscreen_controller->IsFullscreenForTabOrPending(
- content::WebContents::FromRenderViewHost(rvh))) {
- (*it)->fullscreen = true;
- DispatchStatusChangeEvent(*it);
- break;
+ if ((*it)->is_verified() && (*it)->extension_id() == extension_id) {
+ tab_capture::CaptureInfo info;
+ (*it)->GetCaptureInfo(&info);
+ list_of_capture_info->Append(info.ToValue().release());
}
}
}
@@ -186,9 +182,9 @@ void TabCaptureRegistry::OnExtensionUnloaded(
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
// Cleanup all the requested media streams for this extension.
- for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin();
+ for (ScopedVector<LiveRequest>::iterator it = requests_.begin();
it != requests_.end();) {
- if ((*it)->extension_id == extension->id()) {
+ if ((*it)->extension_id() == extension->id()) {
it = requests_.erase(it);
} else {
++it;
@@ -196,78 +192,96 @@ void TabCaptureRegistry::OnExtensionUnloaded(
}
}
-bool TabCaptureRegistry::AddRequest(int render_process_id,
- int render_view_id,
- const std::string& extension_id,
- int tab_id,
- TabCaptureState status) {
- TabCaptureRequest* request = FindCaptureRequest(render_process_id,
- render_view_id);
+bool TabCaptureRegistry::AddRequest(content::WebContents* target_contents,
+ const std::string& extension_id) {
+ LiveRequest* const request = FindRequest(target_contents);
+
// Currently, we do not allow multiple active captures for same tab.
if (request != NULL) {
- if (request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
- request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) {
+ if (request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_ERROR) {
return false;
} else {
- DeleteCaptureRequest(render_process_id, render_view_id);
+ // Delete the request before creating its replacement (below).
+ KillRequest(request);
}
}
- requests_.push_back(new TabCaptureRequest(render_process_id,
- render_view_id,
- extension_id,
- tab_id,
- status));
+ requests_.push_back(new LiveRequest(target_contents, extension_id, this));
return true;
}
-bool TabCaptureRegistry::VerifyRequest(int render_process_id,
- int render_view_id) {
+bool TabCaptureRegistry::VerifyRequest(
+ int render_process_id,
+ int render_frame_id,
+ const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DVLOG(1) << "Verifying tabCapture request for "
- << render_process_id << ":" << render_view_id;
- // TODO(justinlin): Verify extension too.
- return (FindCaptureRequest(render_process_id, render_view_id) != NULL);
+
+ LiveRequest* const request = FindRequest(
+ content::WebContents::FromRenderFrameHost(
+ content::RenderFrameHost::FromID(
+ render_process_id, render_frame_id)));
+ if (!request)
+ return false; // Unknown RenderFrameHost ID, or frame has gone away.
+
+ // TODO(miu): We should probably also verify the origin URL, like the desktop
+ // capture API. http://crbug.com/163100
+ if (request->is_verified() ||
+ request->extension_id() != extension_id ||
+ (request->capture_state() != tab_capture::TAB_CAPTURE_STATE_NONE &&
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_PENDING))
+ return false;
+
+ // TODO(miu): The RenderFrameHost IDs should be set when LiveRequest is
+ // constructed, but ExtensionFunction does not yet support use of
+ // render_frame_host() to determine the exact RenderFrameHost for the call to
+ // AddRequest() above. Fix tab_capture_api.cc, and then fix this ugly hack.
+ // http://crbug.com/304341
+ request->SetOriginallyTargettedRenderFrameID(
+ render_process_id, render_frame_id);
+
+ request->SetIsVerified();
+ return true;
}
void TabCaptureRegistry::OnRequestUpdate(
- int render_process_id,
- int render_view_id,
- const content::MediaStreamDevice& device,
+ int original_target_render_process_id,
+ int original_target_render_frame_id,
+ content::MediaStreamType stream_type,
const content::MediaRequestState new_state) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE &&
- device.type != content::MEDIA_TAB_AUDIO_CAPTURE) {
+ if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE &&
+ stream_type != content::MEDIA_TAB_AUDIO_CAPTURE) {
return;
}
- TabCaptureRequest* request = FindCaptureRequest(render_process_id,
- render_view_id);
- if (request == NULL) {
- // TODO(justinlin): This can happen because the extension's renderer does
- // not seem to always cleanup streams correctly.
- LOG(ERROR) << "Receiving updates for deleted capture request.";
- return;
+ LiveRequest* request = FindRequest(original_target_render_process_id,
+ original_target_render_frame_id);
+ if (!request) {
+ // Fall-back: Search again using WebContents since this method may have been
+ // called before VerifyRequest() set the RenderFrameHost ID. If the
+ // RenderFrameHost has gone away, that's okay since the upcoming call to
+ // VerifyRequest() will fail, and that means the tracking of request updates
+ // doesn't matter anymore.
+ request = FindRequest(content::WebContents::FromRenderFrameHost(
+ content::RenderFrameHost::FromID(original_target_render_process_id,
+ original_target_render_frame_id)));
+ if (!request)
+ return; // Stale or invalid request update.
}
- bool opening_stream = false;
- bool stopping_stream = false;
-
TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE;
switch (new_state) {
case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL:
next_state = tab_capture::TAB_CAPTURE_STATE_PENDING;
break;
case content::MEDIA_REQUEST_STATE_DONE:
- opening_stream = true;
next_state = tab_capture::TAB_CAPTURE_STATE_ACTIVE;
break;
case content::MEDIA_REQUEST_STATE_CLOSING:
- stopping_stream = true;
next_state = tab_capture::TAB_CAPTURE_STATE_STOPPED;
break;
case content::MEDIA_REQUEST_STATE_ERROR:
- stopping_stream = true;
next_state = tab_capture::TAB_CAPTURE_STATE_ERROR;
break;
case content::MEDIA_REQUEST_STATE_OPENING:
@@ -279,76 +293,68 @@ void TabCaptureRegistry::OnRequestUpdate(
}
if (next_state == tab_capture::TAB_CAPTURE_STATE_PENDING &&
- request->status != tab_capture::TAB_CAPTURE_STATE_PENDING &&
- request->status != tab_capture::TAB_CAPTURE_STATE_NONE &&
- request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
- request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) {
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_PENDING &&
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_NONE &&
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
+ request->capture_state() != tab_capture::TAB_CAPTURE_STATE_ERROR) {
// If we end up trying to grab a new stream while the previous one was never
// terminated, then something fishy is going on.
NOTREACHED() << "Trying to capture tab with existing stream.";
return;
}
- if (opening_stream) {
- request->fullscreen_observer.reset(new FullscreenObserver(request, this));
- }
-
- if (stopping_stream) {
- request->fullscreen_observer.reset();
- }
-
- request->last_status = request->status;
- request->status = next_state;
-
- // We will get duplicate events if we requested both audio and video, so only
- // send new events.
- if (request->last_status != request->status) {
- DispatchStatusChangeEvent(request);
- }
+ request->UpdateCaptureState(next_state);
}
void TabCaptureRegistry::DispatchStatusChangeEvent(
- const TabCaptureRequest* request) const {
+ const LiveRequest* request) const {
EventRouter* router = EventRouter::Get(browser_context_);
if (!router)
return;
- scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo());
- info->tab_id = request->tab_id;
- info->status = request->status;
- info->fullscreen = request->fullscreen;
-
scoped_ptr<base::ListValue> args(new base::ListValue());
- args->Append(info->ToValue().release());
+ tab_capture::CaptureInfo info;
+ request->GetCaptureInfo(&info);
+ args->Append(info.ToValue().release());
scoped_ptr<Event> event(new Event(tab_capture::OnStatusChanged::kEventName,
args.Pass()));
event->restrict_to_browser_context = browser_context_;
- router->DispatchEventToExtension(request->extension_id, event.Pass());
+ router->DispatchEventToExtension(request->extension_id(), event.Pass());
}
-TabCaptureRequest* TabCaptureRegistry::FindCaptureRequest(
- int render_process_id, int render_view_id) const {
- for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin();
+TabCaptureRegistry::LiveRequest* TabCaptureRegistry::FindRequest(
+ const content::WebContents* target_contents) const {
+ for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
it != requests_.end(); ++it) {
- if ((*it)->render_process_id == render_process_id &&
- (*it)->render_view_id == render_view_id) {
+ if ((*it)->target_contents() == target_contents)
+ return *it;
+ }
+ return NULL;
+}
+
+TabCaptureRegistry::LiveRequest* TabCaptureRegistry::FindRequest(
+ int original_target_render_process_id,
+ int original_target_render_frame_id) const {
+ for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
+ it != requests_.end(); ++it) {
+ if ((*it)->WasOriginallyTargettingRenderFrameID(
+ original_target_render_process_id,
+ original_target_render_frame_id))
return *it;
- }
}
return NULL;
}
-void TabCaptureRegistry::DeleteCaptureRequest(int render_process_id,
- int render_view_id) {
- for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin();
+void TabCaptureRegistry::KillRequest(LiveRequest* request) {
+ for (ScopedVector<LiveRequest>::iterator it = requests_.begin();
it != requests_.end(); ++it) {
- if ((*it)->render_process_id == render_process_id &&
- (*it)->render_view_id == render_view_id) {
+ if ((*it) == request) {
requests_.erase(it);
return;
}
}
+ NOTREACHED();
}
} // namespace extensions
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h
index 54fd9e6..49f7379 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.h
@@ -14,31 +14,28 @@
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "chrome/common/extensions/api/tab_capture.h"
#include "content/public/browser/media_request_state.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_registry_observer.h"
+namespace base {
+class ListValue;
+}
+
namespace content {
class BrowserContext;
+class WebContents;
}
namespace extensions {
-struct TabCaptureRequest;
class ExtensionRegistry;
-class FullscreenObserver;
namespace tab_capture = api::tab_capture;
class TabCaptureRegistry : public BrowserContextKeyedAPI,
- public content::NotificationObserver,
public ExtensionRegistryObserver,
public MediaCaptureDevicesDispatcher::Observer {
public:
- typedef std::vector<std::pair<int, tab_capture::TabCaptureState> >
- RegistryCaptureInfo;
-
static TabCaptureRegistry* Get(content::BrowserContext* context);
// Used by BrowserContextKeyedAPI.
@@ -46,24 +43,29 @@ class TabCaptureRegistry : public BrowserContextKeyedAPI,
GetFactoryInstance();
// List all pending, active and stopped capture requests.
- const RegistryCaptureInfo GetCapturedTabs(
- const std::string& extension_id) const;
+ void GetCapturedTabs(const std::string& extension_id,
+ base::ListValue* list_of_capture_info) const;
// Add a tab capture request to the registry when a stream is requested
- // through the API.
- bool AddRequest(int render_process_id,
- int render_view_id,
- const std::string& extension_id,
- int tab_id,
- tab_capture::TabCaptureState status);
-
- // The MediaStreamDevicesController will verify the request before creating
- // the stream by checking the registry here.
- bool VerifyRequest(int render_process_id, int render_view_id);
+ // through the API. |target_contents| refers to the WebContents associated
+ // with the tab to be captured. |extension_id| refers to the Extension
+ // initiating the request.
+ bool AddRequest(content::WebContents* target_contents,
+ const std::string& extension_id);
+
+ // Called by MediaStreamDevicesController to verify the request before
+ // creating the stream. |render_process_id| and |render_frame_id| are used to
+ // look-up a WebContents instance, which should match the |target_contents|
+ // from the prior call to AddRequest(). In addition, a request is not
+ // verified unless the |extension_id| also matches AND the request itself is
+ // in the PENDING state.
+ bool VerifyRequest(int render_process_id,
+ int render_frame_id,
+ const std::string& extension_id);
private:
friend class BrowserContextKeyedAPIFactory<TabCaptureRegistry>;
- friend class FullscreenObserver;
+ class LiveRequest;
explicit TabCaptureRegistry(content::BrowserContext* context);
virtual ~TabCaptureRegistry();
@@ -76,11 +78,6 @@ class TabCaptureRegistry : public BrowserContextKeyedAPI,
static const bool kServiceIsCreatedWithBrowserContext = false;
static const bool kServiceRedirectedInIncognito = true;
- // content::NotificationObserver implementation.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
// ExtensionRegistryObserver implementation.
virtual void OnExtensionUnloaded(
content::BrowserContext* browser_context,
@@ -89,21 +86,25 @@ class TabCaptureRegistry : public BrowserContextKeyedAPI,
// MediaCaptureDevicesDispatcher::Observer implementation.
virtual void OnRequestUpdate(
- int render_process_id,
- int render_view_id,
- const content::MediaStreamDevice& device,
+ int original_target_render_process_id,
+ int original_target_render_frame_id,
+ content::MediaStreamType stream_type,
const content::MediaRequestState state) OVERRIDE;
- void DispatchStatusChangeEvent(const TabCaptureRequest* request) const;
+ // Send a StatusChanged event containing the current state of |request|.
+ void DispatchStatusChangeEvent(const LiveRequest* request) const;
- TabCaptureRequest* FindCaptureRequest(int render_process_id,
- int render_view_id) const;
+ // Look-up a LiveRequest associated with the given |target_contents| (or
+ // the originally targetted RenderFrameHost), if any.
+ LiveRequest* FindRequest(const content::WebContents* target_contents) const;
+ LiveRequest* FindRequest(int original_target_render_process_id,
+ int original_target_render_frame_id) const;
- void DeleteCaptureRequest(int render_process_id, int render_view_id);
+ // Removes the |request| from |requests_|, thus causing its destruction.
+ void KillRequest(LiveRequest* request);
- content::NotificationRegistrar registrar_;
content::BrowserContext* const browser_context_;
- ScopedVector<TabCaptureRequest> requests_;
+ ScopedVector<LiveRequest> requests_;
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_;
diff --git a/chrome/browser/media/desktop_streams_registry.cc b/chrome/browser/media/desktop_streams_registry.cc
index f2e2607..9f6a0eb 100644
--- a/chrome/browser/media/desktop_streams_registry.cc
+++ b/chrome/browser/media/desktop_streams_registry.cc
@@ -32,16 +32,17 @@ DesktopStreamsRegistry::~DesktopStreamsRegistry() {}
std::string DesktopStreamsRegistry::RegisterStream(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& origin,
const content::DesktopMediaID& source,
const std::string& extension_name) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
std::string id = GenerateRandomStreamId();
+ DCHECK(approved_streams_.find(id) == approved_streams_.end());
ApprovedDesktopMediaStream& stream = approved_streams_[id];
stream.render_process_id = render_process_id;
- stream.render_view_id = render_view_id;
+ stream.render_frame_id = render_frame_id;
stream.origin = origin;
stream.source = source;
stream.extension_name = extension_name;
@@ -58,7 +59,7 @@ std::string DesktopStreamsRegistry::RegisterStream(
content::DesktopMediaID DesktopStreamsRegistry::RequestMediaForStreamId(
const std::string& id,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& origin,
std::string* extension_name) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -69,7 +70,7 @@ content::DesktopMediaID DesktopStreamsRegistry::RequestMediaForStreamId(
// the same origin and the same renderer.
if (it == approved_streams_.end() ||
render_process_id != it->second.render_process_id ||
- render_view_id != it->second.render_view_id ||
+ render_frame_id != it->second.render_frame_id ||
origin != it->second.origin) {
return content::DesktopMediaID();
}
@@ -86,4 +87,4 @@ void DesktopStreamsRegistry::CleanupStream(const std::string& id) {
}
DesktopStreamsRegistry::ApprovedDesktopMediaStream::ApprovedDesktopMediaStream()
- : render_process_id(-1), render_view_id(-1) {}
+ : render_process_id(-1), render_frame_id(-1) {}
diff --git a/chrome/browser/media/desktop_streams_registry.h b/chrome/browser/media/desktop_streams_registry.h
index 90fb365..c497bd6 100644
--- a/chrome/browser/media/desktop_streams_registry.h
+++ b/chrome/browser/media/desktop_streams_registry.h
@@ -22,19 +22,21 @@ class DesktopStreamsRegistry {
// Adds new stream to the registry. Called by the implementation of
// desktopCapture.chooseDesktopMedia() API after user has approved access to
// |source| for the |origin|. Returns identifier of the new stream.
+ // |render_frame_id| refers to the RenderFrame requesting the stream.
std::string RegisterStream(int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& origin,
const content::DesktopMediaID& source,
const std::string& extension_name);
// Validates stream identifier specified in getUserMedia(). Returns null
// DesktopMediaID if the specified |id| is invalid, i.e. wasn't generated
- // using RegisterStream() or if it was generated for a different origin.
- // Otherwise returns ID of the source and removes it from the registry.
+ // using RegisterStream() or if it was generated for a different
+ // RenderFrame/origin. Otherwise returns ID of the source and removes it from
+ // the registry.
content::DesktopMediaID RequestMediaForStreamId(const std::string& id,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& origin,
std::string* extension_name);
@@ -44,7 +46,7 @@ class DesktopStreamsRegistry {
ApprovedDesktopMediaStream();
int render_process_id;
- int render_view_id;
+ int render_frame_id;
GURL origin;
content::DesktopMediaID source;
std::string extension_name;
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc
index 136139a..7806eb9 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/media_capture_devices_dispatcher.cc
@@ -36,6 +36,7 @@
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/media_stream_request.h"
#include "extensions/common/constants.h"
@@ -394,11 +395,24 @@ void MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest(
// The extension name that the stream is registered with.
std::string original_extension_name;
// Resolve DesktopMediaID for the specified device id.
- content::DesktopMediaID media_id =
- GetDesktopStreamsRegistry()->RequestMediaForStreamId(
- request.requested_video_device_id, request.render_process_id,
- request.render_view_id, request.security_origin,
- &original_extension_name);
+ content::DesktopMediaID media_id;
+ // TODO(miu): Replace "main RenderFrame" IDs with the request's actual
+ // RenderFrame IDs once the desktop capture extension API implementation is
+ // fixed. http://crbug.com/304341
+ content::WebContents* const web_contents_for_stream =
+ content::WebContents::FromRenderFrameHost(
+ content::RenderFrameHost::FromID(request.render_process_id,
+ request.render_frame_id));
+ content::RenderFrameHost* const main_frame = web_contents_for_stream ?
+ web_contents_for_stream->GetMainFrame() : NULL;
+ if (main_frame) {
+ media_id = GetDesktopStreamsRegistry()->RequestMediaForStreamId(
+ request.requested_video_device_id,
+ main_frame->GetProcess()->GetID(),
+ main_frame->GetRoutingID(),
+ request.security_origin,
+ &original_extension_name);
+ }
// Received invalid device id.
if (media_id.type == content::DesktopMediaID::TYPE_NONE) {
@@ -545,9 +559,8 @@ void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest(
callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
return;
}
- bool tab_capture_allowed =
- tab_capture_registry->VerifyRequest(request.render_process_id,
- request.render_view_id);
+ const bool tab_capture_allowed = tab_capture_registry->VerifyRequest(
+ request.render_process_id, request.render_frame_id, extension->id());
if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE &&
tab_capture_allowed &&
@@ -576,7 +589,7 @@ void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest(
ui.Pass());
#else // defined(ENABLE_EXTENSIONS)
callback.Run(devices, content::MEDIA_DEVICE_TAB_CAPTURE_FAILURE, ui.Pass());
-#endif // !defined(OS_ANDROID)
+#endif // defined(ENABLE_EXTENSIONS)
}
void MediaCaptureDevicesDispatcher::
@@ -804,18 +817,18 @@ void MediaCaptureDevicesDispatcher::OnVideoCaptureDevicesChanged() {
void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
- const content::MediaStreamDevice& device,
+ content::MediaStreamType stream_type,
content::MediaRequestState state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
&MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread,
- base::Unretained(this), render_process_id, render_view_id,
- page_request_id, security_origin, device, state));
+ base::Unretained(this), render_process_id, render_frame_id,
+ page_request_id, security_origin, stream_type, state));
}
void MediaCaptureDevicesDispatcher::OnAudioStreamPlaying(
@@ -877,17 +890,17 @@ void MediaCaptureDevicesDispatcher::NotifyVideoDevicesChangedOnUIThread() {
void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
- const content::MediaStreamDevice& device,
+ content::MediaStreamType stream_type,
content::MediaRequestState state) {
// Track desktop capture sessions. Tracking is necessary to avoid unbalanced
// session counts since not all requests will reach MEDIA_REQUEST_STATE_DONE,
// but they will all reach MEDIA_REQUEST_STATE_CLOSING.
- if (device.type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) {
+ if (stream_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) {
if (state == content::MEDIA_REQUEST_STATE_DONE) {
- DesktopCaptureSession session = { render_process_id, render_view_id,
+ DesktopCaptureSession session = { render_process_id, render_frame_id,
page_request_id };
desktop_capture_sessions_.push_back(session);
} else if (state == content::MEDIA_REQUEST_STATE_CLOSING) {
@@ -896,7 +909,7 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
it != desktop_capture_sessions_.end();
++it) {
if (it->render_process_id == render_process_id &&
- it->render_view_id == render_view_id &&
+ it->render_frame_id == render_frame_id &&
it->page_request_id == page_request_id) {
desktop_capture_sessions_.erase(it);
break;
@@ -914,7 +927,7 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
for (RequestsQueue::iterator it = queue.begin();
it != queue.end(); ++it) {
if (it->request.render_process_id == render_process_id &&
- it->request.render_view_id == render_view_id &&
+ it->request.render_frame_id == render_frame_id &&
it->request.page_request_id == page_request_id) {
queue.erase(it);
found = true;
@@ -927,7 +940,7 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
}
#if defined(OS_CHROMEOS)
- if (IsOriginForCasting(security_origin) && IsVideoMediaType(device.type)) {
+ if (IsOriginForCasting(security_origin) && IsVideoMediaType(stream_type)) {
// Notify ash that casting state has changed.
if (state == content::MEDIA_REQUEST_STATE_DONE) {
ash::Shell::GetInstance()->OnCastingSessionStartedOrStopped(true);
@@ -939,8 +952,8 @@ void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
FOR_EACH_OBSERVER(Observer, observers_,
OnRequestUpdate(render_process_id,
- render_view_id,
- device,
+ render_frame_id,
+ stream_type,
state));
}
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h
index 0c16f3b..6c71661 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.h
+++ b/chrome/browser/media/media_capture_devices_dispatcher.h
@@ -51,8 +51,8 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
// Handle an information update related to a media stream request.
virtual void OnRequestUpdate(
int render_process_id,
- int render_view_id,
- const content::MediaStreamDevice& device,
+ int render_frame_id,
+ content::MediaStreamType stream_type,
const content::MediaRequestState state) {}
// Handle an information update that a new stream is being created.
@@ -116,10 +116,10 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
virtual void OnVideoCaptureDevicesChanged() OVERRIDE;
virtual void OnMediaRequestStateChanged(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
- const content::MediaStreamDevice& device,
+ content::MediaStreamType stream_type,
content::MediaRequestState state) OVERRIDE;
virtual void OnCreatingAudioStream(int render_process_id,
int render_frame_id) OVERRIDE;
@@ -203,10 +203,10 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
void NotifyVideoDevicesChangedOnUIThread();
void UpdateMediaRequestStateOnUIThread(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
- const content::MediaStreamDevice& device,
+ content::MediaStreamType stream_type,
content::MediaRequestState state);
void OnCreatingAudioStreamOnUIThread(int render_process_id,
int render_frame_id);
@@ -236,7 +236,7 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
// MEDIA_REQUEST_STATE_CLOSING is encountered.
struct DesktopCaptureSession {
int render_process_id;
- int render_view_id;
+ int render_frame_id;
int page_request_id;
};
typedef std::list<DesktopCaptureSession> DesktopCaptureSessions;
diff --git a/chrome/browser/ui/ash/media_delegate_chromeos.cc b/chrome/browser/ui/ash/media_delegate_chromeos.cc
index ff92c70..6e0d151 100644
--- a/chrome/browser/ui/ash/media_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/media_delegate_chromeos.cc
@@ -157,8 +157,8 @@ ash::MediaCaptureState MediaDelegateChromeOS::GetMediaCaptureState(
void MediaDelegateChromeOS::OnRequestUpdate(
int render_process_id,
- int render_view_id,
- const content::MediaStreamDevice& device,
+ int render_frame_id,
+ content::MediaStreamType stream_type,
const content::MediaRequestState state) {
base::MessageLoopForUI::current()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/ui/ash/media_delegate_chromeos.h b/chrome/browser/ui/ash/media_delegate_chromeos.h
index 7370432..f8d8317 100644
--- a/chrome/browser/ui/ash/media_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/media_delegate_chromeos.h
@@ -24,8 +24,8 @@ class MediaDelegateChromeOS : public ash::MediaDelegate,
// MediaCaptureDevicesDispatcher::Observer:
virtual void OnRequestUpdate(int render_process_id,
- int render_view_id,
- const content::MediaStreamDevice& device,
+ int render_frame_id,
+ content::MediaStreamType stream_type,
const content::MediaRequestState state) OVERRIDE;
private:
diff --git a/chrome/test/data/extensions/api_test/tab_capture/api_tests.js b/chrome/test/data/extensions/api_test/tab_capture/api_tests.js
index a100d25..06e5022 100644
--- a/chrome/test/data/extensions/api_test/tab_capture/api_tests.js
+++ b/chrome/test/data/extensions/api_test/tab_capture/api_tests.js
@@ -29,25 +29,53 @@ chrome.test.runTests([
},
function getCapturedTabs() {
- var activeStream = null;
+ chrome.tabs.create({active:true}, function(secondTab) {
+ // chrome.tabCapture.capture() will only capture the active tab.
+ chrome.test.assertTrue(secondTab.active);
- var capturedTabsAfterClose = function(infos) {
- chrome.test.assertEq(1, infos.length);
- chrome.test.assertEq('stopped', infos[0].status);
- chrome.test.succeed();
- };
+ function checkInfoForSecondTabHasStatus(infos, status) {
+ for (var i = 0; i < infos.length; ++i) {
+ if (infos[i].tabId == secondTab) {
+ chrome.test.assertNe(null, status);
+ chrome.test.assertEq(status, infos[i].status);
+ chrome.test.assertEq(false, infos[i].fullscreen);
+ return;
+ }
+ }
+ }
- var capturedTabsAfterOpen = function(infos) {
- chrome.test.assertEq(1, infos.length);
- chrome.test.assertEq('active', infos[0].status);
- activeStream.stop();
- tabCapture.getCapturedTabs(capturedTabsAfterClose);
- };
+ // Step 4: After the second tab is closed, check that getCapturedTabs()
+ // returns no info at all about the second tab. http://crbug.com/338445
+ chrome.tabs.onRemoved.addListener(function() {
+ tabCapture.getCapturedTabs(function checkNoInfos(infos) {
+ checkInfoForSecondTabHasStatus(infos, null);
+ chrome.test.succeed();
+ });
+ });
- tabCapture.capture({audio: true, video: true}, function(stream) {
- chrome.test.assertTrue(!!stream);
- activeStream = stream;
- tabCapture.getCapturedTabs(capturedTabsAfterOpen);
+ var activeStream = null;
+
+ // Step 3: After the stream is stopped, check that getCapturedTabs()
+ // returns 'stopped' capturing status for the second tab.
+ var capturedTabsAfterStopCapture = function(infos) {
+ checkInfoForSecondTabHasStatus(infos, 'stopped');
+ chrome.tabs.remove(secondTab.id);
+ };
+
+ // Step 2: After the stream is started, check that getCapturedTabs()
+ // returns 'active' capturing status for the second tab.
+ var capturedTabsAfterStartCapture = function(infos) {
+ checkInfoForSecondTabHasStatus(infos, 'active');
+ activeStream.stop();
+ tabCapture.getCapturedTabs(capturedTabsAfterStopCapture);
+ };
+
+ // Step 1: Start capturing the second tab (the currently active tab).
+ tabCapture.capture({audio: true, video: true}, function(stream) {
+ chrome.test.assertTrue(!!stream);
+ activeStream = stream;
+ tabCapture.getCapturedTabs(capturedTabsAfterStartCapture);
+ });
});
},
diff --git a/chrome/test/data/extensions/api_test/tab_capture/manifest.json b/chrome/test/data/extensions/api_test/tab_capture/manifest.json
index 56d761c..991b2e5 100644
--- a/chrome/test/data/extensions/api_test/tab_capture/manifest.json
+++ b/chrome/test/data/extensions/api_test/tab_capture/manifest.json
@@ -5,5 +5,5 @@
"manifest_version": 2,
"description": "Tab Capture API Test Extension",
"incognito": "split",
- "permissions": ["tabCapture"]
+ "permissions": ["tabCapture","tabs"]
}
diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
index 3b7fad1..d333185 100644
--- a/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -4,6 +4,7 @@
#include <stddef.h>
+#include "base/callback.h"
#include "base/strings/string16.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "url/gurl.h"
@@ -34,4 +35,12 @@ WebContents* RenderFrameHostDelegate::GetAsWebContents() {
return NULL;
}
+void RenderFrameHostDelegate::RequestMediaAccessPermission(
+ const MediaStreamRequest& request,
+ const MediaResponseCallback& callback) {
+ callback.Run(MediaStreamDevices(),
+ MEDIA_DEVICE_INVALID_STATE,
+ scoped_ptr<MediaStreamUI>());
+}
+
} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index a49e22c..4d53936 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -9,6 +9,7 @@
#include "base/i18n/rtl.h"
#include "content/common/content_export.h"
#include "content/public/common/javascript_message_type.h"
+#include "content/public/common/media_stream_request.h"
class GURL;
@@ -111,6 +112,13 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// not a WebContents, returns NULL.
virtual WebContents* GetAsWebContents();
+ // The render frame has requested access to media devices listed in
+ // |request|, and the client should grant or deny that permission by
+ // calling |callback|.
+ virtual void RequestMediaAccessPermission(
+ const MediaStreamRequest& request,
+ const MediaResponseCallback& callback);
+
protected:
virtual ~RenderFrameHostDelegate() {}
};
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.cc b/content/browser/media/capture/web_contents_audio_input_stream.cc
index ad5a33f..9d42c2d 100644
--- a/content/browser/media/capture/web_contents_audio_input_stream.cc
+++ b/content/browser/media/capture/web_contents_audio_input_stream.cc
@@ -25,7 +25,7 @@ class WebContentsAudioInputStream::Impl
public AudioMirroringManager::MirroringDestination {
public:
// Takes ownership of |mixer_stream|. The rest outlive this instance.
- Impl(int render_process_id, int render_view_id,
+ Impl(int render_process_id, int main_render_frame_id,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream);
@@ -84,6 +84,8 @@ class WebContentsAudioInputStream::Impl
void OnTargetChanged(int render_process_id, int render_view_id);
// Injected dependencies.
+ const int initial_render_process_id_;
+ const int initial_main_render_frame_id_;
AudioMirroringManager* const mirroring_manager_;
const scoped_refptr<WebContentsTracker> tracker_;
// The AudioInputStream implementation that handles the audio conversion and
@@ -93,6 +95,7 @@ class WebContentsAudioInputStream::Impl
State state_;
// Current audio mirroring target.
+ bool target_identified_;
int target_render_process_id_;
int target_render_view_id_;
@@ -105,14 +108,19 @@ class WebContentsAudioInputStream::Impl
};
WebContentsAudioInputStream::Impl::Impl(
- int render_process_id, int render_view_id,
+ int render_process_id, int main_render_frame_id,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream)
- : mirroring_manager_(mirroring_manager),
- tracker_(tracker), mixer_stream_(mixer_stream), state_(CONSTRUCTED),
- target_render_process_id_(render_process_id),
- target_render_view_id_(render_view_id),
+ : initial_render_process_id_(render_process_id),
+ initial_main_render_frame_id_(main_render_frame_id),
+ mirroring_manager_(mirroring_manager),
+ tracker_(tracker),
+ mixer_stream_(mixer_stream),
+ state_(CONSTRUCTED),
+ target_identified_(false),
+ target_render_process_id_(-1),
+ target_render_view_id_(-1),
callback_(NULL) {
DCHECK(mirroring_manager_);
DCHECK(tracker_.get());
@@ -138,7 +146,7 @@ bool WebContentsAudioInputStream::Impl::Open() {
state_ = OPENED;
tracker_->Start(
- target_render_process_id_, target_render_view_id_,
+ initial_render_process_id_, initial_main_render_frame_id_,
base::Bind(&Impl::OnTargetChanged, this));
return true;
@@ -196,7 +204,8 @@ void WebContentsAudioInputStream::Impl::Close() {
bool WebContentsAudioInputStream::Impl::IsTargetLost() const {
DCHECK(thread_checker_.CalledOnValidThread());
-
+ if (!target_identified_)
+ return false;
return target_render_process_id_ <= 0 || target_render_view_id_ <= 0;
}
@@ -252,7 +261,8 @@ void WebContentsAudioInputStream::Impl::OnTargetChanged(int render_process_id,
int render_view_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (target_render_process_id_ == render_process_id &&
+ if (target_identified_ &&
+ target_render_process_id_ == render_process_id &&
target_render_view_id_ == render_view_id) {
return;
}
@@ -264,6 +274,7 @@ void WebContentsAudioInputStream::Impl::OnTargetChanged(int render_process_id,
if (state_ == MIRRORING)
StopMirroring();
+ target_identified_ = true;
target_render_process_id_ = render_process_id;
target_render_view_id_ = render_view_id;
@@ -284,14 +295,14 @@ WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
AudioMirroringManager* audio_mirroring_manager) {
int render_process_id;
- int render_view_id;
+ int main_render_frame_id;
if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
- device_id, &render_process_id, &render_view_id)) {
+ device_id, &render_process_id, &main_render_frame_id)) {
return NULL;
}
return new WebContentsAudioInputStream(
- render_process_id, render_view_id,
+ render_process_id, main_render_frame_id,
audio_mirroring_manager,
new WebContentsTracker(),
new media::VirtualAudioInputStream(
@@ -300,11 +311,11 @@ WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
}
WebContentsAudioInputStream::WebContentsAudioInputStream(
- int render_process_id, int render_view_id,
+ int render_process_id, int main_render_frame_id,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream)
- : impl_(new Impl(render_process_id, render_view_id,
+ : impl_(new Impl(render_process_id, main_render_frame_id,
mirroring_manager, tracker, mixer_stream)) {}
WebContentsAudioInputStream::~WebContentsAudioInputStream() {}
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.h b/content/browser/media/capture/web_contents_audio_input_stream.h
index c0a2c6a..9bdc914 100644
--- a/content/browser/media/capture/web_contents_audio_input_stream.h
+++ b/content/browser/media/capture/web_contents_audio_input_stream.h
@@ -75,7 +75,7 @@ class CONTENT_EXPORT WebContentsAudioInputStream
class Impl;
WebContentsAudioInputStream(
- int render_process_id, int render_view_id,
+ int render_process_id, int main_render_frame_id,
AudioMirroringManager* mirroring_manager,
const scoped_refptr<WebContentsTracker>& tracker,
media::VirtualAudioInputStream* mixer_stream);
diff --git a/content/browser/media/capture/web_contents_capture_util.cc b/content/browser/media/capture/web_contents_capture_util.cc
index 57b636a..e1c5d52 100644
--- a/content/browser/media/capture/web_contents_capture_util.cc
+++ b/content/browser/media/capture/web_contents_capture_util.cc
@@ -9,40 +9,24 @@
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
-namespace {
-
-const char kVirtualDeviceScheme[] = "virtual-media-stream://";
-
-} // namespace
-
namespace content {
-std::string WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
- const std::string& device_id) {
- return kVirtualDeviceScheme + device_id;
-}
-
-std::string WebContentsCaptureUtil::StripWebContentsDeviceScheme(
- const std::string& device_id) {
- return (IsWebContentsDeviceId(device_id) ?
- device_id.substr(arraysize(kVirtualDeviceScheme) - 1) :
- device_id);
-}
-
bool WebContentsCaptureUtil::IsWebContentsDeviceId(
const std::string& device_id) {
- return StartsWithASCII(device_id, kVirtualDeviceScheme, true);
+ int ignored;
+ return ExtractTabCaptureTarget(device_id, &ignored, &ignored);
}
bool WebContentsCaptureUtil::ExtractTabCaptureTarget(
const std::string& device_id_param,
int* render_process_id,
- int* render_view_id) {
- if (!IsWebContentsDeviceId(device_id_param))
+ int* main_render_frame_id) {
+ static const char kDeviceScheme[] = "web-contents-media-stream://";
+ if (!StartsWithASCII(device_id_param, kDeviceScheme, true))
return false;
const std::string device_id = device_id_param.substr(
- arraysize(kVirtualDeviceScheme) - 1);
+ arraysize(kDeviceScheme) - 1);
const size_t sep_pos = device_id.find(':');
if (sep_pos == std::string::npos)
@@ -53,7 +37,7 @@ bool WebContentsCaptureUtil::ExtractTabCaptureTarget(
device_id.length() - sep_pos - 1);
return (base::StringToInt(component1, render_process_id) &&
- base::StringToInt(component2, render_view_id));
+ base::StringToInt(component2, main_render_frame_id));
}
} // namespace content
diff --git a/content/browser/media/capture/web_contents_capture_util.h b/content/browser/media/capture/web_contents_capture_util.h
index 5f43f42..60a9113 100644
--- a/content/browser/media/capture/web_contents_capture_util.h
+++ b/content/browser/media/capture/web_contents_capture_util.h
@@ -13,21 +13,14 @@ namespace content {
class CONTENT_EXPORT WebContentsCaptureUtil {
public:
- // Returns a new id after appending the device id scheme for virtual streams.
- static std::string AppendWebContentsDeviceScheme(
- const std::string& device_id_param);
-
- static std::string StripWebContentsDeviceScheme(
- const std::string& device_id_param);
-
// Check whether the device id indicates that this is a web contents stream.
static bool IsWebContentsDeviceId(const std::string& device_id);
- // Function to extract the target renderer id's from a tab media stream
+ // Function to extract the target render frame id's from a media stream
// request's device id.
static bool ExtractTabCaptureTarget(const std::string& device_id,
int* render_process_id,
- int* render_view_id);
+ int* main_render_frame_id);
};
} // namespace content
diff --git a/content/browser/media/capture/web_contents_tracker.cc b/content/browser/media/capture/web_contents_tracker.cc
index 0765331..5bfdf4e 100644
--- a/content/browser/media/capture/web_contents_tracker.cc
+++ b/content/browser/media/capture/web_contents_tracker.cc
@@ -6,6 +6,7 @@
#include "base/message_loop/message_loop_proxy.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -18,7 +19,7 @@ WebContentsTracker::~WebContentsTracker() {
DCHECK(!web_contents()) << "BUG: Still observering!";
}
-void WebContentsTracker::Start(int render_process_id, int render_view_id,
+void WebContentsTracker::Start(int render_process_id, int main_render_frame_id,
const ChangeCallback& callback) {
DCHECK(!message_loop_.get() || message_loop_->BelongsToCurrentThread());
@@ -29,7 +30,7 @@ void WebContentsTracker::Start(int render_process_id, int render_view_id,
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&WebContentsTracker::LookUpAndObserveWebContents, this,
- render_process_id, render_view_id));
+ render_process_id, main_render_frame_id));
}
void WebContentsTracker::Stop() {
@@ -67,17 +68,15 @@ void WebContentsTracker::MaybeDoCallback(int render_process_id,
}
void WebContentsTracker::LookUpAndObserveWebContents(int render_process_id,
- int render_view_id) {
+ int main_render_frame_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- RenderViewHost* const rvh =
- RenderViewHost::FromID(render_process_id, render_view_id);
- DVLOG_IF(1, !rvh) << "RenderViewHost::FromID("
- << render_process_id << ", " << render_view_id
- << ") returned NULL.";
- Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
+ Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
+ render_process_id, main_render_frame_id)));
DVLOG_IF(1, !web_contents())
- << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL.";
+ << "Could not find WebContents associated with main RenderFrameHost "
+ << "referenced by render_process_id=" << render_process_id
+ << ", routing_id=" << main_render_frame_id;
OnWebContentsChangeEvent();
}
diff --git a/content/browser/media/capture/web_contents_tracker.h b/content/browser/media/capture/web_contents_tracker.h
index f8957f3..bd551ca 100644
--- a/content/browser/media/capture/web_contents_tracker.h
+++ b/content/browser/media/capture/web_contents_tracker.h
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Given a starting render_process_id and render_view_id, the WebContentsTracker
-// tracks RenderViewHost instance swapping during the lifetime of a WebContents
-// instance. This is used when mirroring tab video and audio so that user
-// navigations, crashes, etc., during a tab's lifetime allow the capturing code
-// to remain active on the current/latest RenderView.
+// Given a starting render_process_id and main_render_frame_id, the
+// WebContentsTracker tracks RenderViewHost instance swapping during the
+// lifetime of a WebContents instance. This is used when mirroring tab video
+// and audio so that user navigations, crashes, etc., during a tab's lifetime
+// allow the capturing code to remain active on the current/latest RenderView.
+//
+// TODO(miu): In a soon upcoming change, the cross-site isolation migration of
+// this code will be completed such that the main RenderFrameHost is tracked
+// instead of the RenderViewHost.
//
// Threading issues: Start(), Stop() and the ChangeCallback are invoked on the
// same thread. This can be any thread, and the decision is locked-in by
@@ -39,10 +43,11 @@ class CONTENT_EXPORT WebContentsTracker
typedef base::Callback<void(int render_process_id, int render_view_id)>
ChangeCallback;
- // Start tracking. The last-known |render_process_id| and |render_view_id|
- // are provided, and the given callback is invoked asynchronously one or more
- // times. The callback will be invoked on the same thread calling Start().
- virtual void Start(int render_process_id, int render_view_id,
+ // Start tracking. The last-known |render_process_id| and
+ // |main_render_frame_id| are provided, and the given callback is invoked
+ // asynchronously one or more times. The callback will be invoked on the same
+ // thread calling Start().
+ virtual void Start(int render_process_id, int main_render_frame_id,
const ChangeCallback& callback);
// Stop tracking. Once this method returns, the callback is guaranteed not to
@@ -63,9 +68,9 @@ class CONTENT_EXPORT WebContentsTracker
void MaybeDoCallback(int render_process_id, int render_view_id);
// Look-up the current WebContents instance associated with the given
- // |render_process_id| and |render_view_id| and begin observing it.
+ // |render_process_id| and |main_render_frame_id| and begin observing it.
void LookUpAndObserveWebContents(int render_process_id,
- int render_view_id);
+ int main_render_frame_id);
// WebContentsObserver overrides to react to events of interest.
virtual void RenderViewReady() OVERRIDE;
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index 47993b2..7eb2d94 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -225,7 +225,7 @@ class WebContentsCaptureMachine
: public VideoCaptureMachine,
public WebContentsObserver {
public:
- WebContentsCaptureMachine(int render_process_id, int render_view_id);
+ WebContentsCaptureMachine(int render_process_id, int main_render_frame_id);
virtual ~WebContentsCaptureMachine();
// VideoCaptureMachine overrides.
@@ -301,7 +301,7 @@ class WebContentsCaptureMachine
// Parameters saved in constructor.
const int initial_render_process_id_;
- const int initial_render_view_id_;
+ const int initial_main_render_frame_id_;
// A dedicated worker thread on which SkBitmap->VideoFrame conversion will
// occur. Only used when this activity cannot be done on the GPU.
@@ -558,9 +558,9 @@ void VideoFrameDeliveryLog::ChronicleFrameDelivery(base::TimeTicks frame_time) {
}
WebContentsCaptureMachine::WebContentsCaptureMachine(int render_process_id,
- int render_view_id)
+ int main_render_frame_id)
: initial_render_process_id_(render_process_id),
- initial_render_view_id_(render_view_id),
+ initial_main_render_frame_id_(main_render_frame_id),
fullscreen_widget_id_(MSG_ROUTING_NONE),
weak_ptr_factory_(this) {}
@@ -672,22 +672,21 @@ void WebContentsCaptureMachine::Capture(
}
bool WebContentsCaptureMachine::StartObservingWebContents() {
- // Look-up the RenderViewHost and, from that, the WebContents that wraps it.
+ // Look-up the RenderFrameHost and, from that, the WebContents that wraps it.
// If successful, begin observing the WebContents instance.
//
// Why this can be unsuccessful: The request for mirroring originates in a
- // render process, and this request is based on the current RenderView
+ // render process, and this request is based on the current main RenderFrame
// associated with a tab. However, by the time we get up-and-running here,
// there have been multiple back-and-forth IPCs between processes, as well as
// a bit of indirection across threads. It's easily possible that, in the
- // meantime, the original RenderView may have gone away.
- RenderViewHost* const rvh =
- RenderViewHost::FromID(initial_render_process_id_,
- initial_render_view_id_);
- DVLOG_IF(1, !rvh) << "RenderViewHost::FromID("
- << initial_render_process_id_ << ", "
- << initial_render_view_id_ << ") returned NULL.";
- Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
+ // meantime, the original RenderFrame may have gone away.
+ Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
+ initial_render_process_id_, initial_main_render_frame_id_)));
+ DVLOG_IF(1, !web_contents())
+ << "Could not find WebContents associated with main RenderFrameHost "
+ << "referenced by render_process_id=" << initial_render_process_id_
+ << ", routing_id=" << initial_main_render_frame_id_;
WebContentsImpl* contents = static_cast<WebContentsImpl*>(web_contents());
if (contents) {
@@ -696,8 +695,6 @@ bool WebContentsCaptureMachine::StartObservingWebContents() {
RenewFrameSubscription();
return true;
}
-
- DVLOG(1) << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL.";
return false;
}
@@ -786,9 +783,10 @@ void WebContentsCaptureMachine::RenewFrameSubscription() {
} // namespace
WebContentsVideoCaptureDevice::WebContentsVideoCaptureDevice(
- int render_process_id, int render_view_id)
+ int render_process_id, int main_render_frame_id)
: core_(new ContentVideoCaptureDeviceCore(scoped_ptr<VideoCaptureMachine>(
- new WebContentsCaptureMachine(render_process_id, render_view_id)))) {}
+ new WebContentsCaptureMachine(
+ render_process_id, main_render_frame_id)))) {}
WebContentsVideoCaptureDevice::~WebContentsVideoCaptureDevice() {
DVLOG(2) << "WebContentsVideoCaptureDevice@" << this << " destroying.";
@@ -799,13 +797,14 @@ media::VideoCaptureDevice* WebContentsVideoCaptureDevice::Create(
const std::string& device_id) {
// Parse device_id into render_process_id and render_view_id.
int render_process_id = -1;
- int render_view_id = -1;
+ int main_render_frame_id = -1;
if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
- device_id, &render_process_id, &render_view_id)) {
+ device_id, &render_process_id, &main_render_frame_id)) {
return NULL;
}
- return new WebContentsVideoCaptureDevice(render_process_id, render_view_id);
+ return new WebContentsVideoCaptureDevice(
+ render_process_id, main_render_frame_id);
}
void WebContentsVideoCaptureDevice::AllocateAndStart(
diff --git a/content/browser/media/capture/web_contents_video_capture_device.h b/content/browser/media/capture/web_contents_video_capture_device.h
index 16c7b09..e7d31f6 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.h
+++ b/content/browser/media/capture/web_contents_video_capture_device.h
@@ -19,22 +19,21 @@ class ContentVideoCaptureDeviceCore;
// tab (accessed via its associated WebContents instance), producing a stream of
// video frames.
//
-// An instance is created by providing a device_id. The device_id contains the
-// routing ID for a RenderViewHost, and from the RenderViewHost instance, a
-// reference to its associated WebContents instance is acquired. From then on,
+// An instance is created by providing a device_id. The device_id contains
+// information necessary for finding a WebContents instance. From then on,
// WebContentsVideoCaptureDevice will capture from whatever render view is
// currently associated with that WebContents instance. This allows the
// underlying render view to be swapped out (e.g., due to navigation or
// crashes/reloads), without any interruption in capturing.
+//
+// TODO(miu): In a soon upcoming change, the cross-site isolation migration of
+// this code will be completed such that the main RenderFrameHost is tracked
+// instead of the RenderViewHost.
class CONTENT_EXPORT WebContentsVideoCaptureDevice
: public media::VideoCaptureDevice {
public:
- // Construct from a |device_id| string of the form:
- // "virtual-media-stream://render_process_id:render_view_id", where
- // |render_process_id| and |render_view_id| are decimal integers.
- // |destroy_cb| is invoked on an outside thread once all outstanding objects
- // are completely destroyed -- this will be some time after the
- // WebContentsVideoCaptureDevice is itself deleted.
+ // Create a WebContentsVideoCaptureDevice instance from the given
+ // |device_id|. Returns NULL if |device_id| is invalid.
static media::VideoCaptureDevice* Create(const std::string& device_id);
virtual ~WebContentsVideoCaptureDevice();
@@ -45,7 +44,8 @@ class CONTENT_EXPORT WebContentsVideoCaptureDevice
virtual void StopAndDeAllocate() OVERRIDE;
private:
- WebContentsVideoCaptureDevice(int render_process_id, int render_view_id);
+ WebContentsVideoCaptureDevice(
+ int render_process_id, int main_render_frame_id);
const scoped_ptr<ContentVideoCaptureDeviceCore> core_;
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index fde3706..f9557b6 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -499,17 +499,11 @@ class WebContentsVideoCaptureDeviceTest : public testing::Test {
render_process_host_factory_.get());
web_contents_.reset(
TestWebContents::Create(browser_context_.get(), site_instance.get()));
-
- // This is actually a CaptureTestRenderViewHost.
- RenderWidgetHostImpl* rwh =
- RenderWidgetHostImpl::From(web_contents_->GetRenderViewHost());
-
- std::string device_id =
- WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
- base::StringPrintf("%d:%d", rwh->GetProcess()->GetID(),
- rwh->GetRoutingID()));
-
- device_.reset(WebContentsVideoCaptureDevice::Create(device_id));
+ RenderFrameHost* const main_frame = web_contents_->GetMainFrame();
+ device_.reset(WebContentsVideoCaptureDevice::Create(
+ base::StringPrintf("web-contents-media-stream://%d:%d",
+ main_frame->GetProcess()->GetID(),
+ main_frame->GetRoutingID())));
base::RunLoop().RunUntilIdle();
}
diff --git a/content/browser/renderer_host/media/DEPS b/content/browser/renderer_host/media/DEPS
index c3a5b96..21fd0fd9 100644
--- a/content/browser/renderer_host/media/DEPS
+++ b/content/browser/renderer_host/media/DEPS
@@ -1,3 +1,11 @@
include_rules = [
"+media",
]
+
+specific_include_rules = {
+ # TODO(miu): Need to relocate MediaStreamManager/DispatcherHost/UIProxy and
+ # friends to somewhere more appropriate. Perhaps content/browser/media?
+ "media_stream_ui_proxy(_unittest)?\.cc": [
+ "+content/browser/frame_host",
+ ],
+}
diff --git a/content/browser/renderer_host/media/device_request_message_filter.cc b/content/browser/renderer_host/media/device_request_message_filter.cc
index db0d175..d15039d 100644
--- a/content/browser/renderer_host/media/device_request_message_filter.cc
+++ b/content/browser/renderer_host/media/device_request_message_filter.cc
@@ -53,7 +53,7 @@ struct DeviceRequestMessageFilter::DeviceRequest {
};
void DeviceRequestMessageFilter::DevicesEnumerated(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& new_devices) {
diff --git a/content/browser/renderer_host/media/device_request_message_filter.h b/content/browser/renderer_host/media/device_request_message_filter.h
index 2ec54cc..4bf30aa 100644
--- a/content/browser/renderer_host/media/device_request_message_filter.h
+++ b/content/browser/renderer_host/media/device_request_message_filter.h
@@ -32,22 +32,22 @@ class CONTENT_EXPORT DeviceRequestMessageFilter : public BrowserMessageFilter,
// we don't have to override all these callbacks we don't care about.
// (crbug.com/249476)
virtual void StreamGenerated(
- int render_view_id, int page_request_id, const std::string& label,
+ int render_frame_id, int page_request_id, const std::string& label,
const StreamDeviceInfoArray& audio_devices,
const StreamDeviceInfoArray& video_devices) OVERRIDE {}
virtual void StreamGenerationFailed(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
content::MediaStreamRequestResult result) OVERRIDE {}
- virtual void DeviceStopped(int render_view_id,
+ virtual void DeviceStopped(int render_frame_id,
const std::string& label,
const StreamDeviceInfo& device) OVERRIDE {}
- virtual void DeviceOpened(int render_view_id,
+ virtual void DeviceOpened(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfo& video_device) OVERRIDE {}
// DevicesEnumerated() is the only callback we're interested in.
- virtual void DevicesEnumerated(int render_view_id,
+ virtual void DevicesEnumerated(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& devices) OVERRIDE;
diff --git a/content/browser/renderer_host/media/device_request_message_filter_unittest.cc b/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
index 6d6a9e3..628bd19 100644
--- a/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
+++ b/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
@@ -28,7 +28,7 @@ class MockMediaStreamManager : public MediaStreamManager {
MOCK_METHOD8(EnumerateDevices,
std::string(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& rc,
int page_request_id,
MediaStreamType type,
@@ -37,7 +37,7 @@ class MockMediaStreamManager : public MediaStreamManager {
std::string DoEnumerateDevices(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& rc,
int page_request_id,
MediaStreamType type,
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 91fad34..327efce 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -26,7 +26,7 @@ MediaStreamDispatcherHost::MediaStreamDispatcherHost(
}
void MediaStreamDispatcherHost::StreamGenerated(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& audio_devices,
@@ -36,12 +36,11 @@ void MediaStreamDispatcherHost::StreamGenerated(
<< ", {label = " << label << "})";
Send(new MediaStreamMsg_StreamGenerated(
- render_view_id, page_request_id, label, audio_devices,
- video_devices));
+ render_frame_id, page_request_id, label, audio_devices, video_devices));
}
void MediaStreamDispatcherHost::StreamGenerationFailed(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
content::MediaStreamRequestResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -50,12 +49,12 @@ void MediaStreamDispatcherHost::StreamGenerationFailed(
<< ", { result= " << result << "})";
- Send(new MediaStreamMsg_StreamGenerationFailed(render_view_id,
+ Send(new MediaStreamMsg_StreamGenerationFailed(render_frame_id,
page_request_id,
result));
}
-void MediaStreamDispatcherHost::DeviceStopped(int render_view_id,
+void MediaStreamDispatcherHost::DeviceStopped(int render_frame_id,
const std::string& label,
const StreamDeviceInfo& device) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -64,11 +63,11 @@ void MediaStreamDispatcherHost::DeviceStopped(int render_view_id,
<< "{type = " << device.device.type << "}, "
<< "{device_id = " << device.device.id << "})";
- Send(new MediaStreamMsg_DeviceStopped(render_view_id, label, device));
+ Send(new MediaStreamMsg_DeviceStopped(render_frame_id, label, device));
}
void MediaStreamDispatcherHost::DevicesEnumerated(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& devices) {
@@ -76,12 +75,12 @@ void MediaStreamDispatcherHost::DevicesEnumerated(
DVLOG(1) << "MediaStreamDispatcherHost::DevicesEnumerated("
<< ", {page_request_id = " << page_request_id << "})";
- Send(new MediaStreamMsg_DevicesEnumerated(render_view_id, page_request_id,
+ Send(new MediaStreamMsg_DevicesEnumerated(render_frame_id, page_request_id,
devices));
}
void MediaStreamDispatcherHost::DeviceOpened(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfo& video_device) {
@@ -90,7 +89,7 @@ void MediaStreamDispatcherHost::DeviceOpened(
<< ", {page_request_id = " << page_request_id << "})";
Send(new MediaStreamMsg_DeviceOpened(
- render_view_id, page_request_id, label, video_device));
+ render_frame_id, page_request_id, label, video_device));
}
bool MediaStreamDispatcherHost::OnMessageReceived(const IPC::Message& message) {
@@ -125,13 +124,13 @@ MediaStreamDispatcherHost::~MediaStreamDispatcherHost() {
}
void MediaStreamDispatcherHost::OnGenerateStream(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const StreamOptions& components,
const GURL& security_origin,
bool user_gesture) {
DVLOG(1) << "MediaStreamDispatcherHost::OnGenerateStream("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< page_request_id << ", ["
<< " audio:" << components.audio_requested
<< " video:" << components.video_requested
@@ -143,37 +142,37 @@ void MediaStreamDispatcherHost::OnGenerateStream(
return;
media_stream_manager_->GenerateStream(
- this, render_process_id_, render_view_id, salt_callback_,
+ this, render_process_id_, render_frame_id, salt_callback_,
page_request_id, components, security_origin, user_gesture);
}
-void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_view_id,
+void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_frame_id,
int page_request_id) {
DVLOG(1) << "MediaStreamDispatcherHost::OnCancelGenerateStream("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< page_request_id << ")";
- media_stream_manager_->CancelRequest(render_process_id_, render_view_id,
+ media_stream_manager_->CancelRequest(render_process_id_, render_frame_id,
page_request_id);
}
void MediaStreamDispatcherHost::OnStopStreamDevice(
- int render_view_id,
+ int render_frame_id,
const std::string& device_id) {
DVLOG(1) << "MediaStreamDispatcherHost::OnStopStreamDevice("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< device_id << ")";
- media_stream_manager_->StopStreamDevice(render_process_id_, render_view_id,
+ media_stream_manager_->StopStreamDevice(render_process_id_, render_frame_id,
device_id);
}
void MediaStreamDispatcherHost::OnEnumerateDevices(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
MediaStreamType type,
const GURL& security_origin,
bool hide_labels_if_no_access) {
DVLOG(1) << "MediaStreamDispatcherHost::OnEnumerateDevices("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< page_request_id << ", "
<< type << ", "
<< security_origin.spec() << ")";
@@ -194,28 +193,28 @@ void MediaStreamDispatcherHost::OnEnumerateDevices(
}
media_stream_manager_->EnumerateDevices(
- this, render_process_id_, render_view_id, salt_callback_,
+ this, render_process_id_, render_frame_id, salt_callback_,
page_request_id, type, security_origin, have_permission);
}
void MediaStreamDispatcherHost::OnCancelEnumerateDevices(
- int render_view_id,
+ int render_frame_id,
int page_request_id) {
DVLOG(1) << "MediaStreamDispatcherHost::OnCancelEnumerateDevices("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< page_request_id << ")";
- media_stream_manager_->CancelRequest(render_process_id_, render_view_id,
+ media_stream_manager_->CancelRequest(render_process_id_, render_frame_id,
page_request_id);
}
void MediaStreamDispatcherHost::OnOpenDevice(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
const GURL& security_origin) {
DVLOG(1) << "MediaStreamDispatcherHost::OnOpenDevice("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< page_request_id << ", device_id: "
<< device_id.c_str() << ", type: "
<< type << ", "
@@ -225,15 +224,15 @@ void MediaStreamDispatcherHost::OnOpenDevice(
return;
media_stream_manager_->OpenDevice(
- this, render_process_id_, render_view_id, salt_callback_,
+ this, render_process_id_, render_frame_id, salt_callback_,
page_request_id, device_id, type, security_origin);
}
void MediaStreamDispatcherHost::OnCloseDevice(
- int render_view_id,
+ int render_frame_id,
const std::string& label) {
DVLOG(1) << "MediaStreamDispatcherHost::OnCloseDevice("
- << render_view_id << ", "
+ << render_frame_id << ", "
<< label << ")";
media_stream_manager_->CancelRequest(label);
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index b599c39..d467718 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -22,8 +22,8 @@ class MediaStreamManager;
class ResourceContext;
// MediaStreamDispatcherHost is a delegate for Media Stream API messages used by
-// MediaStreamImpl. It's the complement of MediaStreamDispatcher
-// (owned by RenderView).
+// MediaStreamImpl. There is one MediaStreamDispatcherHost per
+// RenderProcessHost, the former owned by the latter.
class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
public MediaStreamRequester {
public:
@@ -35,23 +35,23 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
// MediaStreamRequester implementation.
virtual void StreamGenerated(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& audio_devices,
const StreamDeviceInfoArray& video_devices) OVERRIDE;
virtual void StreamGenerationFailed(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
content::MediaStreamRequestResult result) OVERRIDE;
- virtual void DeviceStopped(int render_view_id,
+ virtual void DeviceStopped(int render_frame_id,
const std::string& label,
const StreamDeviceInfo& device) OVERRIDE;
- virtual void DevicesEnumerated(int render_view_id,
+ virtual void DevicesEnumerated(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& devices) OVERRIDE;
- virtual void DeviceOpened(int render_view_id,
+ virtual void DeviceOpened(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfo& video_device) OVERRIDE;
@@ -66,35 +66,35 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
private:
friend class MockMediaStreamDispatcherHost;
- void OnGenerateStream(int render_view_id,
+ void OnGenerateStream(int render_frame_id,
int page_request_id,
const StreamOptions& components,
const GURL& security_origin,
bool user_gesture);
- void OnCancelGenerateStream(int render_view_id,
+ void OnCancelGenerateStream(int render_frame_id,
int page_request_id);
- void OnStopStreamDevice(int render_view_id,
+ void OnStopStreamDevice(int render_frame_id,
const std::string& device_id);
- void OnEnumerateDevices(int render_view_id,
+ void OnEnumerateDevices(int render_frame_id,
int page_request_id,
MediaStreamType type,
const GURL& security_origin,
bool hide_labels_if_no_access);
- void OnCancelEnumerateDevices(int render_view_id,
+ void OnCancelEnumerateDevices(int render_frame_id,
int page_request_id);
- void OnOpenDevice(int render_view_id,
+ void OnOpenDevice(int render_frame_id,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
const GURL& security_origin);
- void OnCloseDevice(int render_view_id,
+ void OnCloseDevice(int render_frame_id,
const std::string& label);
- void StoreRequest(int render_view_id,
+ void StoreRequest(int render_frame_id,
int page_request_id,
const std::string& label);
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index a7edd38..24366a5 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -70,22 +70,22 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
// Accessor to private functions.
- void OnGenerateStream(int render_view_id,
+ void OnGenerateStream(int render_frame_id,
int page_request_id,
const StreamOptions& components,
const GURL& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnGenerateStream(
- render_view_id, page_request_id, components, security_origin, false);
+ render_frame_id, page_request_id, components, security_origin, false);
}
- void OnStopStreamDevice(int render_view_id,
+ void OnStopStreamDevice(int render_frame_id,
const std::string& device_id) {
- MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
+ MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id, device_id);
}
- void OnOpenDevice(int render_view_id,
+ void OnOpenDevice(int render_frame_id,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
@@ -93,10 +93,10 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnOpenDevice(
- render_view_id, page_request_id, device_id, type, security_origin);
+ render_frame_id, page_request_id, device_id, type, security_origin);
}
- void OnEnumerateDevices(int render_view_id,
+ void OnEnumerateDevices(int render_frame_id,
int page_request_id,
MediaStreamType type,
const GURL& security_origin,
@@ -104,7 +104,7 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnEnumerateDevices(
- render_view_id, page_request_id, type, security_origin,
+ render_frame_id, page_request_id, type, security_origin,
hide_labels_if_no_access);
}
@@ -279,7 +279,7 @@ class MediaStreamDispatcherHostTest : public testing::Test {
stream_ui.PassAs<FakeMediaStreamUIProxy>());
}
- void GenerateStreamAndWaitForResult(int render_view_id,
+ void GenerateStreamAndWaitForResult(int render_frame_id,
int page_request_id,
const StreamOptions& options) {
base::RunLoop run_loop;
@@ -289,10 +289,11 @@ class MediaStreamDispatcherHostTest : public testing::Test {
int expected_video_array_size =
(options.video_requested &&
physical_video_devices_.size() > 0) ? 1 : 0;
- EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
+ EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
+ page_request_id,
expected_audio_array_size,
expected_video_array_size));
- host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
+ host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
@@ -302,25 +303,25 @@ class MediaStreamDispatcherHostTest : public testing::Test {
}
void GenerateStreamAndWaitForFailure(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const StreamOptions& options,
MediaStreamRequestResult expected_result) {
base::RunLoop run_loop;
EXPECT_CALL(*host_.get(),
- OnStreamGenerationFailed(render_view_id,
+ OnStreamGenerationFailed(render_frame_id,
page_request_id,
expected_result));
- host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
- run_loop.QuitClosure());
+ host_->OnGenerateStream(render_frame_id, page_request_id, options,
+ origin_, run_loop.QuitClosure());
run_loop.Run();
}
- void OpenVideoDeviceAndWaitForResult(int render_view_id,
+ void OpenVideoDeviceAndWaitForResult(int render_frame_id,
int page_request_id,
const std::string& device_id) {
base::RunLoop run_loop;
- host_->OnOpenDevice(render_view_id, page_request_id, device_id,
+ host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
run_loop.QuitClosure());
run_loop.Run();
@@ -328,12 +329,12 @@ class MediaStreamDispatcherHostTest : public testing::Test {
EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
}
- void EnumerateDevicesAndWaitForResult(int render_view_id,
+ void EnumerateDevicesAndWaitForResult(int render_frame_id,
int page_request_id,
MediaStreamType type,
bool hide_labels_if_no_access) {
base::RunLoop run_loop;
- host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
+ host_->OnEnumerateDevices(render_frame_id, page_request_id, type, origin_,
hide_labels_if_no_access, run_loop.QuitClosure());
run_loop.Run();
ASSERT_FALSE(host_->enumerated_devices_.empty());
@@ -470,8 +471,8 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
EXPECT_EQ(host_->video_devices_.size(), 1u);
}
-// This test generates two streams with video only using the same render view
-// id. The same capture device with the same device and session id is expected
+// This test generates two streams with video only using the same render frame
+// id. The same capture device with the same device and session id is expected
// to be used.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
StreamOptions options(false, true);
@@ -530,7 +531,7 @@ TEST_F(MediaStreamDispatcherHostTest,
// This test generates two streams with video only using two separate render
-// view ids. The same device id but different session ids are expected.
+// frame ids. The same device id but different session ids are expected.
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
StreamOptions options(false, true);
@@ -545,7 +546,7 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
const std::string device_id1 = host_->video_devices_.front().device.id;
const int session_id1 = host_->video_devices_.front().session_id;
- // Generate second stream from another render view.
+ // Generate second stream from another render frame.
SetupFakeUI(true);
GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 2b337ca..21d2aa4 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -183,7 +183,7 @@ class MediaStreamManager::DeviceRequest {
public:
DeviceRequest(MediaStreamRequester* requester,
int requesting_process_id,
- int requesting_view_id,
+ int requesting_frame_id,
int page_request_id,
const GURL& security_origin,
bool have_permission,
@@ -193,7 +193,7 @@ class MediaStreamManager::DeviceRequest {
const ResourceContext::SaltCallback& salt_callback)
: requester(requester),
requesting_process_id(requesting_process_id),
- requesting_view_id(requesting_view_id),
+ requesting_frame_id(requesting_frame_id),
page_request_id(page_request_id),
security_origin(security_origin),
have_permission(have_permission),
@@ -230,7 +230,7 @@ class MediaStreamManager::DeviceRequest {
const std::string& requested_video_device_id) {
DCHECK(!ui_request_);
ui_request_.reset(new MediaStreamRequest(requesting_process_id,
- requesting_view_id,
+ requesting_frame_id,
page_request_id,
security_origin,
user_gesture,
@@ -243,12 +243,12 @@ class MediaStreamManager::DeviceRequest {
// Creates a tab capture specific MediaStreamRequest object that is used by
// this request when UI is asked for permission and device selection.
- void CreateTabCatureUIRequest(int target_render_process_id,
- int target_render_view_id,
- const std::string& tab_capture_id) {
+ void CreateTabCaptureUIRequest(int target_render_process_id,
+ int target_render_frame_id,
+ const std::string& tab_capture_id) {
DCHECK(!ui_request_);
ui_request_.reset(new MediaStreamRequest(target_render_process_id,
- target_render_view_id,
+ target_render_frame_id,
page_request_id,
security_origin,
user_gesture,
@@ -283,17 +283,10 @@ class MediaStreamManager::DeviceRequest {
if (!ui_request_)
return;
- // If we appended a device_id scheme, we want to remove it when notifying
- // observers which may be in different modules since this scheme is only
- // used internally within the content module.
- std::string device_id =
- WebContentsCaptureUtil::StripWebContentsDeviceScheme(
- ui_request_->tab_capture_device_id);
-
media_observer->OnMediaRequestStateChanged(
- ui_request_->render_process_id, ui_request_->render_view_id,
+ ui_request_->render_process_id, ui_request_->render_frame_id,
ui_request_->page_request_id, ui_request_->security_origin,
- MediaStreamDevice(stream_type, device_id, device_id), new_state);
+ stream_type, new_state);
}
MediaRequestState state(MediaStreamType stream_type) const {
@@ -309,13 +302,13 @@ class MediaStreamManager::DeviceRequest {
// specifies the target renderer from which audio and video is captured.
const int requesting_process_id;
- // The render view id that requested this stream to be generated and that
+ // The render frame id that requested this stream to be generated and that
// will receive a handle to the MediaStream. This may be different from
- // MediaStreamRequest::render_view_id which in the tab capture case
+ // MediaStreamRequest::render_frame_id which in the tab capture case
// specifies the target renderer from which audio and video is captured.
- const int requesting_view_id;
+ const int requesting_frame_id;
- // An ID the render view provided to identify this request.
+ // An ID the render frame provided to identify this request.
const int page_request_id;
const GURL security_origin;
@@ -414,7 +407,7 @@ AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
std::string MediaStreamManager::MakeMediaAccessRequest(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const StreamOptions& options,
const GURL& security_origin,
@@ -425,7 +418,7 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
// suggests that this is the wrong design. Can this be refactored?
DeviceRequest* request = new DeviceRequest(NULL,
render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
security_origin,
true,
@@ -451,7 +444,7 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
const StreamOptions& options,
@@ -466,7 +459,7 @@ void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
DeviceRequest* request = new DeviceRequest(requester,
render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
security_origin,
true,
@@ -489,13 +482,13 @@ void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
}
void MediaStreamManager::CancelRequest(int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id) {
for (DeviceRequests::const_iterator request_it = requests_.begin();
request_it != requests_.end(); ++request_it) {
const DeviceRequest* request = request_it->second;
if (request->requesting_process_id == render_process_id &&
- request->requesting_view_id == render_view_id &&
+ request->requesting_frame_id == render_frame_id &&
request->page_request_id == page_request_id) {
CancelRequest(request_it->first);
return;
@@ -557,19 +550,19 @@ void MediaStreamManager::CancelAllRequests(int render_process_id) {
}
void MediaStreamManager::StopStreamDevice(int render_process_id,
- int render_view_id,
+ int render_frame_id,
const std::string& device_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} "
+ DVLOG(1) << "StopStreamDevice({render_frame_id = " << render_frame_id << "} "
<< ", {device_id = " << device_id << "})";
- // Find the first request for this |render_process_id| and |render_view_id|
+ // Find the first request for this |render_process_id| and |render_frame_id|
// of type MEDIA_GENERATE_STREAM that has requested to use |device_id| and
// stop it.
for (DeviceRequests::iterator request_it = requests_.begin();
- request_it != requests_.end(); ++request_it) {
+ request_it != requests_.end(); ++request_it) {
DeviceRequest* request = request_it->second;
if (request->requesting_process_id != render_process_id ||
- request->requesting_view_id != render_view_id ||
+ request->requesting_frame_id != render_frame_id ||
request->request_type != MEDIA_GENERATE_STREAM) {
continue;
}
@@ -648,7 +641,7 @@ void MediaStreamManager::CloseDevice(MediaStreamType type, int session_id) {
std::string MediaStreamManager::EnumerateDevices(
MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
MediaStreamType type,
@@ -662,7 +655,7 @@ std::string MediaStreamManager::EnumerateDevices(
DeviceRequest* request = new DeviceRequest(requester,
render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
security_origin,
have_permission,
@@ -733,8 +726,7 @@ void MediaStreamManager::DoEnumerateDevices(const std::string& label) {
DVLOG(1) << "Enumerate Devices ({label = " << label << "})";
}
-void MediaStreamManager::EnumerateAudioOutputDevices(
- const std::string& label) {
+void MediaStreamManager::EnumerateAudioOutputDevices(const std::string& label) {
DCHECK(device_task_runner_->BelongsToCurrentThread());
scoped_ptr<media::AudioDeviceNames> device_names(
@@ -786,7 +778,7 @@ void MediaStreamManager::AudioOutputDevicesEnumerated(
void MediaStreamManager::OpenDevice(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
const std::string& device_id,
@@ -810,7 +802,7 @@ void MediaStreamManager::OpenDevice(MediaStreamRequester* requester,
}
DeviceRequest* request = new DeviceRequest(requester,
render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
security_origin,
true,
@@ -910,7 +902,7 @@ void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) {
session_ids.push_back(device_it->session_id);
if (it->second->requester) {
it->second->requester->DeviceStopped(
- it->second->requesting_view_id,
+ it->second->requesting_frame_id,
it->first,
*device_it);
}
@@ -1295,17 +1287,10 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
// Customize options for a WebContents based capture.
int target_render_process_id = 0;
- int target_render_view_id = 0;
-
- // TODO(justinlin): Can't plumb audio mirroring using stream type right
- // now, so plumbing by device_id. Will revisit once it's refactored.
- // http://crbug.com/163100
- std::string tab_capture_device_id =
- WebContentsCaptureUtil::AppendWebContentsDeviceScheme(capture_device_id);
+ int target_render_frame_id = 0;
bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
- tab_capture_device_id, &target_render_process_id,
- &target_render_view_id);
+ capture_device_id, &target_render_process_id, &target_render_frame_id);
if (!has_valid_device_id ||
(request->audio_type() != MEDIA_TAB_AUDIO_CAPTURE &&
request->audio_type() != MEDIA_NO_SERVICE) ||
@@ -1314,15 +1299,15 @@ bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
return false;
}
- request->CreateTabCatureUIRequest(target_render_process_id,
- target_render_view_id,
- tab_capture_device_id);
+ request->CreateTabCaptureUIRequest(target_render_process_id,
+ target_render_frame_id,
+ capture_device_id);
DVLOG(3) << "SetupTabCaptureRequest "
- << ", {tab_capture_device_id = " << tab_capture_device_id << "}"
+ << ", {capture_device_id = " << capture_device_id << "}"
<< ", {target_render_process_id = " << target_render_process_id
<< "}"
- << ", {target_render_view_id = " << target_render_view_id << "}";
+ << ", {target_render_frame_id = " << target_render_frame_id << "}";
return true;
}
@@ -1394,7 +1379,7 @@ bool MediaStreamManager::FindExistingRequestedDeviceInfo(
it != requests_.end() ; ++it) {
const DeviceRequest* request = it->second;
if (request->requesting_process_id == new_request.requesting_process_id &&
- request->requesting_view_id == new_request.requesting_view_id &&
+ request->requesting_frame_id == new_request.requesting_frame_id &&
request->request_type == new_request.request_type) {
for (StreamDeviceInfoArray::const_iterator device_it =
request->devices.begin();
@@ -1431,7 +1416,7 @@ void MediaStreamManager::FinalizeGenerateStream(const std::string& label,
}
request->requester->StreamGenerated(
- request->requesting_view_id,
+ request->requesting_frame_id,
request->page_request_id,
label, audio_devices, video_devices);
}
@@ -1442,7 +1427,7 @@ void MediaStreamManager::FinalizeRequestFailed(
content::MediaStreamRequestResult result) {
if (request->requester)
request->requester->StreamGenerationFailed(
- request->requesting_view_id,
+ request->requesting_frame_id,
request->page_request_id,
result);
@@ -1457,7 +1442,7 @@ void MediaStreamManager::FinalizeRequestFailed(
void MediaStreamManager::FinalizeOpenDevice(const std::string& label,
DeviceRequest* request) {
const StreamDeviceInfoArray& requested_devices = request->devices;
- request->requester->DeviceOpened(request->requesting_view_id,
+ request->requester->DeviceOpened(request->requesting_frame_id,
request->page_request_id,
label, requested_devices.front());
}
@@ -1480,7 +1465,7 @@ void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label,
ClearDeviceLabels(&request->devices);
request->requester->DevicesEnumerated(
- request->requesting_view_id,
+ request->requesting_frame_id,
request->page_request_id,
label,
request->devices);
@@ -1817,8 +1802,6 @@ void MediaStreamManager::HandleAccessRequestResponse(
StreamDeviceInfo device_info;
device_info.device = *device_it;
- // TODO(justinlin): Nicer way to do this?
- // Re-append the device's id since we lost it when posting request to UI.
if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE ||
device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) {
device_info.device.id = request->UIRequest()->tab_capture_device_id;
@@ -1847,7 +1830,7 @@ void MediaStreamManager::HandleAccessRequestResponse(
}
// If this is request for a new MediaStream, a device is only opened once
- // per render view. This is so that the permission to use a device can be
+ // per render frame. This is so that the permission to use a device can be
// revoked by a single call to StopStreamDevice regardless of how many
// MediaStreams it is being used in.
if (request->request_type == MEDIA_GENERATE_STREAM) {
@@ -1900,7 +1883,7 @@ void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) {
if (request->requester) {
for (StreamDeviceInfoArray::iterator device_it = request->devices.begin();
device_it != request->devices.end(); ++device_it) {
- request->requester->DeviceStopped(request->requesting_view_id,
+ request->requester->DeviceStopped(request->requesting_frame_id,
label,
*device_it);
}
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index 1de659c..4125b39 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -81,13 +81,13 @@ class CONTENT_EXPORT MediaStreamManager
// Creates a new media access request which is identified by a unique string
// that's returned to the caller. This will trigger the infobar and ask users
- // for access to the device. |render_process_id| and |render_view_id| refer
- // to the view where the infobar will appear to the user. |callback| is
+ // for access to the device. |render_process_id| and |render_frame_id| are
+ // used to determine where the infobar will appear to the user. |callback| is
// used to send the selected device to the clients. An empty list of device
// will be returned if the users deny the access.
std::string MakeMediaAccessRequest(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const StreamOptions& options,
const GURL& security_origin,
@@ -95,11 +95,11 @@ class CONTENT_EXPORT MediaStreamManager
// GenerateStream opens new media devices according to |components|. It
// creates a new request which is identified by a unique string that's
- // returned to the caller. |render_process_id| and |render_view_id| refer to
- // the view where the infobar will appear to the user.
+ // returned to the caller. |render_process_id| and |render_frame_id| are used
+ // to determine where the infobar will appear to the user.
void GenerateStream(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
const StreamOptions& components,
@@ -107,7 +107,7 @@ class CONTENT_EXPORT MediaStreamManager
bool user_gesture);
void CancelRequest(int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id);
// Cancel an open request identified by |label|.
@@ -116,10 +116,10 @@ class CONTENT_EXPORT MediaStreamManager
// Cancel all requests for the given |render_process_id|.
void CancelAllRequests(int render_process_id);
- // Closes the stream device for a certain render view. The stream must have
+ // Closes the stream device for a certain render frame. The stream must have
// been opened by a call to GenerateStream.
void StopStreamDevice(int render_process_id,
- int render_view_id,
+ int render_frame_id,
const std::string& device_id);
// Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
@@ -132,7 +132,7 @@ class CONTENT_EXPORT MediaStreamManager
// If |have_permission| is false, we remove the device label from the result.
virtual std::string EnumerateDevices(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
MediaStreamType type,
@@ -144,7 +144,7 @@ class CONTENT_EXPORT MediaStreamManager
// The request is identified using string returned to the caller.
void OpenDevice(MediaStreamRequester* requester,
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const ResourceContext::SaltCallback& sc,
int page_request_id,
const std::string& device_id,
@@ -301,7 +301,7 @@ class CONTENT_EXPORT MediaStreamManager
// needed.
void PostRequestToUI(const std::string& label, DeviceRequest* request);
// Returns true if a device with |device_id| has already been requested with
- // a render procecss_id and render_view_id and type equal to the the values
+ // a render procecss_id and render_frame_id and type equal to the the values
// in |request|. If it has been requested, |device_info| contain information
// about the device.
bool FindExistingRequestedDeviceInfo(
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index e01b945..cc19af2 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -99,7 +99,7 @@ class MediaStreamManagerTest : public ::testing::Test {
protected:
std::string MakeMediaAccessRequest(int index) {
const int render_process_id = 1;
- const int render_view_id = 1;
+ const int render_frame_id = 1;
const int page_request_id = 1;
const GURL security_origin;
MediaStreamManager::MediaRequestResponseCallback callback =
@@ -107,7 +107,7 @@ class MediaStreamManagerTest : public ::testing::Test {
base::Unretained(this), index);
StreamOptions options(true, true);
return media_stream_manager_->MakeMediaAccessRequest(render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
options,
security_origin,
@@ -146,7 +146,7 @@ TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
// Second request.
int render_process_id = 2;
- int render_view_id = 2;
+ int render_frame_id = 2;
int page_request_id = 2;
GURL security_origin;
StreamOptions options(true, true);
@@ -155,7 +155,7 @@ TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
base::Unretained(this), 1);
std::string label2 = media_stream_manager_->MakeMediaAccessRequest(
render_process_id,
- render_view_id,
+ render_frame_id,
page_request_id,
options,
security_origin,
diff --git a/content/browser/renderer_host/media/media_stream_requester.h b/content/browser/renderer_host/media/media_stream_requester.h
index 337effa..c36f166 100644
--- a/content/browser/renderer_host/media/media_stream_requester.h
+++ b/content/browser/renderer_host/media/media_stream_requester.h
@@ -18,29 +18,29 @@ namespace content {
class CONTENT_EXPORT MediaStreamRequester {
public:
// Called as a reply of a successful call to GenerateStream.
- virtual void StreamGenerated(int render_view_id,
+ virtual void StreamGenerated(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& audio_devices,
const StreamDeviceInfoArray& video_devices) = 0;
// Called if GenerateStream failed.
virtual void StreamGenerationFailed(
- int render_view_id,
+ int render_frame_id,
int page_request_id,
content::MediaStreamRequestResult result) = 0;
// Called if a device has been stopped by a user from UI or the device
- // has become unavailable. |render_view_id| is the render view that requested
- // the device and |label| is the label of the request|.
- virtual void DeviceStopped(int render_view_id,
+ // has become unavailable. |render_frame_id| is the render frame that
+ // requested the device and |label| is the label of the request.
+ virtual void DeviceStopped(int render_frame_id,
const std::string& label,
const StreamDeviceInfo& device) = 0;
// Called as a reply of a successful call to EnumerateDevices.
- virtual void DevicesEnumerated(int render_view_id,
+ virtual void DevicesEnumerated(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& devices) = 0;
// Called as a reply of a successful call to OpenDevice.
- virtual void DeviceOpened(int render_view_id,
+ virtual void DeviceOpened(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfo& device_info) = 0;
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 1c92424..122bfa2 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -5,8 +5,8 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "base/command_line.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/frame_host/render_frame_host_delegate.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "media/video/capture/fake_video_capture_device.h"
@@ -16,7 +16,7 @@ namespace content {
class MediaStreamUIProxy::Core {
public:
explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
- RenderViewHostDelegate* test_render_delegate);
+ RenderFrameHostDelegate* test_render_delegate);
~Core();
void RequestAccess(const MediaStreamRequest& request);
@@ -31,7 +31,7 @@ class MediaStreamUIProxy::Core {
base::WeakPtr<MediaStreamUIProxy> proxy_;
scoped_ptr<MediaStreamUI> ui_;
- RenderViewHostDelegate* const test_render_delegate_;
+ RenderFrameHostDelegate* const test_render_delegate_;
// WeakPtr<> is used to RequestMediaAccessPermission() because there is no way
// cancel media requests.
@@ -41,7 +41,7 @@ class MediaStreamUIProxy::Core {
};
MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
- RenderViewHostDelegate* test_render_delegate)
+ RenderFrameHostDelegate* test_render_delegate)
: proxy_(proxy),
test_render_delegate_(test_render_delegate),
weak_factory_(this) {
@@ -55,24 +55,22 @@ void MediaStreamUIProxy::Core::RequestAccess(
const MediaStreamRequest& request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderViewHostDelegate* render_delegate;
-
+ RenderFrameHostDelegate* render_delegate;
if (test_render_delegate_) {
render_delegate = test_render_delegate_;
} else {
- RenderViewHostImpl* host = RenderViewHostImpl::FromID(
- request.render_process_id, request.render_view_id);
-
- // Tab may have gone away.
- if (!host || !host->GetDelegate()) {
- ProcessAccessRequestResponse(
- MediaStreamDevices(),
- MEDIA_DEVICE_INVALID_STATE,
- scoped_ptr<MediaStreamUI>());
- return;
- }
+ RenderFrameHostImpl* const host = RenderFrameHostImpl::FromID(
+ request.render_process_id, request.render_frame_id);
+ render_delegate = host ? host->delegate() : NULL;
+ }
- render_delegate = host->GetDelegate();
+ // Tab may have gone away, or has no delegate from which to request access.
+ if (!render_delegate) {
+ ProcessAccessRequestResponse(
+ MediaStreamDevices(),
+ MEDIA_DEVICE_INVALID_STATE,
+ scoped_ptr<MediaStreamUI>());
+ return;
}
render_delegate->RequestMediaAccessPermission(
@@ -116,13 +114,13 @@ scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() {
// static
scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::CreateForTests(
- RenderViewHostDelegate* render_delegate) {
+ RenderFrameHostDelegate* render_delegate) {
return scoped_ptr<MediaStreamUIProxy>(
new MediaStreamUIProxy(render_delegate));
}
MediaStreamUIProxy::MediaStreamUIProxy(
- RenderViewHostDelegate* test_render_delegate)
+ RenderFrameHostDelegate* test_render_delegate)
: weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
core_.reset(new Core(weak_factory_.GetWeakPtr(), test_render_delegate));
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.h b/content/browser/renderer_host/media/media_stream_ui_proxy.h
index 01be166..fe1dde5 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.h
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.h
@@ -13,11 +13,11 @@
namespace content {
-class RenderViewHostDelegate;
+class RenderFrameHostDelegate;
// MediaStreamUIProxy proxies calls to media stream UI between IO thread and UI
// thread. One instance of this class is create per MediaStream object. It must
-// be create, used and destroyed on IO thread.
+// be created, used and destroyed on IO thread.
class CONTENT_EXPORT MediaStreamUIProxy {
public:
typedef base::Callback<
@@ -29,7 +29,7 @@ class CONTENT_EXPORT MediaStreamUIProxy {
static scoped_ptr<MediaStreamUIProxy> Create();
static scoped_ptr<MediaStreamUIProxy> CreateForTests(
- RenderViewHostDelegate* render_delegate);
+ RenderFrameHostDelegate* render_delegate);
virtual ~MediaStreamUIProxy();
@@ -48,10 +48,10 @@ class CONTENT_EXPORT MediaStreamUIProxy {
virtual void OnStarted(const base::Closure& stop_callback,
const WindowIdCallback& window_id_callback);
- void SetRenderViewHostDelegateForTests(RenderViewHostDelegate* delegate);
+ void SetRenderFrameHostDelegateForTests(RenderFrameHostDelegate* delegate);
protected:
- MediaStreamUIProxy(RenderViewHostDelegate* test_render_delegate);
+ explicit MediaStreamUIProxy(RenderFrameHostDelegate* test_render_delegate);
private:
class Core;
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 4529b49..3bc1b06 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -5,7 +5,7 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "base/message_loop/message_loop.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -19,22 +19,11 @@ using testing::SaveArg;
namespace content {
namespace {
-class MockRenderViewHostDelegate : public RenderViewHostDelegate {
+class MockRenderFrameHostDelegate : public RenderFrameHostDelegate {
public:
MOCK_METHOD2(RequestMediaAccessPermission,
void(const MediaStreamRequest& request,
const MediaResponseCallback& callback));
-
- // Stubs for pure virtual methods we don't care about.
- virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE {
- NOTREACHED();
- return gfx::Rect();
- }
- virtual RendererPreferences GetRendererPrefs(
- BrowserContext* browser_context) const OVERRIDE {
- NOTREACHED();
- return RendererPreferences();
- }
};
class MockResponseCallback {
@@ -76,7 +65,7 @@ class MediaStreamUIProxyTest : public testing::Test {
TestBrowserThread ui_thread_;
TestBrowserThread io_thread_;
- MockRenderViewHostDelegate delegate_;
+ MockRenderFrameHostDelegate delegate_;
MockResponseCallback response_callback_;
scoped_ptr<MediaStreamUIProxy> proxy_;
};
@@ -84,7 +73,7 @@ class MediaStreamUIProxyTest : public testing::Test {
MATCHER_P(SameRequest, expected, "") {
return
expected.render_process_id == arg.render_process_id &&
- expected.render_view_id == arg.render_view_id &&
+ expected.render_frame_id == arg.render_frame_id &&
expected.tab_capture_device_id == arg.tab_capture_device_id &&
expected.security_origin == arg.security_origin &&
expected.request_type == arg.request_type &&
diff --git a/content/browser/renderer_host/media/mock_media_observer.h b/content/browser/renderer_host/media/mock_media_observer.h
index 04678c9..ae4e7e6 100644
--- a/content/browser/renderer_host/media/mock_media_observer.h
+++ b/content/browser/renderer_host/media/mock_media_observer.h
@@ -21,9 +21,9 @@ class MockMediaObserver : public MediaObserver {
virtual ~MockMediaObserver();
MOCK_METHOD6(OnMediaRequestStateChanged,
- void(int render_process_id, int render_view_id,
+ void(int render_process_id, int render_frame_id,
int page_request_id, const GURL& security_origin,
- const MediaStreamDevice& device,
+ MediaStreamType stream_type,
const MediaRequestState state));
};
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc
index 6088081..1df72ba 100644
--- a/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -86,23 +86,23 @@ class MockMediaStreamRequester : public MediaStreamRequester {
// MediaStreamRequester implementation.
MOCK_METHOD5(StreamGenerated,
- void(int render_view_id,
+ void(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& audio_devices,
const StreamDeviceInfoArray& video_devices));
MOCK_METHOD3(StreamGenerationFailed,
- void(int render_view_id,
+ void(int render_frame_id,
int page_request_id,
content::MediaStreamRequestResult result));
- MOCK_METHOD3(DeviceStopped, void(int render_view_id,
+ MOCK_METHOD3(DeviceStopped, void(int render_frame_id,
const std::string& label,
const StreamDeviceInfo& device));
- MOCK_METHOD4(DevicesEnumerated, void(int render_view_id,
+ MOCK_METHOD4(DevicesEnumerated, void(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfoArray& devices));
- MOCK_METHOD4(DeviceOpened, void(int render_view_id,
+ MOCK_METHOD4(DeviceOpened, void(int render_frame_id,
int page_request_id,
const std::string& label,
const StreamDeviceInfo& device_info));
@@ -319,7 +319,7 @@ class VideoCaptureHostTest : public testing::Test {
void OpenSession() {
const int render_process_id = 1;
- const int render_view_id = 1;
+ const int render_frame_id = 1;
const int page_request_id = 1;
const GURL security_origin("http://test.com");
@@ -332,13 +332,13 @@ class VideoCaptureHostTest : public testing::Test {
std::string label = media_stream_manager_->EnumerateDevices(
&stream_requester_,
render_process_id,
- render_view_id,
+ render_frame_id,
browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
page_request_id,
MEDIA_DEVICE_VIDEO_CAPTURE,
security_origin,
true);
- EXPECT_CALL(stream_requester_, DevicesEnumerated(render_view_id,
+ EXPECT_CALL(stream_requester_, DevicesEnumerated(render_frame_id,
page_request_id,
label,
_))
@@ -359,13 +359,13 @@ class VideoCaptureHostTest : public testing::Test {
media_stream_manager_->OpenDevice(
&stream_requester_,
render_process_id,
- render_view_id,
+ render_frame_id,
browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
page_request_id,
devices[0].device.id,
MEDIA_DEVICE_VIDEO_CAPTURE,
security_origin);
- EXPECT_CALL(stream_requester_, DeviceOpened(render_view_id,
+ EXPECT_CALL(stream_requester_, DeviceOpened(render_frame_id,
page_request_id,
_,
_))
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 6c87b7a..a9dea8b 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -13,7 +13,6 @@
#include "base/strings/string16.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/common/content_export.h"
-#include "content/public/common/media_stream_request.h"
#include "content/public/common/page_transition_types.h"
#include "net/base/load_states.h"
#include "third_party/WebKit/public/web/WebPopupType.h"
@@ -266,13 +265,6 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// Show the newly created full screen widget. Similar to above.
virtual void ShowCreatedFullscreenWidget(int route_id) {}
- // The render view has requested access to media devices listed in
- // |request|, and the client should grant or deny that permission by
- // calling |callback|.
- virtual void RequestMediaAccessPermission(
- const MediaStreamRequest& request,
- const MediaResponseCallback& callback) {}
-
// Returns the SessionStorageNamespace the render view should use. Might
// create the SessionStorageNamespace on the fly.
virtual SessionStorageNamespace* GetSessionStorageNamespace(
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index 0197bcf..f18ad7d 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -108,6 +108,12 @@ void SpeechRecognitionDispatcherHost::OnStartRequest(
SpeechRecognitionManagerImpl::GetInstance()->delegate()->
FilterProfanities(render_process_id_);
+ // TODO(miu): This is a hack to allow SpeechRecognition to operate with the
+ // MediaStreamManager, which partitions requests per RenderFrame, not per
+ // RenderView. http://crbug.com/390749
+ const int params_render_frame_id = render_view_host ?
+ render_view_host->GetMainFrame()->GetRoutingID() : MSG_ROUTING_NONE;
+
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
@@ -116,6 +122,7 @@ void SpeechRecognitionDispatcherHost::OnStartRequest(
embedder_render_process_id,
embedder_render_view_id,
input_params,
+ params_render_frame_id,
filter_profanities));
}
@@ -123,11 +130,13 @@ void SpeechRecognitionDispatcherHost::OnStartRequestOnIO(
int embedder_render_process_id,
int embedder_render_view_id,
const SpeechRecognitionHostMsg_StartRequest_Params& params,
+ int params_render_frame_id,
bool filter_profanities) {
SpeechRecognitionSessionContext context;
context.context_name = params.origin_url;
context.render_process_id = render_process_id_;
context.render_view_id = params.render_view_id;
+ context.render_frame_id = params_render_frame_id;
context.embedder_render_process_id = embedder_render_process_id;
context.embedder_render_view_id = embedder_render_view_id;
if (embedder_render_process_id)
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.h b/content/browser/speech/speech_recognition_dispatcher_host.h
index f8853f1..bd1f2a43 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.h
+++ b/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -68,6 +68,7 @@ class CONTENT_EXPORT SpeechRecognitionDispatcherHost
int embedder_render_process_id,
int embedder_render_view_id,
const SpeechRecognitionHostMsg_StartRequest_Params& params,
+ int params_render_frame_id,
bool filter_profanities);
void OnAbortRequest(int render_view_id, int request_id);
void OnStopCaptureRequest(int render_view_id, int request_id);
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index 4b0827a..1a05420 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -196,7 +196,7 @@ void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
SpeechRecognitionSessionContext& context = session->context;
context.label = media_stream_manager_->MakeMediaAccessRequest(
context.render_process_id,
- context.render_view_id,
+ context.render_frame_id,
context.request_id,
StreamOptions(true, false),
GURL(context.context_name),
diff --git a/content/common/media/media_stream_messages.h b/content/common/media/media_stream_messages.h
index 0d33170..e88aeab 100644
--- a/content/common/media/media_stream_messages.h
+++ b/content/common/media/media_stream_messages.h
@@ -105,7 +105,7 @@ IPC_MESSAGE_CONTROL2(MediaStreamMsg_GetSourcesACK,
// Request a new media stream.
IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_GenerateStream,
- int /* render view id */,
+ int /* render frame id */,
int /* request id */,
content::StreamOptions /* components */,
GURL /* security origin */,
@@ -113,12 +113,12 @@ IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_GenerateStream,
// Request to cancel the request for a new media stream.
IPC_MESSAGE_CONTROL2(MediaStreamHostMsg_CancelGenerateStream,
- int /* render view id */,
+ int /* render frame id */,
int /* request id */)
// Request to close a device that has been opened by GenerateStream.
IPC_MESSAGE_CONTROL2(MediaStreamHostMsg_StopStreamDevice,
- int /* render view id */,
+ int /* render frame id */,
std::string /*device_id*/)
// Request to enumerate devices.
@@ -129,7 +129,7 @@ IPC_MESSAGE_CONTROL2(MediaStreamHostMsg_GetSources,
// Request to enumerate devices.
// Used by Pepper and WebRTC.
IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_EnumerateDevices,
- int /* render view id */,
+ int /* render frame id */,
int /* request id */,
content::MediaStreamType /* type */,
GURL /* security origin */,
@@ -137,12 +137,12 @@ IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_EnumerateDevices,
// Request to stop enumerating devices.
IPC_MESSAGE_CONTROL2(MediaStreamHostMsg_CancelEnumerateDevices,
- int /* render view id */,
+ int /* render frame id */,
int /* request id */)
// Request to open the device.
IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_OpenDevice,
- int /* render view id */,
+ int /* render frame id */,
int /* request id */,
std::string /* device_id */,
content::MediaStreamType /* type */,
@@ -150,5 +150,5 @@ IPC_MESSAGE_CONTROL5(MediaStreamHostMsg_OpenDevice,
// Request to close a device.
IPC_MESSAGE_CONTROL2(MediaStreamHostMsg_CloseDevice,
- int /* render view id */,
+ int /* render frame id */,
std::string /*label*/)
diff --git a/content/common/media/media_stream_options.cc b/content/common/media/media_stream_options.cc
index c727b63..83add2a 100644
--- a/content/common/media/media_stream_options.cc
+++ b/content/common/media/media_stream_options.cc
@@ -42,13 +42,13 @@ bool GetFirstConstraintByName(const StreamOptions::Constraints& mandatory,
std::string* value,
bool* is_mandatory) {
if (GetFirstConstraintByName(mandatory, name, value)) {
- if (is_mandatory)
- *is_mandatory = true;
- return true;
- }
if (is_mandatory)
- *is_mandatory = false;
- return GetFirstConstraintByName(optional, name, value);
+ *is_mandatory = true;
+ return true;
+ }
+ if (is_mandatory)
+ *is_mandatory = false;
+ return GetFirstConstraintByName(optional, name, value);
}
} // namespace
diff --git a/content/public/browser/media_observer.h b/content/public/browser/media_observer.h
index dca5b85..321e7d0 100644
--- a/content/public/browser/media_observer.h
+++ b/content/public/browser/media_observer.h
@@ -24,10 +24,10 @@ class MediaObserver {
// Called when a media request changes state.
virtual void OnMediaRequestStateChanged(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
- const MediaStreamDevice& device,
+ MediaStreamType stream_type,
MediaRequestState state) = 0;
// Called when an audio stream is being created.
diff --git a/content/public/browser/speech_recognition_session_context.cc b/content/public/browser/speech_recognition_session_context.cc
index 9b6575b..b185be8 100644
--- a/content/public/browser/speech_recognition_session_context.cc
+++ b/content/public/browser/speech_recognition_session_context.cc
@@ -11,6 +11,7 @@ namespace content {
SpeechRecognitionSessionContext::SpeechRecognitionSessionContext()
: render_process_id(0),
render_view_id(0),
+ render_frame_id(0),
guest_render_view_id(MSG_ROUTING_NONE),
embedder_render_process_id(0),
embedder_render_view_id(MSG_ROUTING_NONE),
diff --git a/content/public/browser/speech_recognition_session_context.h b/content/public/browser/speech_recognition_session_context.h
index d092a5d..532a4e4 100644
--- a/content/public/browser/speech_recognition_session_context.h
+++ b/content/public/browser/speech_recognition_session_context.h
@@ -26,6 +26,7 @@ struct CONTENT_EXPORT SpeechRecognitionSessionContext {
int render_process_id;
int render_view_id;
+ int render_frame_id;
// Browser plugin guest's render view id, if this context represents a speech
// recognition request from an embedder on behalf of the guest. This is used
diff --git a/content/public/common/media_stream_request.cc b/content/public/common/media_stream_request.cc
index cb3b8ed8..dc5e156 100644
--- a/content/public/common/media_stream_request.cc
+++ b/content/public/common/media_stream_request.cc
@@ -85,7 +85,7 @@ const MediaStreamDevice* MediaStreamDevices::FindById(
MediaStreamRequest::MediaStreamRequest(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
bool user_gesture,
@@ -95,7 +95,7 @@ MediaStreamRequest::MediaStreamRequest(
MediaStreamType audio_type,
MediaStreamType video_type)
: render_process_id(render_process_id),
- render_view_id(render_view_id),
+ render_frame_id(render_frame_id),
page_request_id(page_request_id),
security_origin(security_origin),
user_gesture(user_gesture),
diff --git a/content/public/common/media_stream_request.h b/content/public/common/media_stream_request.h
index 5a91fd1..6d882ea 100644
--- a/content/public/common/media_stream_request.h
+++ b/content/public/common/media_stream_request.h
@@ -192,7 +192,7 @@ typedef std::map<MediaStreamType, MediaStreamDevices> MediaStreamDeviceMap;
struct CONTENT_EXPORT MediaStreamRequest {
MediaStreamRequest(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
int page_request_id,
const GURL& security_origin,
bool user_gesture,
@@ -209,12 +209,12 @@ struct CONTENT_EXPORT MediaStreamRequest {
// displayed for this renderer.
int render_process_id;
- // This is the render view id for the renderer associated with generating
+ // This is the render frame id for the renderer associated with generating
// frames for a MediaStream. Any indicators associated with a capture will be
// displayed for this renderer.
- int render_view_id;
+ int render_frame_id;
- // The unique id combined with render_process_id and render_view_id for
+ // The unique id combined with render_process_id and render_frame_id for
// identifying this request. This is used for cancelling request.
int page_request_id;
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index ac836bb..d298065 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -54,6 +54,10 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidClearWindowObject() {}
virtual void DidChangeName(const base::string16& name) {}
+ // Called when the frame will soon be closed. This is the last opportunity to
+ // send messages to the host (e.g., for clean-up, shutdown, etc.).
+ virtual void FrameWillClose() {}
+
// Called when we receive a console message from Blink for which we requested
// extra details (like the stack trace). |message| is the error message,
// |source| is the Blink-reported source of the error (either external or
diff --git a/content/renderer/media/media_stream_audio_source.cc b/content/renderer/media/media_stream_audio_source.cc
index 069f4e3..d988552 100644
--- a/content/renderer/media/media_stream_audio_source.cc
+++ b/content/renderer/media/media_stream_audio_source.cc
@@ -4,14 +4,28 @@
#include "content/renderer/media/media_stream_audio_source.h"
+#include "content/renderer/render_frame_impl.h"
+#include "content/renderer/render_view_impl.h"
+
namespace content {
+namespace {
+// TODO(miu): This is a temporary hack until the Chrome audio vertical is
+// migrated for the Cross-Site Isolation project. http://crbug.com/392596
+int ToRenderViewId(int render_frame_id) {
+ RenderFrameImpl* const frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ RenderViewImpl* const view = frame ? frame->render_view() : NULL;
+ return view ? view->GetRoutingID() : -1;
+}
+} // namespace
+
MediaStreamAudioSource::MediaStreamAudioSource(
- int render_view_id,
+ int render_frame_id,
const StreamDeviceInfo& device_info,
const SourceStoppedCallback& stop_callback,
PeerConnectionDependencyFactory* factory)
- : render_view_id_(render_view_id),
+ : render_view_id_(ToRenderViewId(render_frame_id)),
factory_(factory) {
SetDeviceInfo(device_info);
SetStopCallback(stop_callback);
diff --git a/content/renderer/media/media_stream_audio_source.h b/content/renderer/media/media_stream_audio_source.h
index 29f1d4c..7d49a43 100644
--- a/content/renderer/media/media_stream_audio_source.h
+++ b/content/renderer/media/media_stream_audio_source.h
@@ -17,7 +17,7 @@ namespace content {
class CONTENT_EXPORT MediaStreamAudioSource
: NON_EXPORTED_BASE(public MediaStreamSource) {
public:
- MediaStreamAudioSource(int render_view_id,
+ MediaStreamAudioSource(int render_frame_id,
const StreamDeviceInfo& device_info,
const SourceStoppedCallback& stop_callback,
PeerConnectionDependencyFactory* factory);
@@ -49,15 +49,15 @@ class CONTENT_EXPORT MediaStreamAudioSource
virtual void DoStopSource() OVERRIDE;
private:
- int render_view_id_; // Render view ID that created this source.
+ const int render_view_id_; // Render view ID that created this source.
+ PeerConnectionDependencyFactory* const factory_;
+
// This member holds an instance of webrtc::LocalAudioSource. This is used
// as a container for audio options.
scoped_refptr<webrtc::AudioSourceInterface> local_audio_source_;
scoped_refptr<WebRtcAudioCapturer> audio_capturer_;
- PeerConnectionDependencyFactory* factory_;
-
DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioSource);
};
diff --git a/content/renderer/media/media_stream_dispatcher.cc b/content/renderer/media/media_stream_dispatcher.cc
index e2675a8..9903bdf 100644
--- a/content/renderer/media/media_stream_dispatcher.cc
+++ b/content/renderer/media/media_stream_dispatcher.cc
@@ -5,11 +5,9 @@
#include "content/renderer/media/media_stream_dispatcher.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "content/common/media/media_stream_messages.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
#include "content/renderer/render_thread_impl.h"
-#include "content/renderer/render_view_impl.h"
#include "media/audio/audio_parameters.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "url/gurl.h"
@@ -63,9 +61,8 @@ struct MediaStreamDispatcher::Stream {
StreamDeviceInfoArray video_array;
};
-MediaStreamDispatcher::MediaStreamDispatcher(RenderViewImpl* render_view)
- : RenderViewObserver(render_view),
- main_loop_(base::MessageLoopProxy::current()),
+MediaStreamDispatcher::MediaStreamDispatcher(RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame),
next_ipc_id_(0) {
}
@@ -76,7 +73,7 @@ void MediaStreamDispatcher::GenerateStream(
const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler,
const StreamOptions& components,
const GURL& security_origin) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::GenerateStream(" << request_id << ")";
requests_.push_back(Request(event_handler, request_id, next_ipc_id_));
@@ -88,7 +85,7 @@ void MediaStreamDispatcher::GenerateStream(
void MediaStreamDispatcher::CancelGenerateStream(
int request_id,
const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::CancelGenerateStream"
<< ", {request_id = " << request_id << "}";
@@ -106,7 +103,7 @@ void MediaStreamDispatcher::CancelGenerateStream(
void MediaStreamDispatcher::StopStreamDevice(
const StreamDeviceInfo& device_info) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::StopStreamDevice"
<< ", {device_id = " << device_info.device.id << "}";
// Remove |device_info| from all streams in |label_stream_map_|.
@@ -128,9 +125,10 @@ void MediaStreamDispatcher::StopStreamDevice(
}
if (!device_found) {
- // TODO(perkj): This can currently happen since there is one
- // MediaStreamDispatcher per RenderView but there is one MediaStreamImpl
- // per RenderFrame. http://crbug/368030.
+ // TODO(perkj): Revisit this. It used to be true (but isn't anymore) that
+ // there was one MediaStreamDispatcher per RenderView, but one
+ // MediaStreamImpl per RenderFrame. Now both MediaStreamDispatcher and
+ // MediaStreamImpl are 1:1 per RenderFrame. http://crbug/368030.
return;
}
@@ -144,7 +142,7 @@ void MediaStreamDispatcher::EnumerateDevices(
MediaStreamType type,
const GURL& security_origin,
bool hide_labels_if_no_access) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
type == MEDIA_DEVICE_VIDEO_CAPTURE ||
type == MEDIA_DEVICE_AUDIO_OUTPUT);
@@ -167,7 +165,7 @@ void MediaStreamDispatcher::EnumerateDevices(
void MediaStreamDispatcher::StopEnumerateDevices(
int request_id,
const base::WeakPtr<MediaStreamDispatcherEventHandler>& event_handler) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::StopEnumerateDevices("
<< request_id << ")";
for (RequestList::iterator it = requests_.begin(); it != requests_.end();
@@ -187,7 +185,7 @@ void MediaStreamDispatcher::OpenDevice(
const std::string& device_id,
MediaStreamType type,
const GURL& security_origin) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::OpenDevice(" << request_id << ")";
requests_.push_back(Request(event_handler, request_id, next_ipc_id_));
@@ -205,7 +203,7 @@ void MediaStreamDispatcher::CancelOpenDevice(
}
void MediaStreamDispatcher::CloseDevice(const std::string& label) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!label.empty());
DVLOG(1) << "MediaStreamDispatcher::CloseDevice"
<< ", {label = " << label << "}";
@@ -218,6 +216,10 @@ void MediaStreamDispatcher::CloseDevice(const std::string& label) {
Send(new MediaStreamHostMsg_CloseDevice(routing_id(), label));
}
+void MediaStreamDispatcher::OnDestruct() {
+ // Do not self-destruct. MediaStreamImpl owns |this|.
+}
+
bool MediaStreamDispatcher::Send(IPC::Message* message) {
if (!RenderThread::Get()) {
delete message;
@@ -252,7 +254,7 @@ void MediaStreamDispatcher::OnStreamGenerated(
const std::string& label,
const StreamDeviceInfoArray& audio_array,
const StreamDeviceInfoArray& video_array) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
for (RequestList::iterator it = requests_.begin();
it != requests_.end(); ++it) {
@@ -278,7 +280,7 @@ void MediaStreamDispatcher::OnStreamGenerated(
void MediaStreamDispatcher::OnStreamGenerationFailed(
int request_id,
content::MediaStreamRequestResult result) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
for (RequestList::iterator it = requests_.begin();
it != requests_.end(); ++it) {
Request& request = *it;
@@ -297,7 +299,7 @@ void MediaStreamDispatcher::OnStreamGenerationFailed(
void MediaStreamDispatcher::OnDeviceStopped(
const std::string& label,
const StreamDeviceInfo& device_info) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "MediaStreamDispatcher::OnDeviceStopped("
<< "{label = " << label << "})"
<< ", {device_id = " << device_info.device.id << "})";
@@ -324,7 +326,7 @@ void MediaStreamDispatcher::OnDeviceStopped(
void MediaStreamDispatcher::OnDevicesEnumerated(
int request_id,
const StreamDeviceInfoArray& device_array) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_GE(request_id, 0);
for (RequestList::iterator it = requests_.begin(); it != requests_.end();
@@ -340,7 +342,7 @@ void MediaStreamDispatcher::OnDeviceOpened(
int request_id,
const std::string& label,
const StreamDeviceInfo& device_info) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
for (RequestList::iterator it = requests_.begin();
it != requests_.end(); ++it) {
Request& request = *it;
@@ -367,7 +369,7 @@ void MediaStreamDispatcher::OnDeviceOpened(
}
void MediaStreamDispatcher::OnDeviceOpenFailed(int request_id) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
for (RequestList::iterator it = requests_.begin();
it != requests_.end(); ++it) {
Request& request = *it;
@@ -385,7 +387,7 @@ void MediaStreamDispatcher::OnDeviceOpenFailed(int request_id) {
int MediaStreamDispatcher::audio_session_id(const std::string& label,
int index) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
LabelStreamMap::iterator it = label_stream_map_.find(label);
if (it == label_stream_map_.end() ||
it->second.audio_array.size() <= static_cast<size_t>(index)) {
@@ -395,13 +397,13 @@ int MediaStreamDispatcher::audio_session_id(const std::string& label,
}
bool MediaStreamDispatcher::IsStream(const std::string& label) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
return label_stream_map_.find(label) != label_stream_map_.end();
}
int MediaStreamDispatcher::video_session_id(const std::string& label,
int index) {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
LabelStreamMap::iterator it = label_stream_map_.find(label);
if (it == label_stream_map_.end() ||
it->second.video_array.size() <= static_cast<size_t>(index)) {
@@ -411,7 +413,7 @@ int MediaStreamDispatcher::video_session_id(const std::string& label,
}
bool MediaStreamDispatcher::IsAudioDuckingActive() const {
- DCHECK(main_loop_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
LabelStreamMap::const_iterator stream_it = label_stream_map_.begin();
while (stream_it != label_stream_map_.end()) {
const StreamDeviceInfoArray& audio_array = stream_it->second.audio_array;
diff --git a/content/renderer/media/media_stream_dispatcher.h b/content/renderer/media/media_stream_dispatcher.h
index 59363a3..c4e5136 100644
--- a/content/renderer/media/media_stream_dispatcher.h
+++ b/content/renderer/media/media_stream_dispatcher.h
@@ -13,9 +13,10 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h"
-#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
namespace base {
@@ -24,18 +25,16 @@ class MessageLoopProxy;
namespace content {
-class RenderViewImpl;
-
// MediaStreamDispatcher is a delegate for the Media Stream API messages.
// MediaStreams are used by WebKit to open media devices such as Video Capture
// and Audio input devices.
// It's the complement of MediaStreamDispatcherHost (owned by
// BrowserRenderProcessHost).
class CONTENT_EXPORT MediaStreamDispatcher
- : public RenderViewObserver,
+ : public RenderFrameObserver,
public base::SupportsWeakPtr<MediaStreamDispatcher> {
public:
- explicit MediaStreamDispatcher(RenderViewImpl* render_view);
+ explicit MediaStreamDispatcher(RenderFrame* render_frame);
virtual ~MediaStreamDispatcher();
// Request a new media stream to be created.
@@ -115,11 +114,12 @@ class CONTENT_EXPORT MediaStreamDispatcher
// opened it.
struct Stream;
- // RenderViewObserver OVERRIDE.
+ // RenderFrameObserver OVERRIDE.
+ virtual void OnDestruct() OVERRIDE;
virtual bool Send(IPC::Message* message) OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Messages from the browser.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnStreamGenerated(
int request_id,
const std::string& label,
@@ -140,7 +140,7 @@ class CONTENT_EXPORT MediaStreamDispatcher
void OnDeviceOpenFailed(int request_id);
// Used for DCHECKs so methods calls won't execute in the wrong thread.
- scoped_refptr<base::MessageLoopProxy> main_loop_;
+ base::ThreadChecker thread_checker_;
int next_ipc_id_;
typedef std::map<std::string, Stream> LabelStreamMap;
diff --git a/content/renderer/media/media_stream_dispatcher_unittest.cc b/content/renderer/media/media_stream_dispatcher_unittest.cc
index 62a6f70..6e80f98 100644
--- a/content/renderer/media/media_stream_dispatcher_unittest.cc
+++ b/content/renderer/media/media_stream_dispatcher_unittest.cc
@@ -109,7 +109,7 @@ class MediaStreamDispatcherUnderTest : public MediaStreamDispatcher {
MediaStreamDispatcherUnderTest() : MediaStreamDispatcher(NULL) {}
using MediaStreamDispatcher::GetNextIpcIdForTest;
- using RenderViewObserver::OnMessageReceived;
+ using RenderFrameObserver::OnMessageReceived;
};
class MediaStreamDispatcherTest : public ::testing::Test {
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 79f86a8..887b593 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -12,6 +12,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/public/renderer/render_frame.h"
#include "content/renderer/media/media_stream.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/media_stream_dispatcher.h"
@@ -82,15 +83,22 @@ struct MediaStreamImpl::MediaDevicesRequestInfo {
};
MediaStreamImpl::MediaStreamImpl(
- RenderView* render_view,
- MediaStreamDispatcher* media_stream_dispatcher,
- PeerConnectionDependencyFactory* dependency_factory)
- : RenderViewObserver(render_view),
+ RenderFrame* render_frame,
+ PeerConnectionDependencyFactory* dependency_factory,
+ scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher)
+ : RenderFrameObserver(render_frame),
dependency_factory_(dependency_factory),
- media_stream_dispatcher_(media_stream_dispatcher) {
+ media_stream_dispatcher_(media_stream_dispatcher.Pass()),
+ weak_factory_(this) {
+ DCHECK(dependency_factory_);
+ DCHECK(media_stream_dispatcher_.get());
}
MediaStreamImpl::~MediaStreamImpl() {
+ // Force-close all outstanding user media requests and local sources here,
+ // before the outstanding WeakPtrs are invalidated, to ensure a clean
+ // shutdown.
+ FrameWillClose();
}
void MediaStreamImpl::requestUserMedia(
@@ -108,7 +116,6 @@ void MediaStreamImpl::requestUserMedia(
int request_id = g_next_request_id++;
StreamOptions options;
- blink::WebLocalFrame* frame = NULL;
GURL security_origin;
bool enable_automatic_output_device_selection = false;
@@ -142,11 +149,9 @@ void MediaStreamImpl::requestUserMedia(
}
security_origin = GURL(user_media_request.securityOrigin().toString());
- // Get the WebFrame that requested a MediaStream.
- // The frame is needed to tell the MediaStreamDispatcher when a stream goes
- // out of scope.
- frame = user_media_request.ownerDocument().frame();
- DCHECK(frame);
+ DCHECK(render_frame()->GetWebFrame() ==
+ static_cast<blink::WebFrame*>(
+ user_media_request.ownerDocument().frame()));
}
DVLOG(1) << "MediaStreamImpl::requestUserMedia(" << request_id << ", [ "
@@ -176,12 +181,12 @@ void MediaStreamImpl::requestUserMedia(
mandatory_video ? "true":"false"));
user_media_requests_.push_back(
- new UserMediaRequestInfo(request_id, frame, user_media_request,
- enable_automatic_output_device_selection));
+ new UserMediaRequestInfo(request_id, user_media_request,
+ enable_automatic_output_device_selection));
media_stream_dispatcher_->GenerateStream(
request_id,
- AsWeakPtr(),
+ weak_factory_.GetWeakPtr(),
options,
security_origin);
}
@@ -226,21 +231,21 @@ void MediaStreamImpl::requestMediaDevices(
media_stream_dispatcher_->EnumerateDevices(
audio_input_request_id,
- AsWeakPtr(),
+ weak_factory_.GetWeakPtr(),
MEDIA_DEVICE_AUDIO_CAPTURE,
security_origin,
true);
media_stream_dispatcher_->EnumerateDevices(
video_input_request_id,
- AsWeakPtr(),
+ weak_factory_.GetWeakPtr(),
MEDIA_DEVICE_VIDEO_CAPTURE,
security_origin,
true);
media_stream_dispatcher_->EnumerateDevices(
audio_output_request_id,
- AsWeakPtr(),
+ weak_factory_.GetWeakPtr(),
MEDIA_DEVICE_AUDIO_OUTPUT,
security_origin,
true);
@@ -253,18 +258,7 @@ void MediaStreamImpl::cancelMediaDevicesRequest(
FindMediaDevicesRequestInfo(media_devices_request);
if (!request)
return;
-
- // Cancel device enumeration.
- media_stream_dispatcher_->StopEnumerateDevices(
- request->audio_input_request_id,
- AsWeakPtr());
- media_stream_dispatcher_->StopEnumerateDevices(
- request->video_input_request_id,
- AsWeakPtr());
- media_stream_dispatcher_->StopEnumerateDevices(
- request->audio_output_request_id,
- AsWeakPtr());
- DeleteMediaDevicesRequestInfo(request);
+ CancelAndDeleteMediaDevicesRequest(request);
}
// Callback from MediaStreamDispatcher.
@@ -334,7 +328,8 @@ void MediaStreamImpl::OnStreamGenerated(
// Wait for the tracks to be started successfully or to fail.
request_info->CallbackOnTracksStarted(
- base::Bind(&MediaStreamImpl::OnCreateNativeTracksCompleted, AsWeakPtr()));
+ base::Bind(&MediaStreamImpl::OnCreateNativeTracksCompleted,
+ weak_factory_.GetWeakPtr()));
}
// Callback from MediaStreamDispatcher.
@@ -380,7 +375,7 @@ void MediaStreamImpl::OnDeviceStopped(
for (LocalStreamSources::iterator device_it = local_sources_.begin();
device_it != local_sources_.end(); ++device_it) {
- if (device_it->source.id() == source.id()) {
+ if (device_it->id() == source.id()) {
local_sources_.erase(device_it);
break;
}
@@ -391,7 +386,6 @@ void MediaStreamImpl::InitializeSourceObject(
const StreamDeviceInfo& device,
blink::WebMediaStreamSource::Type type,
const blink::WebMediaConstraints& constraints,
- blink::WebFrame* frame,
blink::WebMediaStreamSource* webkit_source) {
const blink::WebMediaStreamSource* existing_source =
FindLocalSource(device);
@@ -415,18 +409,20 @@ void MediaStreamImpl::InitializeSourceObject(
webkit_source->setExtraData(
CreateVideoSource(
device,
- base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr())));
+ base::Bind(&MediaStreamImpl::OnLocalSourceStopped,
+ weak_factory_.GetWeakPtr())));
} else {
DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, type);
MediaStreamAudioSource* audio_source(
new MediaStreamAudioSource(
- RenderViewObserver::routing_id(),
+ RenderFrameObserver::routing_id(),
device,
- base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()),
+ base::Bind(&MediaStreamImpl::OnLocalSourceStopped,
+ weak_factory_.GetWeakPtr()),
dependency_factory_));
webkit_source->setExtraData(audio_source);
}
- local_sources_.push_back(LocalStreamSource(frame, *webkit_source));
+ local_sources_.push_back(*webkit_source);
}
MediaStreamVideoSource* MediaStreamImpl::CreateVideoSource(
@@ -450,7 +446,6 @@ void MediaStreamImpl::CreateVideoTracks(
InitializeSourceObject(devices[i],
blink::WebMediaStreamSource::TypeVideo,
constraints,
- request->frame,
&webkit_source);
(*webkit_tracks)[i] =
request->CreateAndStartVideoTrack(webkit_source, constraints);
@@ -491,7 +486,6 @@ void MediaStreamImpl::CreateAudioTracks(
InitializeSourceObject(overridden_audio_array[i],
blink::WebMediaStreamSource::TypeAudio,
constraints,
- request->frame,
&webkit_source);
(*webkit_tracks)[i].initialize(webkit_source);
request->StartAudioTrack((*webkit_tracks)[i], constraints);
@@ -585,19 +579,7 @@ void MediaStreamImpl::OnDevicesEnumerated(
}
EnumerateDevicesSucceded(&request->request, devices);
-
- // Cancel device enumeration.
- media_stream_dispatcher_->StopEnumerateDevices(
- request->audio_input_request_id,
- AsWeakPtr());
- media_stream_dispatcher_->StopEnumerateDevices(
- request->video_input_request_id,
- AsWeakPtr());
- media_stream_dispatcher_->StopEnumerateDevices(
- request->audio_output_request_id,
- AsWeakPtr());
-
- DeleteMediaDevicesRequestInfo(request);
+ CancelAndDeleteMediaDevicesRequest(request);
}
void MediaStreamImpl::OnDeviceOpened(
@@ -672,13 +654,13 @@ const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource(
const StreamDeviceInfo& device) const {
for (LocalStreamSources::const_iterator it = local_sources_.begin();
it != local_sources_.end(); ++it) {
- MediaStreamSource* source =
- static_cast<MediaStreamSource*>(it->source.extraData());
+ MediaStreamSource* const source =
+ static_cast<MediaStreamSource*>(it->extraData());
const StreamDeviceInfo& active_device = source->device_info();
if (active_device.device.id == device.device.id &&
active_device.device.type == device.device.type &&
active_device.session_id == device.session_id) {
- return &it->source;
+ return &(*it);
}
}
return NULL;
@@ -742,11 +724,19 @@ MediaStreamImpl::FindMediaDevicesRequestInfo(
return NULL;
}
-void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
+void MediaStreamImpl::CancelAndDeleteMediaDevicesRequest(
MediaDevicesRequestInfo* request) {
MediaDevicesRequests::iterator it = media_devices_requests_.begin();
for (; it != media_devices_requests_.end(); ++it) {
if ((*it) == request) {
+ // Cancel device enumeration.
+ media_stream_dispatcher_->StopEnumerateDevices(
+ request->audio_input_request_id, weak_factory_.GetWeakPtr());
+ media_stream_dispatcher_->StopEnumerateDevices(
+ request->video_input_request_id, weak_factory_.GetWeakPtr());
+ media_stream_dispatcher_->StopEnumerateDevices(
+ request->audio_output_request_id, weak_factory_.GetWeakPtr());
+
media_devices_requests_.erase(it);
return;
}
@@ -754,43 +744,28 @@ void MediaStreamImpl::DeleteMediaDevicesRequestInfo(
NOTREACHED();
}
-void MediaStreamImpl::FrameDetached(blink::WebFrame* frame) {
- // Do same thing as FrameWillClose.
- FrameWillClose(frame);
-}
-
-void MediaStreamImpl::FrameWillClose(blink::WebFrame* frame) {
- // Loop through all UserMediaRequests and find the requests that belong to the
- // frame that is being closed.
+void MediaStreamImpl::FrameWillClose() {
+ // Cancel all outstanding UserMediaRequests.
UserMediaRequests::iterator request_it = user_media_requests_.begin();
while (request_it != user_media_requests_.end()) {
- if ((*request_it)->frame == frame) {
- DVLOG(1) << "MediaStreamImpl::FrameWillClose: "
- << "Cancel user media request " << (*request_it)->request_id;
- // If the request is not generated, it means that a request
- // has been sent to the MediaStreamDispatcher to generate a stream
- // but MediaStreamDispatcher has not yet responded and we need to cancel
- // the request.
- if (!(*request_it)->generated) {
- media_stream_dispatcher_->CancelGenerateStream(
- (*request_it)->request_id, AsWeakPtr());
- }
- request_it = user_media_requests_.erase(request_it);
- } else {
- ++request_it;
+ DVLOG(1) << "MediaStreamImpl@" << this << "::FrameWillClose: "
+ << "Cancel user media request " << (*request_it)->request_id;
+ // If the request is not generated, it means that a request
+ // has been sent to the MediaStreamDispatcher to generate a stream
+ // but MediaStreamDispatcher has not yet responded and we need to cancel
+ // the request.
+ if (!(*request_it)->generated) {
+ media_stream_dispatcher_->CancelGenerateStream(
+ (*request_it)->request_id, weak_factory_.GetWeakPtr());
}
+ request_it = user_media_requests_.erase(request_it);
}
- // Loop through all current local sources and stop the sources that were
- // created by the frame that will be closed.
+ // Loop through all current local sources and stop the sources.
LocalStreamSources::iterator sources_it = local_sources_.begin();
while (sources_it != local_sources_.end()) {
- if (sources_it->frame == frame) {
- StopLocalSource(sources_it->source, true);
- sources_it = local_sources_.erase(sources_it);
- } else {
- ++sources_it;
- }
+ StopLocalSource(*sources_it, true);
+ sources_it = local_sources_.erase(sources_it);
}
}
@@ -802,7 +777,7 @@ void MediaStreamImpl::OnLocalSourceStopped(
bool device_found = false;
for (LocalStreamSources::iterator device_it = local_sources_.begin();
device_it != local_sources_.end(); ++device_it) {
- if (device_it->source.id() == source.id()) {
+ if (device_it->id() == source.id()) {
device_found = true;
local_sources_.erase(device_it);
break;
@@ -811,7 +786,7 @@ void MediaStreamImpl::OnLocalSourceStopped(
CHECK(device_found);
MediaStreamSource* source_impl =
- static_cast<MediaStreamSource*> (source.extraData());
+ static_cast<MediaStreamSource*>(source.extraData());
media_stream_dispatcher_->StopStreamDevice(source_impl->device_info());
}
@@ -819,7 +794,7 @@ void MediaStreamImpl::StopLocalSource(
const blink::WebMediaStreamSource& source,
bool notify_dispatcher) {
MediaStreamSource* source_impl =
- static_cast<MediaStreamSource*> (source.extraData());
+ static_cast<MediaStreamSource*>(source.extraData());
DVLOG(1) << "MediaStreamImpl::StopLocalSource("
<< "{device_id = " << source_impl->device_info().device.id << "})";
@@ -832,14 +807,12 @@ void MediaStreamImpl::StopLocalSource(
MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
int request_id,
- blink::WebFrame* frame,
const blink::WebUserMediaRequest& request,
bool enable_automatic_output_device_selection)
: request_id(request_id),
generated(false),
enable_automatic_output_device_selection(
enable_automatic_output_device_selection),
- frame(frame),
request(request),
request_failed_(false) {
}
diff --git a/content/renderer/media/media_stream_impl.h b/content/renderer/media/media_stream_impl.h
index ad96020..0effc2a 100644
--- a/content/renderer/media/media_stream_impl.h
+++ b/content/renderer/media/media_stream_impl.h
@@ -16,7 +16,7 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "content/common/content_export.h"
-#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
#include "content/renderer/media/media_stream_source.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
@@ -38,20 +38,23 @@ class VideoCapturerDelegate;
// (via MediaStreamDispatcher and MediaStreamDispatcherHost)
// in the browser process. It must be created, called and destroyed on the
// render thread.
-// MediaStreamImpl have weak pointers to a MediaStreamDispatcher.
class CONTENT_EXPORT MediaStreamImpl
- : public RenderViewObserver,
+ : public RenderFrameObserver,
NON_EXPORTED_BASE(public blink::WebUserMediaClient),
public MediaStreamDispatcherEventHandler,
- public base::SupportsWeakPtr<MediaStreamImpl>,
NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
+ // |render_frame| and |dependency_factory| must outlive this instance.
MediaStreamImpl(
- RenderView* render_view,
- MediaStreamDispatcher* media_stream_dispatcher,
- PeerConnectionDependencyFactory* dependency_factory);
+ RenderFrame* render_frame,
+ PeerConnectionDependencyFactory* dependency_factory,
+ scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher);
virtual ~MediaStreamImpl();
+ MediaStreamDispatcher* media_stream_dispatcher() const {
+ return media_stream_dispatcher_.get();
+ }
+
// blink::WebUserMediaClient implementation
virtual void requestUserMedia(
const blink::WebUserMediaRequest& user_media_request);
@@ -82,9 +85,8 @@ class CONTENT_EXPORT MediaStreamImpl
const StreamDeviceInfo& device_info) OVERRIDE;
virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
- // RenderViewObserver OVERRIDE
- virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
- virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
+ // RenderFrameObserver OVERRIDE
+ virtual void FrameWillClose() OVERRIDE;
protected:
// Called when |source| has been stopped from JavaScript.
@@ -119,7 +121,6 @@ class CONTENT_EXPORT MediaStreamImpl
ResourcesReady;
UserMediaRequestInfo(int request_id,
- blink::WebFrame* frame,
const blink::WebUserMediaRequest& request,
bool enable_automatic_output_device_selection);
~UserMediaRequestInfo();
@@ -128,7 +129,6 @@ class CONTENT_EXPORT MediaStreamImpl
// OnStreamGenerated.
bool generated;
const bool enable_automatic_output_device_selection;
- blink::WebFrame* frame; // WebFrame that requested the MediaStream.
blink::WebMediaStream web_stream;
blink::WebUserMediaRequest request;
@@ -160,17 +160,7 @@ class CONTENT_EXPORT MediaStreamImpl
};
typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
- struct LocalStreamSource {
- LocalStreamSource(blink::WebFrame* frame,
- const blink::WebMediaStreamSource& source)
- : frame(frame), source(source) {
- }
- // |frame| is the WebFrame that requested |source|. NULL in unit tests.
- // TODO(perkj): Change so that |frame| is not NULL in unit tests.
- blink::WebFrame* frame;
- blink::WebMediaStreamSource source;
- };
- typedef std::vector<LocalStreamSource> LocalStreamSources;
+ typedef std::vector<blink::WebMediaStreamSource> LocalStreamSources;
struct MediaDevicesRequestInfo;
typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests;
@@ -181,7 +171,6 @@ class CONTENT_EXPORT MediaStreamImpl
const StreamDeviceInfo& device,
blink::WebMediaStreamSource::Type type,
const blink::WebMediaConstraints& constraints,
- blink::WebFrame* frame,
blink::WebMediaStreamSource* webkit_source);
void CreateVideoTracks(
@@ -210,7 +199,7 @@ class CONTENT_EXPORT MediaStreamImpl
MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id);
MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(
const blink::WebMediaDevicesRequest& request);
- void DeleteMediaDevicesRequestInfo(MediaDevicesRequestInfo* request);
+ void CancelAndDeleteMediaDevicesRequest(MediaDevicesRequestInfo* request);
// Returns the source that use a device with |device.session_id|
// and |device.device.id|. NULL if such source doesn't exist.
@@ -224,11 +213,11 @@ class CONTENT_EXPORT MediaStreamImpl
// It's valid for the lifetime of RenderThread.
// TODO(xians): Remove this dependency once audio do not need it for local
// audio.
- PeerConnectionDependencyFactory* dependency_factory_;
+ PeerConnectionDependencyFactory* const dependency_factory_;
- // media_stream_dispatcher_ is a weak reference, owned by RenderView. It's
- // valid for the lifetime of RenderView.
- MediaStreamDispatcher* media_stream_dispatcher_;
+ // MediaStreamImpl owns MediaStreamDispatcher instead of RenderFrameImpl
+ // (or RenderFrameObserver) to ensure tear-down occurs in the right order.
+ const scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher_;
LocalStreamSources local_sources_;
@@ -237,6 +226,10 @@ class CONTENT_EXPORT MediaStreamImpl
// Requests to enumerate media devices.
MediaDevicesRequests media_devices_requests_;
+ // Note: This member must be the last to ensure all outstanding weak pointers
+ // are invalidated first.
+ base::WeakPtrFactory<MediaStreamImpl> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
};
diff --git a/content/renderer/media/media_stream_impl_unittest.cc b/content/renderer/media/media_stream_impl_unittest.cc
index cddf119..997340a 100644
--- a/content/renderer/media/media_stream_impl_unittest.cc
+++ b/content/renderer/media/media_stream_impl_unittest.cc
@@ -43,9 +43,11 @@ class MediaStreamImplUnderTest : public MediaStreamImpl {
REQUEST_FAILED,
};
- MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
- PeerConnectionDependencyFactory* dependency_factory)
- : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
+ MediaStreamImplUnderTest(
+ PeerConnectionDependencyFactory* dependency_factory,
+ scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher)
+ : MediaStreamImpl(
+ NULL, dependency_factory, media_stream_dispatcher.Pass()),
state_(REQUEST_NOT_STARTED),
result_(NUM_MEDIA_REQUEST_RESULTS),
factory_(dependency_factory),
@@ -128,10 +130,11 @@ class MediaStreamImplTest : public ::testing::Test {
virtual void SetUp() {
// Create our test object.
child_process_.reset(new ChildProcess());
- ms_dispatcher_.reset(new MockMediaStreamDispatcher());
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
- dependency_factory_.get()));
+ ms_dispatcher_ = new MockMediaStreamDispatcher();
+ ms_impl_.reset(new MediaStreamImplUnderTest(
+ dependency_factory_.get(),
+ scoped_ptr<MediaStreamDispatcher>(ms_dispatcher_).Pass()));
}
blink::WebMediaStream RequestLocalMediaStream() {
@@ -199,7 +202,7 @@ class MediaStreamImplTest : public ::testing::Test {
protected:
base::MessageLoop message_loop_;
scoped_ptr<ChildProcess> child_process_;
- scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
+ MockMediaStreamDispatcher* ms_dispatcher_; // Owned my |ms_impl_|.
scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
scoped_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
};
@@ -329,16 +332,13 @@ TEST_F(MediaStreamImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}
-// Test that the MediaStreams are deleted if the owning WebFrame is deleted.
+// Test that the MediaStreams are deleted if the owning WebFrame is closing.
// In the unit test the owning frame is NULL.
TEST_F(MediaStreamImplTest, FrameWillClose) {
// Test a stream with both audio and video.
blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
blink::WebMediaStream desc2 = RequestLocalMediaStream();
-
- // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
- // In the unit test the owning frame is NULL.
- ms_impl_->FrameWillClose(NULL);
+ ms_impl_->FrameWillClose();
EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}
@@ -387,7 +387,7 @@ TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
// being generated by the MediaStreamDispatcher.
TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
ms_impl_->RequestUserMedia();
- ms_impl_->FrameWillClose(NULL);
+ ms_impl_->FrameWillClose();
EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
@@ -401,7 +401,7 @@ TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
ms_impl_->RequestUserMedia();
FakeMediaStreamDispatcherRequestUserMediaComplete();
EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
- ms_impl_->FrameWillClose(NULL);
+ ms_impl_->FrameWillClose();
EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
@@ -413,7 +413,7 @@ TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
TEST_F(MediaStreamImplTest, StopTrackAfterReload) {
blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
- ms_impl_->FrameWillClose(NULL);
+ ms_impl_->FrameWillClose();
EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index 3193dba..006f12f 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -12,7 +12,7 @@
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/media/webrtc_logging.h"
-#include "content/renderer/render_view_impl.h"
+#include "content/renderer/render_frame_impl.h"
#include "media/audio/audio_output_device.h"
#include "media/audio/audio_parameters.h"
#include "media/audio/sample_rates.h"
@@ -186,10 +186,12 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
// Returns either AudioParameters::NO_EFFECTS or AudioParameters::DUCKING
// depending on whether or not an input element is currently open with
// ducking enabled.
-int GetCurrentDuckingFlag(int render_view_id) {
- RenderViewImpl* render_view = RenderViewImpl::FromRoutingID(render_view_id);
- if (render_view && render_view->media_stream_dispatcher() &&
- render_view->media_stream_dispatcher()->IsAudioDuckingActive()) {
+int GetCurrentDuckingFlag(int render_frame_id) {
+ RenderFrameImpl* const frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ MediaStreamDispatcher* const dispatcher = frame ?
+ frame->GetMediaStreamDispatcher() : NULL;
+ if (dispatcher && dispatcher->IsAudioDuckingActive()) {
return media::AudioParameters::DUCKING;
}
@@ -218,7 +220,7 @@ WebRtcAudioRenderer::WebRtcAudioRenderer(
sink_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_STEREO, 0, sample_rate, 16,
frames_per_buffer,
- GetCurrentDuckingFlag(source_render_view_id)) {
+ GetCurrentDuckingFlag(source_render_frame_id)) {
WebRtcLogMessage(base::StringPrintf(
"WAR::WAR. source_render_view_id=%d"
", session_id=%d, sample_rate=%d, frames_per_buffer=%d, effects=%i",
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc
index ed98b28..f13e7b0 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.cc
+++ b/content/renderer/media/webrtc_local_audio_renderer.cc
@@ -12,7 +12,7 @@
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
-#include "content/renderer/render_view_impl.h"
+#include "content/renderer/render_frame_impl.h"
#include "media/audio/audio_output_device.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_fifo.h"
@@ -266,11 +266,11 @@ void WebRtcLocalAudioRenderer::ReconfigureSink(
DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()";
int implicit_ducking_effect = 0;
- RenderViewImpl* render_view =
- RenderViewImpl::FromRoutingID(source_render_view_id_);
- if (render_view &&
- render_view->media_stream_dispatcher() &&
- render_view->media_stream_dispatcher()->IsAudioDuckingActive()) {
+ RenderFrameImpl* const frame =
+ RenderFrameImpl::FromRoutingID(source_render_frame_id_);
+ MediaStreamDispatcher* const dispatcher = frame ?
+ frame->GetMediaStreamDispatcher() : NULL;
+ if (dispatcher && dispatcher->IsAudioDuckingActive()) {
DVLOG(1) << "Forcing DUCKING to be ON for output";
implicit_ducking_effect = media::AudioParameters::DUCKING;
} else {
diff --git a/content/renderer/pepper/pepper_audio_input_host.cc b/content/renderer/pepper/pepper_audio_input_host.cc
index a86e177..0da9cd1 100644
--- a/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/content/renderer/pepper/pepper_audio_input_host.cc
@@ -10,7 +10,7 @@
#include "content/renderer/pepper/pepper_platform_audio_input.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_view_impl.h"
+#include "content/renderer/render_frame_impl.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
@@ -46,8 +46,8 @@ PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
renderer_ppapi_host_(host),
audio_input_(NULL),
enumeration_helper_(this,
- PepperMediaDeviceManager::GetForRenderView(
- host->GetRenderViewForInstance(pp_instance())),
+ PepperMediaDeviceManager::GetForRenderFrame(
+ host->GetRenderFrameForInstance(pp_instance())),
PP_DEVICETYPE_DEV_AUDIOCAPTURE,
host->GetDocumentURL(instance)) {}
@@ -98,16 +98,14 @@ int32_t PepperAudioInputHost::OnOpen(ppapi::host::HostMessageContext* context,
// When it is done, we'll get called back on StreamCreated() or
// StreamCreationFailed().
- RenderViewImpl* render_view = static_cast<RenderViewImpl*>(
- renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()));
-
- audio_input_ =
- PepperPlatformAudioInput::Create(render_view->AsWeakPtr(),
- device_id,
- document_url,
- static_cast<int>(sample_rate),
- static_cast<int>(sample_frame_count),
- this);
+ audio_input_ = PepperPlatformAudioInput::Create(
+ renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
+ GetRoutingID(),
+ device_id,
+ document_url,
+ static_cast<int>(sample_rate),
+ static_cast<int>(sample_frame_count),
+ this);
if (audio_input_) {
open_context_ = context->MakeReplyMessageContext();
return PP_OK_COMPLETIONPENDING;
diff --git a/content/renderer/pepper/pepper_media_device_manager.cc b/content/renderer/pepper/pepper_media_device_manager.cc
index b36df31..3c5abdc 100644
--- a/content/renderer/pepper/pepper_media_device_manager.cc
+++ b/content/renderer/pepper/pepper_media_device_manager.cc
@@ -6,7 +6,7 @@
#include "base/logging.h"
#include "content/renderer/media/media_stream_dispatcher.h"
-#include "content/renderer/render_view_impl.h"
+#include "content/renderer/render_frame_impl.h"
#include "ppapi/shared_impl/ppb_device_ref_shared.h"
namespace content {
@@ -23,18 +23,18 @@ ppapi::DeviceRefData FromStreamDeviceInfo(const StreamDeviceInfo& info) {
} // namespace
-PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderView(
- RenderView* render_view) {
+PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderFrame(
+ RenderFrame* render_frame) {
PepperMediaDeviceManager* handler =
- PepperMediaDeviceManager::Get(render_view);
+ PepperMediaDeviceManager::Get(render_frame);
if (!handler)
- handler = new PepperMediaDeviceManager(render_view);
+ handler = new PepperMediaDeviceManager(render_frame);
return handler;
}
-PepperMediaDeviceManager::PepperMediaDeviceManager(RenderView* render_view)
- : RenderViewObserver(render_view),
- RenderViewObserverTracker<PepperMediaDeviceManager>(render_view),
+PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame),
+ RenderFrameObserverTracker<PepperMediaDeviceManager>(render_frame),
next_id_(1) {}
PepperMediaDeviceManager::~PepperMediaDeviceManager() {
@@ -50,7 +50,7 @@ int PepperMediaDeviceManager::EnumerateDevices(
int request_id = next_id_++;
#if defined(ENABLE_WEBRTC)
- GetRenderViewImpl()->media_stream_dispatcher()->EnumerateDevices(
+ GetMediaStreamDispatcher()->EnumerateDevices(
request_id,
AsWeakPtr(),
PepperMediaDeviceManager::FromPepperDeviceType(type),
@@ -76,10 +76,20 @@ void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) {
// of EnumerateDevices.
base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&MediaStreamDispatcher::StopEnumerateDevices,
- GetRenderViewImpl()->media_stream_dispatcher()->AsWeakPtr(),
- request_id,
- AsWeakPtr()));
+ base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed,
+ AsWeakPtr(),
+ request_id));
+#endif
+}
+
+void PepperMediaDeviceManager::StopEnumerateDevicesDelayed(int request_id) {
+#if defined(ENABLE_WEBRTC)
+ // This method is being invoked by the message loop at some unknown
+ // point-in-time after StopEnumerateDevices(). Therefore, check that
+ // render_frame() is not NULL, in order to guarantee
+ // GetMediaStreamDispatcher() won't return NULL.
+ if (render_frame())
+ GetMediaStreamDispatcher()->StopEnumerateDevices(request_id, AsWeakPtr());
#endif
}
@@ -91,7 +101,7 @@ int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type,
int request_id = next_id_++;
#if defined(ENABLE_WEBRTC)
- GetRenderViewImpl()->media_stream_dispatcher()->OpenDevice(
+ GetMediaStreamDispatcher()->OpenDevice(
request_id,
AsWeakPtr(),
device_id,
@@ -112,14 +122,13 @@ void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
open_callbacks_.erase(request_id);
#if defined(ENABLE_WEBRTC)
- GetRenderViewImpl()->media_stream_dispatcher()->CancelOpenDevice(request_id,
- AsWeakPtr());
+ GetMediaStreamDispatcher()->CancelOpenDevice(request_id, AsWeakPtr());
#endif
}
void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
#if defined(ENABLE_WEBRTC)
- GetRenderViewImpl()->media_stream_dispatcher()->CloseDevice(label);
+ GetMediaStreamDispatcher()->CloseDevice(label);
#endif
}
@@ -128,11 +137,9 @@ int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
#if defined(ENABLE_WEBRTC)
switch (type) {
case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
- return GetRenderViewImpl()->media_stream_dispatcher()->audio_session_id(
- label, 0);
+ return GetMediaStreamDispatcher()->audio_session_id(label, 0);
case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
- return GetRenderViewImpl()->media_stream_dispatcher()->video_session_id(
- label, 0);
+ return GetMediaStreamDispatcher()->video_session_id(label, 0);
default:
NOTREACHED();
return 0;
@@ -236,8 +243,13 @@ void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id,
callback.Run(request_id, succeeded, label);
}
-RenderViewImpl* PepperMediaDeviceManager::GetRenderViewImpl() {
- return static_cast<RenderViewImpl*>(render_view());
+MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher()
+ const {
+ DCHECK(render_frame());
+ MediaStreamDispatcher* const dispatcher =
+ static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher();
+ DCHECK(dispatcher);
+ return dispatcher;
}
} // namespace content
diff --git a/content/renderer/pepper/pepper_media_device_manager.h b/content/renderer/pepper/pepper_media_device_manager.h
index 6fa7d7a..b3d94e0 100644
--- a/content/renderer/pepper/pepper_media_device_manager.h
+++ b/content/renderer/pepper/pepper_media_device_manager.h
@@ -8,22 +8,22 @@
#include <map>
#include "base/memory/weak_ptr.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "content/public/renderer/render_frame_observer_tracker.h"
#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
-#include "content/public/renderer/render_view_observer_tracker.h"
-#include "content/public/renderer/render_view_observer.h"
namespace content {
-class RenderViewImpl;
+class MediaStreamDispatcher;
class PepperMediaDeviceManager
: public MediaStreamDispatcherEventHandler,
public PepperDeviceEnumerationHostHelper::Delegate,
- public RenderViewObserver,
- public RenderViewObserverTracker<PepperMediaDeviceManager>,
+ public RenderFrameObserver,
+ public RenderFrameObserverTracker<PepperMediaDeviceManager>,
public base::SupportsWeakPtr<PepperMediaDeviceManager> {
public:
- static PepperMediaDeviceManager* GetForRenderView(RenderView* render_view);
+ static PepperMediaDeviceManager* GetForRenderFrame(RenderFrame* render_frame);
virtual ~PepperMediaDeviceManager();
// PepperDeviceEnumerationHostHelper::Delegate implementation:
@@ -78,13 +78,18 @@ class PepperMediaDeviceManager
static PP_DeviceType_Dev FromMediaStreamType(MediaStreamType type);
private:
- PepperMediaDeviceManager(RenderView* render_view);
+ explicit PepperMediaDeviceManager(RenderFrame* render_frame);
+
+ // Called by StopEnumerateDevices() after returing to the event loop, to avoid
+ // a reentrancy problem.
+ void StopEnumerateDevicesDelayed(int request_id);
void NotifyDeviceOpened(int request_id,
bool succeeded,
const std::string& label);
- RenderViewImpl* GetRenderViewImpl();
+
+ MediaStreamDispatcher* GetMediaStreamDispatcher() const;
int next_id_;
diff --git a/content/renderer/pepper/pepper_platform_audio_input.cc b/content/renderer/pepper/pepper_platform_audio_input.cc
index ed2bbcf..fafff22 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -12,6 +12,7 @@
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/pepper/pepper_audio_input_host.h"
#include "content/renderer/pepper/pepper_media_device_manager.h"
+#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "media/audio/audio_manager_base.h"
@@ -22,7 +23,7 @@ namespace content {
// static
PepperPlatformAudioInput* PepperPlatformAudioInput::Create(
- const base::WeakPtr<RenderViewImpl>& render_view,
+ int render_frame_id,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
@@ -30,7 +31,7 @@ PepperPlatformAudioInput* PepperPlatformAudioInput::Create(
PepperAudioInputHost* client) {
scoped_refptr<PepperPlatformAudioInput> audio_input(
new PepperPlatformAudioInput());
- if (audio_input->Initialize(render_view,
+ if (audio_input->Initialize(render_frame_id,
device_id,
document_url,
sample_rate,
@@ -139,12 +140,13 @@ PepperPlatformAudioInput::PepperPlatformAudioInput()
: client_(NULL),
main_message_loop_proxy_(base::MessageLoopProxy::current()),
io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()),
+ render_frame_id_(MSG_ROUTING_NONE),
create_stream_sent_(false),
pending_open_device_(false),
pending_open_device_id_(-1) {}
bool PepperPlatformAudioInput::Initialize(
- const base::WeakPtr<RenderViewImpl>& render_view,
+ int render_frame_id,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
@@ -152,15 +154,20 @@ bool PepperPlatformAudioInput::Initialize(
PepperAudioInputHost* client) {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
- if (!render_view.get() || !client)
+ RenderFrameImpl* const render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ if (!render_frame || !client)
+ return false;
+
+ render_frame_id_ = render_frame_id;
+ client_ = client;
+
+ if (!GetMediaDeviceManager())
return false;
ipc_ = RenderThreadImpl::current()
->audio_input_message_filter()
- ->CreateAudioInputIPC(render_view->GetRoutingID());
-
- render_view_ = render_view;
- client_ = client;
+ ->CreateAudioInputIPC(render_frame->render_view()->GetRoutingID());
params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
media::CHANNEL_LAYOUT_MONO,
@@ -230,12 +237,13 @@ void PepperPlatformAudioInput::OnDeviceOpened(int request_id,
pending_open_device_ = false;
pending_open_device_id_ = -1;
- if (succeeded && render_view_.get()) {
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (succeeded && device_manager) {
DCHECK(!label.empty());
label_ = label;
if (client_) {
- int session_id = GetMediaDeviceManager()->GetSessionID(
+ int session_id = device_manager->GetSessionID(
PP_DEVICETYPE_DEV_AUDIOCAPTURE, label);
io_message_loop_proxy_->PostTask(
FROM_HERE,
@@ -254,16 +262,18 @@ void PepperPlatformAudioInput::OnDeviceOpened(int request_id,
void PepperPlatformAudioInput::CloseDevice() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
- if (render_view_.get()) {
- if (!label_.empty()) {
- GetMediaDeviceManager()->CloseDevice(label_);
- label_.clear();
- }
- if (pending_open_device_) {
- GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
- pending_open_device_ = false;
- pending_open_device_id_ = -1;
- }
+ if (!label_.empty()) {
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (device_manager)
+ device_manager->CloseDevice(label_);
+ label_.clear();
+ }
+ if (pending_open_device_) {
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (device_manager)
+ device_manager->CancelOpenDevice(pending_open_device_id_);
+ pending_open_device_ = false;
+ pending_open_device_id_ = -1;
}
}
@@ -275,7 +285,12 @@ void PepperPlatformAudioInput::NotifyStreamCreationFailed() {
}
PepperMediaDeviceManager* PepperPlatformAudioInput::GetMediaDeviceManager() {
- return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
+ DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
+
+ RenderFrameImpl* const render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id_);
+ return render_frame ?
+ PepperMediaDeviceManager::GetForRenderFrame(render_frame) : NULL;
}
} // namespace content
diff --git a/content/renderer/pepper/pepper_platform_audio_input.h b/content/renderer/pepper/pepper_platform_audio_input.h
index 56a701a..e443577 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.h
+++ b/content/renderer/pepper/pepper_platform_audio_input.h
@@ -29,7 +29,6 @@ namespace content {
class PepperAudioInputHost;
class PepperMediaDeviceManager;
-class RenderViewImpl;
// PepperPlatformAudioInput is operated on two threads: the main thread (the
// thread on which objects are created) and the I/O thread. All public methods,
@@ -45,7 +44,7 @@ class PepperPlatformAudioInput
// Factory function, returns NULL on failure. StreamCreated() will be called
// when the stream is created.
static PepperPlatformAudioInput* Create(
- const base::WeakPtr<RenderViewImpl>& render_view,
+ int render_frame_id,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
@@ -76,7 +75,7 @@ class PepperPlatformAudioInput
PepperPlatformAudioInput();
- bool Initialize(const base::WeakPtr<RenderViewImpl>& render_view,
+ bool Initialize(int render_frame_id,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
@@ -93,6 +92,8 @@ class PepperPlatformAudioInput
void CloseDevice();
void NotifyStreamCreationFailed();
+ // Can return NULL if the RenderFrame referenced by |render_frame_id_| has
+ // gone away.
PepperMediaDeviceManager* GetMediaDeviceManager();
// The client to notify when the stream is created. THIS MUST ONLY BE
@@ -106,8 +107,8 @@ class PepperPlatformAudioInput
scoped_refptr<base::MessageLoopProxy> main_message_loop_proxy_;
scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
- // THIS MUST ONLY BE ACCESSED ON THE MAIN THREAD.
- base::WeakPtr<RenderViewImpl> render_view_;
+ // The frame containing the Pepper widget.
+ int render_frame_id_;
// The unique ID to identify the opened device. THIS MUST ONLY BE ACCESSED ON
// THE MAIN THREAD.
diff --git a/content/renderer/pepper/pepper_platform_video_capture.cc b/content/renderer/pepper/pepper_platform_video_capture.cc
index 74eea87..f883d1b 100644
--- a/content/renderer/pepper/pepper_platform_video_capture.cc
+++ b/content/renderer/pepper/pepper_platform_video_capture.cc
@@ -10,19 +10,19 @@
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/pepper/pepper_media_device_manager.h"
#include "content/renderer/pepper/pepper_video_capture_host.h"
+#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
-#include "content/renderer/render_view_impl.h"
#include "media/base/bind_to_current_loop.h"
#include "url/gurl.h"
namespace content {
PepperPlatformVideoCapture::PepperPlatformVideoCapture(
- const base::WeakPtr<RenderViewImpl>& render_view,
+ int render_frame_id,
const std::string& device_id,
const GURL& document_url,
PepperVideoCaptureHost* handler)
- : render_view_(render_view),
+ : render_frame_id_(render_frame_id),
device_id_(device_id),
session_id_(0),
handler_(handler),
@@ -31,8 +31,9 @@ PepperPlatformVideoCapture::PepperPlatformVideoCapture(
weak_factory_(this) {
// We need to open the device and obtain the label and session ID before
// initializing.
- if (render_view_.get()) {
- pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (device_manager) {
+ pending_open_device_id_ = device_manager->OpenDevice(
PP_DEVICETYPE_DEV_VIDEOCAPTURE,
device_id,
document_url,
@@ -75,16 +76,18 @@ void PepperPlatformVideoCapture::DetachEventHandler() {
release_device_cb_.Run();
release_device_cb_.Reset();
}
- if (render_view_.get()) {
- if (!label_.empty()) {
- GetMediaDeviceManager()->CloseDevice(label_);
- label_.clear();
- }
- if (pending_open_device_) {
- GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
- pending_open_device_ = false;
- pending_open_device_id_ = -1;
- }
+ if (!label_.empty()) {
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (device_manager)
+ device_manager->CloseDevice(label_);
+ label_.clear();
+ }
+ if (pending_open_device_) {
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ if (device_manager)
+ device_manager->CancelOpenDevice(pending_open_device_id_);
+ pending_open_device_ = false;
+ pending_open_device_id_ = -1;
}
}
@@ -101,10 +104,11 @@ void PepperPlatformVideoCapture::OnDeviceOpened(int request_id,
pending_open_device_ = false;
pending_open_device_id_ = -1;
- succeeded = succeeded && render_view_.get();
+ PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
+ succeeded = succeeded && device_manager;
if (succeeded) {
label_ = label;
- session_id_ = GetMediaDeviceManager()->GetSessionID(
+ session_id_ = device_manager->GetSessionID(
PP_DEVICETYPE_DEV_VIDEOCAPTURE, label);
VideoCaptureImplManager* manager =
RenderThreadImpl::current()->video_capture_impl_manager();
@@ -145,7 +149,10 @@ void PepperPlatformVideoCapture::OnFrameReady(
}
PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() {
- return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
+ RenderFrameImpl* const render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id_);
+ return render_frame ?
+ PepperMediaDeviceManager::GetForRenderFrame(render_frame) : NULL;
}
} // namespace content
diff --git a/content/renderer/pepper/pepper_platform_video_capture.h b/content/renderer/pepper/pepper_platform_video_capture.h
index e31b8c7..2412f49 100644
--- a/content/renderer/pepper/pepper_platform_video_capture.h
+++ b/content/renderer/pepper/pepper_platform_video_capture.h
@@ -22,12 +22,11 @@ class GURL;
namespace content {
class PepperMediaDeviceManager;
class PepperVideoCaptureHost;
-class RenderViewImpl;
// This object must only be used on the thread it's constructed on.
class PepperPlatformVideoCapture {
public:
- PepperPlatformVideoCapture(const base::WeakPtr<RenderViewImpl>& render_view,
+ PepperPlatformVideoCapture(int render_frame_id,
const std::string& device_id,
const GURL& document_url,
PepperVideoCaptureHost* handler);
@@ -46,11 +45,13 @@ class PepperPlatformVideoCapture {
const media::VideoCaptureFormat& format,
const base::TimeTicks& estimated_capture_time);
+ // Can return NULL if the RenderFrame referenced by |render_frame_id_| has
+ // gone away.
PepperMediaDeviceManager* GetMediaDeviceManager();
- base::WeakPtr<RenderViewImpl> render_view_;
+ const int render_frame_id_;
+ const std::string device_id_;
- std::string device_id_;
std::string label_;
int session_id_;
base::Closure release_device_cb_;
diff --git a/content/renderer/pepper/pepper_video_capture_host.cc b/content/renderer/pepper/pepper_video_capture_host.cc
index 3981785..d28813b 100644
--- a/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/content/renderer/pepper/pepper_video_capture_host.cc
@@ -9,7 +9,7 @@
#include "content/renderer/pepper/pepper_platform_video_capture.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_view_impl.h"
+#include "content/renderer/render_frame_impl.h"
#include "media/base/limits.h"
#include "media/base/video_frame.h"
#include "ppapi/host/dispatch_host_message.h"
@@ -42,8 +42,8 @@ PepperVideoCaptureHost::PepperVideoCaptureHost(RendererPpapiHostImpl* host,
buffer_count_hint_(0),
status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
enumeration_helper_(this,
- PepperMediaDeviceManager::GetForRenderView(
- host->GetRenderViewForInstance(pp_instance())),
+ PepperMediaDeviceManager::GetForRenderFrame(
+ host->GetRenderFrameForInstance(pp_instance())),
PP_DEVICETYPE_DEV_VIDEOCAPTURE,
host->GetDocumentURL(instance)) {
}
@@ -261,11 +261,12 @@ int32_t PepperVideoCaptureHost::OnOpen(
if (!document_url.is_valid())
return PP_ERROR_FAILED;
- RenderViewImpl* render_view = static_cast<RenderViewImpl*>(
- renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()));
-
platform_video_capture_.reset(new PepperPlatformVideoCapture(
- render_view->AsWeakPtr(), device_id, document_url, this));
+ renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())->
+ GetRoutingID(),
+ device_id,
+ document_url,
+ this));
open_reply_context_ = context->MakeReplyMessageContext();
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index fd5708e..eb7370c 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -652,6 +652,13 @@ void RenderFrameImpl::OnImeConfirmComposition(
#endif // ENABLE_PLUGINS
+MediaStreamDispatcher* RenderFrameImpl::GetMediaStreamDispatcher() {
+ if (!web_user_media_client_)
+ InitializeUserMediaClient();
+ return web_user_media_client_ ?
+ web_user_media_client_->media_stream_dispatcher() : NULL;
+}
+
bool RenderFrameImpl::Send(IPC::Message* message) {
if (is_detaching_) {
delete message;
@@ -1569,6 +1576,7 @@ void RenderFrameImpl::frameFocused() {
void RenderFrameImpl::willClose(blink::WebFrame* frame) {
DCHECK(!frame_ || frame_ == frame);
+ FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameWillClose());
FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(),
FrameWillClose(frame));
}
@@ -2757,10 +2765,8 @@ void RenderFrameImpl::willStartUsingPeerConnectionHandler(
}
blink::WebUserMediaClient* RenderFrameImpl::userMediaClient() {
- // This can happen in tests, in which case it's OK to return NULL.
- if (!InitializeUserMediaClient())
- return NULL;
-
+ if (!web_user_media_client_)
+ InitializeUserMediaClient();
return web_user_media_client_;
}
@@ -3443,32 +3449,21 @@ void RenderFrameImpl::SyncSelectionIfRequired() {
GetRenderWidget()->UpdateSelectionBounds();
}
-bool RenderFrameImpl::InitializeUserMediaClient() {
- if (web_user_media_client_)
- return true;
-
+void RenderFrameImpl::InitializeUserMediaClient() {
if (!RenderThreadImpl::current()) // Will be NULL during unit tests.
- return false;
+ return;
#if defined(OS_ANDROID)
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebRTC))
- return false;
+ return;
#endif
#if defined(ENABLE_WEBRTC)
- if (!render_view_->media_stream_dispatcher_) {
- render_view_->media_stream_dispatcher_ =
- new MediaStreamDispatcher(render_view_.get());
- }
-
- MediaStreamImpl* media_stream_impl = new MediaStreamImpl(
- render_view_.get(),
- render_view_->media_stream_dispatcher_,
- RenderThreadImpl::current()->GetPeerConnectionDependencyFactory());
- web_user_media_client_ = media_stream_impl;
- return true;
-#else
- return false;
+ DCHECK(!web_user_media_client_);
+ web_user_media_client_ = new MediaStreamImpl(
+ this,
+ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(),
+ make_scoped_ptr(new MediaStreamDispatcher(this)).Pass());
#endif
}
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 0a7dda7..d1a3303 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -58,6 +58,8 @@ namespace content {
class ChildFrameCompositingHelper;
class GeolocationDispatcher;
+class MediaStreamDispatcher;
+class MediaStreamImpl;
class MediaStreamRendererFactory;
class MidiDispatcher;
class NotificationProvider;
@@ -201,6 +203,10 @@ class CONTENT_EXPORT RenderFrameImpl
bool keep_selection);
#endif // ENABLE_PLUGINS
+ // May return NULL in some cases, especially if userMediaClient() returns
+ // NULL.
+ MediaStreamDispatcher* GetMediaStreamDispatcher();
+
// IPC::Sender
virtual bool Send(IPC::Message* msg) OVERRIDE;
@@ -526,10 +532,10 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebURLError& error,
bool replace);
- // Initializes |web_user_media_client_|, returning true if successful. Returns
- // false if it wasn't possible to create a MediaStreamClient (e.g., WebRTC is
- // disabled) in which case |web_user_media_client_| is NULL.
- bool InitializeUserMediaClient();
+ // Initializes |web_user_media_client_|. If this fails, because it wasn't
+ // possible to create a MediaStreamClient (e.g., WebRTC is disabled), then
+ // |web_user_media_client_| will remain NULL.
+ void InitializeUserMediaClient();
blink::WebMediaPlayer* CreateWebMediaPlayerForMediaStream(
const blink::WebURL& url,
@@ -617,7 +623,8 @@ class CONTENT_EXPORT RenderFrameImpl
// Holds a reference to the service which provides desktop notifications.
NotificationProvider* notification_provider_;
- blink::WebUserMediaClient* web_user_media_client_;
+ // Destroyed via the RenderFrameObserver::OnDestruct() mechanism.
+ MediaStreamImpl* web_user_media_client_;
// MidiClient attached to this frame; lazily initialized.
MidiDispatcher* midi_dispatcher_;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 64f1fa3..95c11b4 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -87,7 +87,6 @@
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/internal_document_state_data.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
#include "content/renderer/memory_benchmarking_extension.h"
@@ -726,7 +725,6 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
#endif
has_scrolled_focused_editable_node_into_rect_(false),
speech_recognition_dispatcher_(NULL),
- media_stream_dispatcher_(NULL),
browser_plugin_manager_(NULL),
devtools_agent_(NULL),
accessibility_mode_(AccessibilityModeOff),
@@ -849,11 +847,6 @@ void RenderViewImpl::Initialize(RenderViewImplParams* params) {
OnSetRendererPrefs(params->renderer_prefs);
-#if defined(ENABLE_WEBRTC)
- if (!media_stream_dispatcher_)
- media_stream_dispatcher_ = new MediaStreamDispatcher(this);
-#endif
-
new MHTMLGenerator(this);
#if defined(OS_MACOSX)
new TextInputClientObserver(this);
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 0bc24bd..6efc709 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -133,7 +133,6 @@ class FaviconHelper;
class HistoryController;
class HistoryEntry;
class ImageResourceFetcher;
-class MediaStreamDispatcher;
class MouseLockDispatcher;
class NavigationState;
class PepperPluginInstanceImpl;
@@ -221,11 +220,6 @@ class CONTENT_EXPORT RenderViewImpl
RenderFrameImpl* main_render_frame() { return main_render_frame_.get(); }
- // TODO(jam): move to RenderFrameImpl
- MediaStreamDispatcher* media_stream_dispatcher() {
- return media_stream_dispatcher_;
- }
-
AccessibilityMode accessibility_mode() {
return accessibility_mode_;
}
@@ -1046,9 +1040,6 @@ class CONTENT_EXPORT RenderViewImpl
// initialized.
SpeechRecognitionDispatcher* speech_recognition_dispatcher_;
- // MediaStream dispatcher attached to this view; lazily initialized.
- MediaStreamDispatcher* media_stream_dispatcher_;
-
// BrowserPluginManager attached to this view; lazily initialized.
scoped_refptr<BrowserPluginManager> browser_plugin_manager_;
diff --git a/content/shell/renderer/test_runner/web_test_proxy.h b/content/shell/renderer/test_runner/web_test_proxy.h
index f4c7f70..a11ceb7 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.h
+++ b/content/shell/renderer/test_runner/web_test_proxy.h
@@ -347,9 +347,6 @@ class WebTestProxy : public Base, public WebTestProxyBase {
WebTestProxyBase::SetStatusText(text);
Base::setStatusText(text);
}
- virtual blink::WebUserMediaClient* userMediaClient() {
- return WebTestProxyBase::GetUserMediaClient();
- }
virtual void printPage(blink::WebLocalFrame* frame) {
WebTestProxyBase::PrintPage(frame);
}