1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/media/capture/web_contents_tracker.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "content/browser/frame_host/render_frame_host_impl.h"
9 #include "content/browser/renderer_host/render_widget_host_impl.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/render_widget_host_view.h"
13 #include "content/public/browser/web_contents.h"
17 WebContentsTracker::WebContentsTracker(bool track_fullscreen_rwh
)
18 : track_fullscreen_rwh_(track_fullscreen_rwh
),
21 WebContentsTracker::~WebContentsTracker() {
22 DCHECK(!web_contents()) << "BUG: Still observering!";
25 void WebContentsTracker::Start(int render_process_id
, int main_render_frame_id
,
26 const ChangeCallback
& callback
) {
27 DCHECK(!message_loop_
.get() || message_loop_
->BelongsToCurrentThread());
29 message_loop_
= base::MessageLoopProxy::current();
30 DCHECK(message_loop_
.get());
33 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
34 StartObservingWebContents(render_process_id
, main_render_frame_id
);
36 BrowserThread::PostTask(
37 BrowserThread::UI
, FROM_HERE
,
38 base::Bind(&WebContentsTracker::StartObservingWebContents
, this,
39 render_process_id
, main_render_frame_id
));
43 void WebContentsTracker::Stop() {
44 DCHECK(message_loop_
->BelongsToCurrentThread());
48 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
49 WebContentsObserver::Observe(NULL
);
51 BrowserThread::PostTask(
52 BrowserThread::UI
, FROM_HERE
,
53 base::Bind(&WebContentsTracker::Observe
, this,
54 static_cast<WebContents
*>(NULL
)));
58 RenderWidgetHost
* WebContentsTracker::GetTargetRenderWidgetHost() const {
59 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
61 WebContents
* const wc
= web_contents();
65 RenderWidgetHost
* rwh
= NULL
;
66 if (track_fullscreen_rwh_
) {
67 RenderWidgetHostView
* const view
= wc
->GetFullscreenRenderWidgetHostView();
69 rwh
= view
->GetRenderWidgetHost();
72 RenderFrameHostImpl
* const rfh
=
73 static_cast<RenderFrameHostImpl
*>(wc
->GetMainFrame());
75 rwh
= rfh
->GetRenderWidgetHost();
81 void WebContentsTracker::OnPossibleTargetChange(bool force_callback_run
) {
82 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
84 RenderWidgetHost
* const rwh
= GetTargetRenderWidgetHost();
85 if (rwh
== last_target_
&& !force_callback_run
)
87 DVLOG(1) << "Will report target change from RenderWidgetHost@" << last_target_
88 << " to RenderWidgetHost@" << rwh
;
91 if (message_loop_
->BelongsToCurrentThread()) {
94 message_loop_
->PostTask(
96 base::Bind(&WebContentsTracker::MaybeDoCallback
, this, rwh
));
100 void WebContentsTracker::MaybeDoCallback(RenderWidgetHost
* rwh
) {
101 DCHECK(message_loop_
->BelongsToCurrentThread());
103 if (!callback_
.is_null())
107 void WebContentsTracker::StartObservingWebContents(int render_process_id
,
108 int main_render_frame_id
) {
109 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
111 Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
112 render_process_id
, main_render_frame_id
)));
113 DVLOG_IF(1, !web_contents())
114 << "Could not find WebContents associated with main RenderFrameHost "
115 << "referenced by render_process_id=" << render_process_id
116 << ", routing_id=" << main_render_frame_id
;
118 OnPossibleTargetChange(true);
121 void WebContentsTracker::RenderFrameDeleted(
122 RenderFrameHost
* render_frame_host
) {
123 OnPossibleTargetChange(false);
126 void WebContentsTracker::RenderFrameHostChanged(RenderFrameHost
* old_host
,
127 RenderFrameHost
* new_host
) {
128 OnPossibleTargetChange(false);
131 void WebContentsTracker::WebContentsDestroyed() {
133 OnPossibleTargetChange(false);
136 void WebContentsTracker::DidShowFullscreenWidget(int routing_id
) {
137 OnPossibleTargetChange(false);
140 void WebContentsTracker::DidDestroyFullscreenWidget(int routing_id
) {
141 OnPossibleTargetChange(false);
144 } // namespace content