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/thread_task_runner_handle.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(!task_runner_
.get() || task_runner_
->BelongsToCurrentThread());
29 task_runner_
= base::ThreadTaskRunnerHandle::Get();
30 DCHECK(task_runner_
.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(task_runner_
->BelongsToCurrentThread());
47 resize_callback_
.Reset();
49 if (BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
50 WebContentsObserver::Observe(NULL
);
52 BrowserThread::PostTask(
53 BrowserThread::UI
, FROM_HERE
,
54 base::Bind(&WebContentsTracker::Observe
, this,
55 static_cast<WebContents
*>(NULL
)));
59 RenderWidgetHost
* WebContentsTracker::GetTargetRenderWidgetHost() const {
60 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
62 WebContents
* const wc
= web_contents();
66 RenderWidgetHost
* rwh
= NULL
;
67 if (track_fullscreen_rwh_
) {
68 RenderWidgetHostView
* const view
= wc
->GetFullscreenRenderWidgetHostView();
70 rwh
= view
->GetRenderWidgetHost();
73 RenderFrameHostImpl
* const rfh
=
74 static_cast<RenderFrameHostImpl
*>(wc
->GetMainFrame());
76 rwh
= rfh
->GetRenderWidgetHost();
82 void WebContentsTracker::SetResizeChangeCallback(
83 const base::Closure
& callback
) {
84 DCHECK(!task_runner_
.get() || task_runner_
->BelongsToCurrentThread());
85 resize_callback_
= callback
;
88 void WebContentsTracker::OnPossibleTargetChange(bool force_callback_run
) {
89 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
91 RenderWidgetHost
* const rwh
= GetTargetRenderWidgetHost();
92 if (rwh
== last_target_
&& !force_callback_run
)
94 DVLOG(1) << "Will report target change from RenderWidgetHost@" << last_target_
95 << " to RenderWidgetHost@" << rwh
;
98 if (task_runner_
->BelongsToCurrentThread()) {
99 MaybeDoCallback(rwh
!= nullptr);
103 task_runner_
->PostTask(
105 base::Bind(&WebContentsTracker::MaybeDoCallback
, this, rwh
!= nullptr));
108 void WebContentsTracker::MaybeDoCallback(bool was_still_tracking
) {
109 DCHECK(task_runner_
->BelongsToCurrentThread());
111 if (!callback_
.is_null())
112 callback_
.Run(was_still_tracking
);
113 if (was_still_tracking
)
114 MaybeDoResizeCallback();
117 void WebContentsTracker::MaybeDoResizeCallback() {
118 DCHECK(task_runner_
->BelongsToCurrentThread());
120 if (!resize_callback_
.is_null())
121 resize_callback_
.Run();
124 void WebContentsTracker::StartObservingWebContents(int render_process_id
,
125 int main_render_frame_id
) {
126 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
128 Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
129 render_process_id
, main_render_frame_id
)));
130 DVLOG_IF(1, !web_contents())
131 << "Could not find WebContents associated with main RenderFrameHost "
132 << "referenced by render_process_id=" << render_process_id
133 << ", routing_id=" << main_render_frame_id
;
135 OnPossibleTargetChange(true);
138 void WebContentsTracker::RenderFrameDeleted(
139 RenderFrameHost
* render_frame_host
) {
140 OnPossibleTargetChange(false);
143 void WebContentsTracker::RenderFrameHostChanged(RenderFrameHost
* old_host
,
144 RenderFrameHost
* new_host
) {
145 OnPossibleTargetChange(false);
148 void WebContentsTracker::MainFrameWasResized(bool width_changed
) {
149 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
151 if (task_runner_
->BelongsToCurrentThread()) {
152 MaybeDoResizeCallback();
156 task_runner_
->PostTask(
158 base::Bind(&WebContentsTracker::MaybeDoResizeCallback
, this));
161 void WebContentsTracker::WebContentsDestroyed() {
163 OnPossibleTargetChange(false);
166 void WebContentsTracker::DidShowFullscreenWidget(int routing_id
) {
167 OnPossibleTargetChange(false);
170 void WebContentsTracker::DidDestroyFullscreenWidget(int routing_id
) {
171 OnPossibleTargetChange(false);
174 } // namespace content