Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / media / capture / web_contents_tracker.cc
blob6810ac097aac4b44ae976d439c1112d2ea611436
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"
15 namespace content {
17 WebContentsTracker::WebContentsTracker(bool track_fullscreen_rwh)
18 : track_fullscreen_rwh_(track_fullscreen_rwh),
19 last_target_(NULL) {}
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());
31 callback_ = callback;
33 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
34 StartObservingWebContents(render_process_id, main_render_frame_id);
35 } else {
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());
46 callback_.Reset();
48 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
49 WebContentsObserver::Observe(NULL);
50 } else {
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();
62 if (!wc)
63 return NULL;
65 RenderWidgetHost* rwh = NULL;
66 if (track_fullscreen_rwh_) {
67 RenderWidgetHostView* const view = wc->GetFullscreenRenderWidgetHostView();
68 if (view)
69 rwh = view->GetRenderWidgetHost();
71 if (!rwh) {
72 RenderFrameHostImpl* const rfh =
73 static_cast<RenderFrameHostImpl*>(wc->GetMainFrame());
74 if (rfh)
75 rwh = rfh->GetRenderWidgetHost();
78 return rwh;
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)
86 return;
87 DVLOG(1) << "Will report target change from RenderWidgetHost@" << last_target_
88 << " to RenderWidgetHost@" << rwh;
89 last_target_ = rwh;
91 if (message_loop_->BelongsToCurrentThread()) {
92 MaybeDoCallback(rwh);
93 } else {
94 message_loop_->PostTask(
95 FROM_HERE,
96 base::Bind(&WebContentsTracker::MaybeDoCallback, this, rwh));
100 void WebContentsTracker::MaybeDoCallback(RenderWidgetHost* rwh) {
101 DCHECK(message_loop_->BelongsToCurrentThread());
103 if (!callback_.is_null())
104 callback_.Run(rwh);
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() {
132 Observe(NULL);
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