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 145 146 147 148 149
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include <stddef.h>
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/metrics/user_metrics.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
namespace content {
BrowserPluginGuest::BrowserPluginGuest(WebContentsImpl* web_contents,
BrowserPluginGuestDelegate* delegate)
: WebContentsObserver(web_contents),
delegate_(delegate->GetGuestDelegateWeakPtr()) {
CHECK(web_contents);
CHECK(delegate_);
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create"));
}
void BrowserPluginGuest::Init() {
WebContentsImpl* owner_web_contents = static_cast<WebContentsImpl*>(
delegate_->GetOwnerWebContents());
owner_web_contents->CreateBrowserPluginEmbedderIfNecessary();
InitInternal(owner_web_contents);
}
std::unique_ptr<WebContentsImpl> BrowserPluginGuest::CreateNewGuestWindow(
const WebContents::CreateParams& params) {
std::unique_ptr<WebContents> new_contents =
delegate_->CreateNewGuestWindow(params);
DCHECK(new_contents);
return base::WrapUnique(
static_cast<WebContentsImpl*>(new_contents.release()));
}
void BrowserPluginGuest::InitInternal(WebContentsImpl* owner_web_contents) {
RenderWidgetHostImpl* rwhi =
GetWebContents()->GetPrimaryMainFrame()->GetRenderWidgetHost();
DCHECK(rwhi);
// The initial state will not be focused but the plugin may be active so
// set that appropriately.
rwhi->GetWidgetInputHandler()->SetFocus(
rwhi->is_active() ? blink::mojom::FocusState::kNotFocusedAndActive
: blink::mojom::FocusState::kNotFocusedAndNotActive);
blink::RendererPreferences* renderer_prefs =
GetWebContents()->GetMutableRendererPrefs();
blink::UserAgentOverride guest_user_agent_override =
renderer_prefs->user_agent_override;
// Copy renderer preferences (and nothing else) from the embedder's
// WebContents to the guest.
//
// For GTK and Aura this is necessary to get proper renderer configuration
// values for caret blinking interval, colors related to selection and
// focus.
*renderer_prefs = *owner_web_contents->GetMutableRendererPrefs();
renderer_prefs->user_agent_override = std::move(guest_user_agent_override);
// Navigation is disabled in Chrome Apps. We want to make sure guest-initiated
// navigations still continue to function inside the app.
renderer_prefs->browser_handles_all_top_level_requests = false;
// Also disable drag/drop navigations.
renderer_prefs->can_accept_load_drops = false;
}
BrowserPluginGuest::~BrowserPluginGuest() = default;
// static
void BrowserPluginGuest::CreateInWebContents(
WebContentsImpl* web_contents,
BrowserPluginGuestDelegate* delegate) {
auto guest = base::WrapUnique(new BrowserPluginGuest(web_contents, delegate));
web_contents->SetBrowserPluginGuest(std::move(guest));
}
WebContentsImpl* BrowserPluginGuest::GetWebContents() const {
return static_cast<WebContentsImpl*>(web_contents());
}
RenderFrameHostImpl* BrowserPluginGuest::GetProspectiveOuterDocument() {
if (!delegate_) {
// The guest delegate may only be null during some destruction scenarios.
CHECK(!web_contents() || web_contents()->IsBeingDestroyed());
return nullptr;
}
return static_cast<RenderFrameHostImpl*>(
delegate_->GetProspectiveOuterDocument());
}
void BrowserPluginGuest::DidStartNavigation(
NavigationHandle* navigation_handle) {
// Originally added to suppress the error page when a navigation is blocked
// using the webrequest API in a <webview> guest: https://crbug.com/284741.
//
// TODO(crbug.com/40148437): net::ERR_BLOCKED_BY_CLIENT is used for
// many other errors. Figure out what suppression policy is desirable here.
//
// TODO(mcnee): Investigate moving this out to WebViewGuest.
NavigationRequest::From(navigation_handle)
->SetSilentlyIgnoreBlockedByClient();
}
void BrowserPluginGuest::DidFinishNavigation(
NavigationHandle* navigation_handle) {
if (navigation_handle->HasCommitted())
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.DidNavigate"));
}
void BrowserPluginGuest::PrimaryMainFrameRenderProcessGone(
base::TerminationStatus status) {
switch (status) {
#if BUILDFLAG(IS_CHROMEOS)
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
#endif
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Killed"));
break;
case base::TERMINATION_STATUS_PROCESS_CRASHED:
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed"));
break;
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
break;
case base::TERMINATION_STATUS_LAUNCH_FAILED:
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.LaunchFailed"));
break;
default:
break;
}
}
} // namespace content
|