1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/media/capture/web_contents_tracker.h"
#include "base/message_loop/message_loop_proxy.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
namespace content {
WebContentsTracker::WebContentsTracker(bool track_fullscreen_rwh)
: track_fullscreen_rwh_(track_fullscreen_rwh),
last_target_(NULL) {}
WebContentsTracker::~WebContentsTracker() {
DCHECK(!web_contents()) << "BUG: Still observering!";
}
void WebContentsTracker::Start(int render_process_id, int main_render_frame_id,
const ChangeCallback& callback) {
DCHECK(!message_loop_.get() || message_loop_->BelongsToCurrentThread());
message_loop_ = base::MessageLoopProxy::current();
DCHECK(message_loop_.get());
callback_ = callback;
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
StartObservingWebContents(render_process_id, main_render_frame_id);
} else {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&WebContentsTracker::StartObservingWebContents, this,
render_process_id, main_render_frame_id));
}
}
void WebContentsTracker::Stop() {
DCHECK(message_loop_->BelongsToCurrentThread());
callback_.Reset();
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
WebContentsObserver::Observe(NULL);
} else {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&WebContentsTracker::Observe, this,
static_cast<WebContents*>(NULL)));
}
}
RenderWidgetHost* WebContentsTracker::GetTargetRenderWidgetHost() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
WebContents* const wc = web_contents();
if (!wc)
return NULL;
RenderWidgetHost* rwh = NULL;
if (track_fullscreen_rwh_) {
RenderWidgetHostView* const view = wc->GetFullscreenRenderWidgetHostView();
if (view)
rwh = view->GetRenderWidgetHost();
}
if (!rwh) {
RenderFrameHostImpl* const rfh =
static_cast<RenderFrameHostImpl*>(wc->GetMainFrame());
if (rfh)
rwh = rfh->GetRenderWidgetHost();
}
return rwh;
}
void WebContentsTracker::OnPossibleTargetChange(bool force_callback_run) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderWidgetHost* const rwh = GetTargetRenderWidgetHost();
if (rwh == last_target_ && !force_callback_run)
return;
DVLOG(1) << "Will report target change from RenderWidgetHost@" << last_target_
<< " to RenderWidgetHost@" << rwh;
last_target_ = rwh;
if (message_loop_->BelongsToCurrentThread()) {
MaybeDoCallback(rwh);
} else {
message_loop_->PostTask(
FROM_HERE,
base::Bind(&WebContentsTracker::MaybeDoCallback, this, rwh));
}
}
void WebContentsTracker::MaybeDoCallback(RenderWidgetHost* rwh) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!callback_.is_null())
callback_.Run(rwh);
}
void WebContentsTracker::StartObservingWebContents(int render_process_id,
int main_render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Observe(WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
render_process_id, main_render_frame_id)));
DVLOG_IF(1, !web_contents())
<< "Could not find WebContents associated with main RenderFrameHost "
<< "referenced by render_process_id=" << render_process_id
<< ", routing_id=" << main_render_frame_id;
OnPossibleTargetChange(true);
}
void WebContentsTracker::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
OnPossibleTargetChange(false);
}
void WebContentsTracker::RenderFrameHostChanged(RenderFrameHost* old_host,
RenderFrameHost* new_host) {
OnPossibleTargetChange(false);
}
void WebContentsTracker::WebContentsDestroyed() {
Observe(NULL);
OnPossibleTargetChange(false);
}
void WebContentsTracker::DidShowFullscreenWidget(int routing_id) {
OnPossibleTargetChange(false);
}
void WebContentsTracker::DidDestroyFullscreenWidget(int routing_id) {
OnPossibleTargetChange(false);
}
} // namespace content
|