summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 08:04:32 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 08:04:32 +0000
commit977db4a4225870c35d80393d2312cb1931a4dba4 (patch)
tree468d02055ff28dbb207ccad8b19c3f170f01569c
parent6ee8a1e328f53fd64c014484e3fdd0f765c64996 (diff)
downloadchromium_src-977db4a4225870c35d80393d2312cb1931a4dba4.zip
chromium_src-977db4a4225870c35d80393d2312cb1931a4dba4.tar.gz
chromium_src-977db4a4225870c35d80393d2312cb1931a4dba4.tar.bz2
[Cross-Site Isolation] Migrate entire MediaStream verticals to be per-RenderFrame.
Much of this change is search-and-replace RenderView-->RenderFrame and render_view_id-->render_frame_id. However, the following significant changes have also been made, mainly to simplify/clarify/clean-up the same LOC that would have had to be changed anyway: 1. Desktop and Tab capture APIs now "register" a WebContents instance, rather than a RenderViewHost. This is a more-appropriate choice than registering a RenderFrameHost, and simplifies a lot of code. 2. Removed unnecessary "prepending" and "stripping" of the first part of the tab capture device ID in special circumstances. It is no longer necessary. 3. TabCaptureRegistry uses WebContentsObserver to detect all fullscreen changes, rather than the deprecated NotificationObserver scheme. 4. Fixes for buggy MediaStreamImpl tear-down: MediaStreamDispatcher is now explicitly owned by MediaStreamImpl, to ensure it is destroyed only after it is no longer needed. Also, weak pointers to MediaStreamImpl are invalidated before MSI data members are destroyed (it was observed during testing that outstanding callbacks were firing *after* the data members were destroyed). Testing: 1. All relevant content_unittests and browser_tests run. 2. Manually engaged tab capture and desktop capture using Google Cast extension and "Desktop Capture Example" (https://developer.chrome.com/extensions/samples) to test screen picker UI. 3. Ran WebRTC demo: http://apprtc.appspot.com 4. Confirmed Flash webcam and microphone input. 5. Checked tab capture/recording/audio indicators. 6. Confirmed HTML5 and Flash fullscreen-within-tab functionality during tab capture. BUG=304341,323223,320200,163100,338445 TEST=See "Testing" above. TBR=kenrb@chromium.org Review URL: https://codereview.chromium.org/364123002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283702 0039d316-1c4b-4281-b951-d872f2087c98
-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);
}