1 // Copyright 2019 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.
4
5 #include "weblayer/renderer/content_renderer_client_impl.h"
6
7 #include "base/feature_list.h"
8 #include "build/build_config.h"
9 #include "components/autofill/content/renderer/autofill_agent.h"
10 #include "components/autofill/content/renderer/password_autofill_agent.h"
11 #include "components/content_settings/renderer/content_settings_agent_impl.h"
12 #include "components/error_page/common/error.h"
13 #include "components/grit/components_scaled_resources.h"
14 #include "components/js_injection/renderer/js_communication.h"
15 #include "components/no_state_prefetch/common/prerender_types.mojom.h"
16 #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
17 #include "components/no_state_prefetch/renderer/prerender_helper.h"
18 #include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h"
19 #include "components/no_state_prefetch/renderer/prerender_utils.h"
20 #include "components/no_state_prefetch/renderer/prerenderer_client.h"
21 #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
22 #include "content/public/renderer/render_frame.h"
23 #include "content/public/renderer/render_thread.h"
24 #include "content/public/renderer/render_view.h"
25 #include "third_party/blink/public/platform/platform.h"
26 #include "ui/base/resource/resource_bundle.h"
27 #include "weblayer/common/features.h"
28 #include "weblayer/renderer/error_page_helper.h"
29 #include "weblayer/renderer/url_loader_throttle_provider.h"
30 #include "weblayer/renderer/weblayer_render_frame_observer.h"
31 #include "weblayer/renderer/weblayer_render_thread_observer.h"
32
33 #if defined(OS_ANDROID)
34 #include "components/android_system_error_page/error_page_populator.h"
35 #include "components/cdm/renderer/android_key_systems.h"
36 #include "components/spellcheck/renderer/spellcheck.h" // nogncheck
37 #include "components/spellcheck/renderer/spellcheck_provider.h" // nogncheck
38 #include "content/public/renderer/render_thread.h"
39 #include "services/service_manager/public/cpp/local_interface_provider.h"
40 #include "third_party/blink/public/platform/web_runtime_features.h"
41 #include "third_party/blink/public/platform/web_string.h"
42 #include "third_party/blink/public/web/web_security_policy.h"
43 #endif
44
45 namespace weblayer {
46
47 namespace {
48
49 #if defined(OS_ANDROID)
50 class SpellcheckInterfaceProvider
51 : public service_manager::LocalInterfaceProvider {
52 public:
53 SpellcheckInterfaceProvider() = default;
54 ~SpellcheckInterfaceProvider() override = default;
55
56 // service_manager::LocalInterfaceProvider:
GetInterface(const std::string & interface_name,mojo::ScopedMessagePipeHandle interface_pipe)57 void GetInterface(const std::string& interface_name,
58 mojo::ScopedMessagePipeHandle interface_pipe) override {
59 // A dirty hack to make SpellCheckHost requests work on WebLayer.
60 // TODO(crbug.com/806394): Use a WebView-specific service for SpellCheckHost
61 // and SafeBrowsing, instead of |content_browser|.
62 content::RenderThread::Get()->BindHostReceiver(mojo::GenericPendingReceiver(
63 interface_name, std::move(interface_pipe)));
64 }
65
66 private:
67 DISALLOW_COPY_AND_ASSIGN(SpellcheckInterfaceProvider);
68 };
69 #endif // defined(OS_ANDROID)
70
71 } // namespace
72
73 ContentRendererClientImpl::ContentRendererClientImpl() = default;
74 ContentRendererClientImpl::~ContentRendererClientImpl() = default;
75
RenderThreadStarted()76 void ContentRendererClientImpl::RenderThreadStarted() {
77 #if defined(OS_ANDROID)
78 if (!spellcheck_) {
79 local_interface_provider_ = std::make_unique<SpellcheckInterfaceProvider>();
80 spellcheck_ = std::make_unique<SpellCheck>(local_interface_provider_.get());
81 }
82 // TODO(sky): refactor. This comes from chrome/common/url_constants.cc's
83 // kAndroidAppScheme.
84 blink::WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer(
85 blink::WebString::FromUTF8("android-app"));
86 #endif
87
88 content::RenderThread* thread = content::RenderThread::Get();
89 weblayer_observer_ = std::make_unique<WebLayerRenderThreadObserver>();
90 thread->AddObserver(weblayer_observer_.get());
91
92 browser_interface_broker_ =
93 blink::Platform::Current()->GetBrowserInterfaceBroker();
94 }
95
RenderFrameCreated(content::RenderFrame * render_frame)96 void ContentRendererClientImpl::RenderFrameCreated(
97 content::RenderFrame* render_frame) {
98 auto* render_frame_observer = new WebLayerRenderFrameObserver(render_frame);
99 new prerender::PrerenderRenderFrameObserver(render_frame);
100
101 ErrorPageHelper::Create(render_frame);
102
103 autofill::PasswordAutofillAgent* password_autofill_agent =
104 new autofill::PasswordAutofillAgent(
105 render_frame, render_frame_observer->associated_interfaces());
106 new autofill::AutofillAgent(render_frame, password_autofill_agent, nullptr,
107 nullptr,
108 render_frame_observer->associated_interfaces());
109 auto* agent = new content_settings::ContentSettingsAgentImpl(
110 render_frame, false /* should_whitelist */,
111 std::make_unique<content_settings::ContentSettingsAgentImpl::Delegate>());
112 if (weblayer_observer_)
113 agent->SetContentSettingRules(weblayer_observer_->content_setting_rules());
114
115 new page_load_metrics::MetricsRenderFrameObserver(render_frame);
116
117 #if defined(OS_ANDROID)
118 // |SpellCheckProvider| manages its own lifetime (and destroys itself when the
119 // RenderFrame is destroyed).
120 new SpellCheckProvider(render_frame, spellcheck_.get(),
121 local_interface_provider_.get());
122 #endif
123 new js_injection::JsCommunication(render_frame);
124
125 if (!render_frame->IsMainFrame()) {
126 auto* prerender_helper = prerender::PrerenderHelper::Get(
127 render_frame->GetRenderView()->GetMainRenderFrame());
128 if (prerender_helper) {
129 // Avoid any race conditions from having the browser tell subframes that
130 // they're prerendering.
131 new prerender::PrerenderHelper(render_frame,
132 prerender_helper->prerender_mode(),
133 prerender_helper->histogram_prefix());
134 }
135 }
136 }
137
RenderViewCreated(content::RenderView * render_view)138 void ContentRendererClientImpl::RenderViewCreated(
139 content::RenderView* render_view) {
140 new prerender::PrerendererClient(render_view);
141 }
142
GetSadPluginBitmap()143 SkBitmap* ContentRendererClientImpl::GetSadPluginBitmap() {
144 return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance()
145 .GetImageNamed(IDR_SAD_PLUGIN)
146 .ToSkBitmap());
147 }
148
GetSadWebViewBitmap()149 SkBitmap* ContentRendererClientImpl::GetSadWebViewBitmap() {
150 return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance()
151 .GetImageNamed(IDR_SAD_WEBVIEW)
152 .ToSkBitmap());
153 }
154
PrepareErrorPage(content::RenderFrame * render_frame,const blink::WebURLError & error,const std::string & http_method,std::string * error_html)155 void ContentRendererClientImpl::PrepareErrorPage(
156 content::RenderFrame* render_frame,
157 const blink::WebURLError& error,
158 const std::string& http_method,
159 std::string* error_html) {
160 auto* error_page_helper = ErrorPageHelper::GetForFrame(render_frame);
161 if (error_page_helper)
162 error_page_helper->PrepareErrorPage();
163
164 #if defined(OS_ANDROID)
165 // This does nothing if |error_html| is non-null (which happens if the
166 // embedder injects an error page).
167 android_system_error_page::PopulateErrorPageHtml(error, error_html);
168 #endif
169 }
170
171 std::unique_ptr<content::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(content::URLLoaderThrottleProviderType provider_type)172 ContentRendererClientImpl::CreateURLLoaderThrottleProvider(
173 content::URLLoaderThrottleProviderType provider_type) {
174 return std::make_unique<URLLoaderThrottleProvider>(
175 browser_interface_broker_.get(), provider_type);
176 }
177
AddSupportedKeySystems(std::vector<std::unique_ptr<::media::KeySystemProperties>> * key_systems)178 void ContentRendererClientImpl::AddSupportedKeySystems(
179 std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
180 #if defined(OS_ANDROID)
181 cdm::AddAndroidWidevine(key_systems);
182 cdm::AddAndroidPlatformKeySystems(key_systems);
183 #endif
184 }
185
186 void ContentRendererClientImpl::
SetRuntimeFeaturesDefaultsBeforeBlinkInitialization()187 SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
188 #if defined(OS_ANDROID)
189 // Web Share is experimental by default, and explicitly enabled on Android
190 // (for both Chrome and WebLayer).
191 blink::WebRuntimeFeatures::EnableWebShare(true);
192 #endif
193 }
194
IsPrefetchOnly(content::RenderFrame * render_frame,const blink::WebURLRequest & request)195 bool ContentRendererClientImpl::IsPrefetchOnly(
196 content::RenderFrame* render_frame,
197 const blink::WebURLRequest& request) {
198 return prerender::PrerenderHelper::GetPrerenderMode(render_frame) ==
199 prerender::mojom::PrerenderMode::kPrefetchOnly;
200 }
201
DeferMediaLoad(content::RenderFrame * render_frame,bool has_played_media_before,base::OnceClosure closure)202 bool ContentRendererClientImpl::DeferMediaLoad(
203 content::RenderFrame* render_frame,
204 bool has_played_media_before,
205 base::OnceClosure closure) {
206 return prerender::DeferMediaLoad(render_frame, has_played_media_before,
207 std::move(closure));
208 }
209
210 } // namespace weblayer
211