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