#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/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"
#include "components/spellcheck/renderer/spellcheck_provider.h"
#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;
void GetInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override {
content::RenderThread::Get()->BindHostReceiver(mojo::GenericPendingReceiver(
interface_name, std::move(interface_pipe)));
}
};
#endif
}
ContentRendererClientImpl::ContentRendererClientImpl() = default;
ContentRendererClientImpl::~ContentRendererClientImpl() = default;
void ContentRendererClientImpl::RenderThreadStarted() {
#if BUILDFLAG(IS_ANDROID)
if (!spellcheck_) {
local_interface_provider_ = std::make_unique<SpellcheckInterfaceProvider>();
spellcheck_ = std::make_unique<SpellCheck>(local_interface_provider_.get());
}
blink::WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer(
blink::WebString::FromUTF8(content::kAndroidAppScheme));
#endif
content::RenderThread* thread = content::RenderThread::Get();
weblayer_observer_ = std::make_unique<WebLayerRenderThreadObserver>();
thread->AddObserver(weblayer_observer_.get());
browser_interface_broker_ =
blink::Platform::Current()->GetBrowserInterfaceBroker();
subresource_filter_ruleset_dealer_ =
std::make_unique<subresource_filter::UnverifiedRulesetDealer>();
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,
render_frame_observer->associated_interfaces());
auto* agent = new content_settings::ContentSettingsAgentImpl(
render_frame, false ,
std::make_unique<content_settings::ContentSettingsAgentImpl::Delegate>());
if (weblayer_observer_) {
if (weblayer_observer_->content_settings_manager()) {
mojo::Remote<content_settings::mojom::ContentSettingsManager> 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<subresource_filter::AdResourceTracker>();
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)
new SpellCheckProvider(render_frame, spellcheck_.get(),
local_interface_provider_.get());
#endif
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) {
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,
const url::Origin* outermost_origin) {
new prerender::NoStatePrefetchClient(web_view);
}
SkBitmap* ContentRendererClientImpl::GetSadPluginBitmap() {
return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance()
.GetImageNamed(IDR_SAD_PLUGIN)
.ToSkBitmap());
}
SkBitmap* ContentRendererClientImpl::GetSadWebViewBitmap() {
return const_cast<SkBitmap*>(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)
android_system_error_page::PopulateErrorPageHtml(error, error_html);
#endif
}
std::unique_ptr<blink::URLLoaderThrottleProvider>
ContentRendererClientImpl::CreateURLLoaderThrottleProvider(
blink::URLLoaderThrottleProviderType provider_type) {
return std::make_unique<URLLoaderThrottleProvider>(
browser_interface_broker_.get(), provider_type);
}
void ContentRendererClientImpl::GetSupportedKeySystems(
media::GetSupportedKeySystemsCB cb) {
media::KeySystemInfos key_systems;
#if BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(ENABLE_WIDEVINE)
cdm::AddAndroidWidevine(&key_systems);
#endif
cdm::AddAndroidPlatformKeySystems(&key_systems);
#endif
std::move(cb).Run(std::move(key_systems));
}
void ContentRendererClientImpl::
SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true);
#if BUILDFLAG(IS_ANDROID)
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));
}
}