// Copyright 2019 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 "weblayer/renderer/content_renderer_client_impl.h" #include "base/feature_list.h" #include "build/build_config.h" #include "components/autofill/content/renderer/autofill_agent.h" #include "components/autofill/content/renderer/password_autofill_agent.h" #include "components/content_capture/common/content_capture_features.h" #include "components/content_capture/renderer/content_capture_sender.h" #include "components/content_settings/renderer/content_settings_agent_impl.h" #include "components/error_page/common/error.h" #include "components/grit/components_scaled_resources.h" #include "components/js_injection/renderer/js_communication.h" #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h" #include "components/no_state_prefetch/renderer/no_state_prefetch_client.h" #include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h" #include "components/no_state_prefetch/renderer/no_state_prefetch_utils.h" #include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h" #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h" #include "components/subresource_filter/content/renderer/ad_resource_tracker.h" #include "components/subresource_filter/content/renderer/subresource_filter_agent.h" #include "components/subresource_filter/content/renderer/unverified_ruleset_dealer.h" #include "components/subresource_filter/core/common/common_features.h" #include "components/webapps/renderer/web_page_metadata_agent.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_runtime_features.h" #include "ui/base/resource/resource_bundle.h" #include "weblayer/common/features.h" #include "weblayer/renderer/error_page_helper.h" #include "weblayer/renderer/url_loader_throttle_provider.h" #include "weblayer/renderer/weblayer_render_frame_observer.h" #include "weblayer/renderer/weblayer_render_thread_observer.h" #if BUILDFLAG(IS_ANDROID) #include "components/android_system_error_page/error_page_populator.h" #include "components/cdm/renderer/android_key_systems.h" #include "components/spellcheck/renderer/spellcheck.h" // nogncheck #include "components/spellcheck/renderer/spellcheck_provider.h" // nogncheck #include "content/public/common/url_constants.h" #include "content/public/renderer/render_thread.h" #include "services/service_manager/public/cpp/local_interface_provider.h" #include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_security_policy.h" #endif namespace weblayer { namespace { #if BUILDFLAG(IS_ANDROID) class SpellcheckInterfaceProvider : public service_manager::LocalInterfaceProvider { public: SpellcheckInterfaceProvider() = default; SpellcheckInterfaceProvider(const SpellcheckInterfaceProvider&) = delete; SpellcheckInterfaceProvider& operator=(const SpellcheckInterfaceProvider&) = delete; ~SpellcheckInterfaceProvider() override = default; // service_manager::LocalInterfaceProvider: void GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override { // A dirty hack to make SpellCheckHost requests work on WebLayer. // TODO(crbug.com/806394): Use a WebView-specific service for SpellCheckHost // and SafeBrowsing, instead of |content_browser|. content::RenderThread::Get()->BindHostReceiver(mojo::GenericPendingReceiver( interface_name, std::move(interface_pipe))); } }; #endif // BUILDFLAG(IS_ANDROID) } // namespace ContentRendererClientImpl::ContentRendererClientImpl() = default; ContentRendererClientImpl::~ContentRendererClientImpl() = default; void ContentRendererClientImpl::RenderThreadStarted() { #if BUILDFLAG(IS_ANDROID) if (!spellcheck_) { local_interface_provider_ = std::make_unique(); spellcheck_ = std::make_unique(local_interface_provider_.get()); } blink::WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer( blink::WebString::FromUTF8(content::kAndroidAppScheme)); #endif content::RenderThread* thread = content::RenderThread::Get(); weblayer_observer_ = std::make_unique(); thread->AddObserver(weblayer_observer_.get()); browser_interface_broker_ = blink::Platform::Current()->GetBrowserInterfaceBroker(); subresource_filter_ruleset_dealer_ = std::make_unique(); thread->AddObserver(subresource_filter_ruleset_dealer_.get()); } void ContentRendererClientImpl::RenderFrameCreated( content::RenderFrame* render_frame) { auto* render_frame_observer = new WebLayerRenderFrameObserver(render_frame); new prerender::PrerenderRenderFrameObserver(render_frame); ErrorPageHelper::Create(render_frame); autofill::PasswordAutofillAgent* password_autofill_agent = new autofill::PasswordAutofillAgent( render_frame, render_frame_observer->associated_interfaces()); new autofill::AutofillAgent(render_frame, password_autofill_agent, nullptr, nullptr, render_frame_observer->associated_interfaces()); auto* agent = new content_settings::ContentSettingsAgentImpl( render_frame, false /* should_whitelist */, std::make_unique()); if (weblayer_observer_) { if (weblayer_observer_->content_settings_manager()) { mojo::Remote manager; weblayer_observer_->content_settings_manager()->Clone( manager.BindNewPipeAndPassReceiver()); agent->SetContentSettingsManager(std::move(manager)); } } auto* metrics_render_frame_observer = new page_load_metrics::MetricsRenderFrameObserver(render_frame); auto ad_resource_tracker = std::make_unique(); metrics_render_frame_observer->SetAdResourceTracker( ad_resource_tracker.get()); auto* subresource_filter_agent = new subresource_filter::SubresourceFilterAgent( render_frame, subresource_filter_ruleset_dealer_.get(), std::move(ad_resource_tracker)); subresource_filter_agent->Initialize(); #if BUILDFLAG(IS_ANDROID) // |SpellCheckProvider| manages its own lifetime (and destroys itself when the // RenderFrame is destroyed). new SpellCheckProvider(render_frame, spellcheck_.get(), local_interface_provider_.get()); #endif new js_injection::JsCommunication(render_frame); if (render_frame->IsMainFrame()) new webapps::WebPageMetadataAgent(render_frame); if (content_capture::features::IsContentCaptureEnabledInWebLayer()) { new content_capture::ContentCaptureSender( render_frame, render_frame_observer->associated_interfaces()); } if (!render_frame->IsMainFrame()) { auto* main_frame_no_state_prefetch_helper = prerender::NoStatePrefetchHelper::Get( render_frame->GetMainRenderFrame()); if (main_frame_no_state_prefetch_helper) { // Avoid any race conditions from having the browser tell subframes that // they're no-state prefetching. new prerender::NoStatePrefetchHelper( render_frame, main_frame_no_state_prefetch_helper->histogram_prefix()); } } } void ContentRendererClientImpl::WebViewCreated(blink::WebView* web_view, bool was_created_by_renderer) { new prerender::NoStatePrefetchClient(web_view); } SkBitmap* ContentRendererClientImpl::GetSadPluginBitmap() { return const_cast(ui::ResourceBundle::GetSharedInstance() .GetImageNamed(IDR_SAD_PLUGIN) .ToSkBitmap()); } SkBitmap* ContentRendererClientImpl::GetSadWebViewBitmap() { return const_cast(ui::ResourceBundle::GetSharedInstance() .GetImageNamed(IDR_SAD_WEBVIEW) .ToSkBitmap()); } void ContentRendererClientImpl::PrepareErrorPage( content::RenderFrame* render_frame, const blink::WebURLError& error, const std::string& http_method, content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info, std::string* error_html) { auto* error_page_helper = ErrorPageHelper::GetForFrame(render_frame); if (error_page_helper) error_page_helper->PrepareErrorPage(); #if BUILDFLAG(IS_ANDROID) // This does nothing if |error_html| is non-null (which happens if the // embedder injects an error page). android_system_error_page::PopulateErrorPageHtml(error, error_html); #endif } std::unique_ptr ContentRendererClientImpl::CreateURLLoaderThrottleProvider( blink::URLLoaderThrottleProviderType provider_type) { return std::make_unique( browser_interface_broker_.get(), provider_type); } void ContentRendererClientImpl::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { media::KeySystemPropertiesVector key_systems; #if BUILDFLAG(IS_ANDROID) #if BUILDFLAG(ENABLE_WIDEVINE) cdm::AddAndroidWidevine(&key_systems); #endif // BUILDFLAG(ENABLE_WIDEVINE) cdm::AddAndroidPlatformKeySystems(&key_systems); #endif // BUILDFLAG(IS_ANDROID) std::move(cb).Run(std::move(key_systems)); } void ContentRendererClientImpl:: SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true); #if BUILDFLAG(IS_ANDROID) // Web Share is experimental by default, and explicitly enabled on Android // (for both Chrome and WebLayer). blink::WebRuntimeFeatures::EnableWebShare(true); #endif if (base::FeatureList::IsEnabled(subresource_filter::kAdTagging)) { blink::WebRuntimeFeatures::EnableAdTagging(true); } } bool ContentRendererClientImpl::IsPrefetchOnly( content::RenderFrame* render_frame) { return prerender::NoStatePrefetchHelper::IsPrefetching(render_frame); } bool ContentRendererClientImpl::DeferMediaLoad( content::RenderFrame* render_frame, bool has_played_media_before, base::OnceClosure closure) { return prerender::DeferMediaLoad(render_frame, has_played_media_before, std::move(closure)); } } // namespace weblayer