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
content / browser / browser_plugin / browser_plugin_guest.cc [blame]
// 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