1 // Copyright (c) 2012 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 "chrome/renderer/chrome_content_renderer_client.h"
6 
7 #include <functional>
8 #include <memory>
9 #include <utility>
10 
11 #include "base/bind.h"
12 #include "base/check_op.h"
13 #include "base/command_line.h"
14 #include "base/debug/crash_logging.h"
15 #include "base/macros.h"
16 #include "base/metrics/histogram_functions.h"
17 #include "base/metrics/histogram_macros.h"
18 #include "base/metrics/user_metrics_action.h"
19 #include "base/no_destructor.h"
20 #include "base/notreached.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/string_util.h"
23 #include "base/strings/stringprintf.h"
24 #include "base/strings/utf_string_conversions.h"
25 #include "base/time/time.h"
26 #include "base/values.h"
27 #include "chrome/common/buildflags.h"
28 #include "chrome/common/channel_info.h"
29 #include "chrome/common/chrome_content_client.h"
30 #include "chrome/common/chrome_features.h"
31 #include "chrome/common/chrome_isolated_world_ids.h"
32 #include "chrome/common/chrome_paths.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/crash_keys.h"
35 #include "chrome/common/pdf_util.h"
36 #include "chrome/common/pepper_permission_util.h"
37 #include "chrome/common/privacy_budget/privacy_budget_settings_provider.h"
38 #include "chrome/common/profiler/thread_profiler.h"
39 #include "chrome/common/secure_origin_allowlist.h"
40 #include "chrome/common/url_constants.h"
41 #include "chrome/common/webui_url_constants.h"
42 #include "chrome/grit/chromium_strings.h"
43 #include "chrome/grit/generated_resources.h"
44 #include "chrome/grit/renderer_resources.h"
45 #include "chrome/renderer/benchmarking_extension.h"
46 #include "chrome/renderer/browser_exposed_renderer_interfaces.h"
47 #include "chrome/renderer/chrome_content_settings_agent_delegate.h"
48 #include "chrome/renderer/chrome_render_frame_observer.h"
49 #include "chrome/renderer/chrome_render_thread_observer.h"
50 #include "chrome/renderer/lite_video/lite_video_hint_agent.h"
51 #include "chrome/renderer/lite_video/lite_video_util.h"
52 #include "chrome/renderer/loadtimes_extension_bindings.h"
53 #include "chrome/renderer/media/flash_embed_rewrite.h"
54 #include "chrome/renderer/media/webrtc_logging_agent_impl.h"
55 #include "chrome/renderer/net/net_error_helper.h"
56 #include "chrome/renderer/net_benchmarking_extension.h"
57 #include "chrome/renderer/pepper/pepper_helper.h"
58 #include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h"
59 #include "chrome/renderer/plugins/pdf_plugin_placeholder.h"
60 #include "chrome/renderer/plugins/plugin_uma.h"
61 #include "chrome/renderer/previews/resource_loading_hints_agent.h"
62 #include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
63 #include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
64 #include "chrome/renderer/sync_encryption_keys_extension.h"
65 #include "chrome/renderer/url_loader_throttle_provider_impl.h"
66 #include "chrome/renderer/v8_unwinder.h"
67 #include "chrome/renderer/websocket_handshake_throttle_provider_impl.h"
68 #include "chrome/renderer/worker_content_settings_client.h"
69 #include "components/autofill/content/renderer/autofill_agent.h"
70 #include "components/autofill/content/renderer/autofill_assistant_agent.h"
71 #include "components/autofill/content/renderer/password_autofill_agent.h"
72 #include "components/autofill/content/renderer/password_generation_agent.h"
73 #include "components/content_capture/common/content_capture_features.h"
74 #include "components/content_capture/renderer/content_capture_sender.h"
75 #include "components/content_settings/core/common/content_settings_pattern.h"
76 #include "components/contextual_search/buildflags.h"
77 #include "components/contextual_search/content/renderer/overlay_js_render_frame_observer.h"
78 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
79 #include "components/dom_distiller/content/renderer/distillability_agent.h"
80 #include "components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h"
81 #include "components/dom_distiller/core/dom_distiller_features.h"
82 #include "components/dom_distiller/core/dom_distiller_switches.h"
83 #include "components/dom_distiller/core/url_constants.h"
84 #include "components/error_page/common/error.h"
85 #include "components/error_page/common/localized_error.h"
86 #include "components/grit/components_scaled_resources.h"
87 #include "components/network_hints/renderer/web_prescient_networking_impl.h"
88 #include "components/no_state_prefetch/common/prerender_types.mojom.h"
89 #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
90 #include "components/no_state_prefetch/renderer/prerender_helper.h"
91 #include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h"
92 #include "components/no_state_prefetch/renderer/prerender_utils.h"
93 #include "components/no_state_prefetch/renderer/prerenderer_client.h"
94 #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
95 #include "components/paint_preview/buildflags/buildflags.h"
96 #include "components/pdf/renderer/pepper_pdf_host.h"
97 #include "components/safe_browsing/buildflags.h"
98 #include "components/safe_browsing/content/renderer/threat_dom_details.h"
99 #include "components/spellcheck/spellcheck_buildflags.h"
100 #include "components/subresource_filter/content/renderer/subresource_filter_agent.h"
101 #include "components/subresource_filter/content/renderer/unverified_ruleset_dealer.h"
102 #include "components/subresource_filter/core/common/common_features.h"
103 #include "components/sync/engine/sync_engine_switches.h"
104 #include "components/translate/content/renderer/per_frame_translate_agent.h"
105 #include "components/translate/core/common/translate_util.h"
106 #include "components/variations/net/variations_http_headers.h"
107 #include "components/variations/variations_switches.h"
108 #include "components/version_info/version_info.h"
109 #include "components/visitedlink/renderer/visitedlink_reader.h"
110 #include "components/web_cache/renderer/web_cache_impl.h"
111 #include "content/public/common/content_constants.h"
112 #include "content/public/common/content_features.h"
113 #include "content/public/common/content_switches.h"
114 #include "content/public/common/page_visibility_state.h"
115 #include "content/public/common/service_names.mojom.h"
116 #include "content/public/common/url_constants.h"
117 #include "content/public/common/webplugininfo.h"
118 #include "content/public/renderer/render_frame.h"
119 #include "content/public/renderer/render_frame_visitor.h"
120 #include "content/public/renderer/render_view.h"
121 #include "content/public/renderer/render_view_observer.h"
122 #include "extensions/buildflags/buildflags.h"
123 #include "ipc/ipc_sync_channel.h"
124 #include "media/base/media_switches.h"
125 #include "media/media_buildflags.h"
126 #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
127 #include "mojo/public/cpp/bindings/remote.h"
128 #include "net/base/net_errors.h"
129 #include "ppapi/buildflags/buildflags.h"
130 #include "ppapi/shared_impl/ppapi_switches.h"
131 #include "printing/buildflags/buildflags.h"
132 #include "services/network/public/cpp/is_potentially_trustworthy.h"
133 #include "services/service_manager/public/cpp/interface_provider.h"
134 #include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
135 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
136 #include "third_party/blink/public/common/features.h"
137 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
138 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
139 #include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
140 #include "third_party/blink/public/platform/platform.h"
141 #include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h"
142 #include "third_party/blink/public/platform/url_conversion.h"
143 #include "third_party/blink/public/platform/web_cache.h"
144 #include "third_party/blink/public/platform/web_runtime_features.h"
145 #include "third_party/blink/public/platform/web_security_origin.h"
146 #include "third_party/blink/public/platform/web_url.h"
147 #include "third_party/blink/public/platform/web_url_error.h"
148 #include "third_party/blink/public/platform/web_url_request.h"
149 #include "third_party/blink/public/platform/web_url_response.h"
150 #include "third_party/blink/public/web/web_document.h"
151 #include "third_party/blink/public/web/web_element.h"
152 #include "third_party/blink/public/web/web_heap.h"
153 #include "third_party/blink/public/web/web_local_frame.h"
154 #include "third_party/blink/public/web/web_origin_trials.h"
155 #include "third_party/blink/public/web/web_plugin_container.h"
156 #include "third_party/blink/public/web/web_plugin_params.h"
157 #include "third_party/blink/public/web/web_security_policy.h"
158 #include "third_party/blink/public/web/web_view.h"
159 #include "ui/base/l10n/l10n_util.h"
160 #include "ui/base/layout.h"
161 #include "ui/base/resource/resource_bundle.h"
162 #include "ui/base/webui/jstemplate_builder.h"
163 #include "url/origin.h"
164 
165 #if defined(OS_ANDROID)
166 #include "chrome/renderer/sandbox_status_extension_android.h"
167 #else
168 #include "chrome/renderer/media/chrome_speech_recognition_client.h"
169 #include "chrome/renderer/searchbox/searchbox.h"
170 #include "chrome/renderer/searchbox/searchbox_extension.h"
171 #endif
172 
173 #if BUILDFLAG(ENABLE_NACL)
174 #include "components/nacl/common/nacl_constants.h"
175 #include "components/nacl/renderer/nacl_helper.h"
176 #endif
177 
178 #if BUILDFLAG(ENABLE_EXTENSIONS)
179 #include "chrome/common/initialize_extensions_client.h"
180 #include "chrome/common/url_loader_factory_proxy.mojom.h"
181 #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
182 #include "extensions/common/constants.h"
183 #include "extensions/common/extension_urls.h"
184 #include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
185 #include "extensions/common/switches.h"
186 #include "extensions/renderer/dispatcher.h"
187 #include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
188 #include "extensions/renderer/renderer_extension_registry.h"
189 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
190 #include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom.h"
191 #include "third_party/blink/public/web/web_settings.h"
192 #include "third_party/blink/public/web/web_view.h"
193 #endif
194 
195 #if BUILDFLAG(ENABLE_PLUGINS)
196 #include "chrome/common/plugin_utils.h"
197 #include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
198 #else
199 #include "components/plugins/renderer/plugin_placeholder.h"
200 #endif
201 
202 #if BUILDFLAG(ENABLE_PRINTING)
203 #include "chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h"
204 #include "components/printing/renderer/print_render_frame_helper.h"  // nogncheck
205 #include "printing/print_settings.h"  // nogncheck
206 #endif
207 
208 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
209 #include "chrome/renderer/pepper/chrome_pdf_print_client.h"
210 #endif
211 
212 #if BUILDFLAG(ENABLE_PAINT_PREVIEW)
213 #include "components/paint_preview/renderer/paint_preview_recorder_impl.h"  // nogncheck
214 #endif
215 
216 #if BUILDFLAG(ENABLE_SPELLCHECK)
217 #include "components/spellcheck/renderer/spellcheck.h"
218 #include "components/spellcheck/renderer/spellcheck_provider.h"
219 
220 #if BUILDFLAG(HAS_SPELLCHECK_PANEL)
221 #include "components/spellcheck/renderer/spellcheck_panel.h"
222 #endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
223 #endif  // BUILDFLAG(ENABLE_SPELLCHECK)
224 
225 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
226 #include "chrome/renderer/supervised_user/supervised_user_error_page_controller_delegate_impl.h"
227 #endif
228 
229 using autofill::AutofillAgent;
230 using autofill::AutofillAssistantAgent;
231 using autofill::PasswordAutofillAgent;
232 using autofill::PasswordGenerationAgent;
233 using base::ASCIIToUTF16;
234 using base::UserMetricsAction;
235 using blink::WebCache;
236 using blink::WebConsoleMessage;
237 using blink::WebDocument;
238 using blink::WebFrame;
239 using blink::WebLocalFrame;
240 using blink::WebPlugin;
241 using blink::WebPluginParams;
242 using blink::WebSecurityOrigin;
243 using blink::WebSecurityPolicy;
244 using blink::WebString;
245 using blink::WebURL;
246 using blink::WebURLError;
247 using blink::WebURLRequest;
248 using blink::WebURLResponse;
249 using blink::WebVector;
250 using blink::mojom::FetchCacheMode;
251 using content::RenderFrame;
252 using content::RenderThread;
253 using content::WebPluginInfo;
254 using content::WebPluginMimeType;
255 using extensions::Extension;
256 
257 namespace {
258 
259 // Whitelist PPAPI for Android Runtime for Chromium. (See crbug.com/383937)
260 #if BUILDFLAG(ENABLE_PLUGINS)
261 const char* const kPredefinedAllowedCameraDeviceOrigins[] = {
262     "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F",
263     "4EB74897CB187C7633357C2FE832E0AD6A44883A"};
264 #endif
265 
266 #if BUILDFLAG(ENABLE_PLUGINS)
AppendParams(const std::vector<WebPluginMimeType::Param> & additional_params,WebVector<WebString> * existing_names,WebVector<WebString> * existing_values)267 void AppendParams(
268     const std::vector<WebPluginMimeType::Param>& additional_params,
269     WebVector<WebString>* existing_names,
270     WebVector<WebString>* existing_values) {
271   DCHECK(existing_names->size() == existing_values->size());
272   size_t existing_size = existing_names->size();
273   size_t total_size = existing_size + additional_params.size();
274 
275   WebVector<WebString> names(total_size);
276   WebVector<WebString> values(total_size);
277 
278   for (size_t i = 0; i < existing_size; ++i) {
279     names[i] = (*existing_names)[i];
280     values[i] = (*existing_values)[i];
281   }
282 
283   for (size_t i = 0; i < additional_params.size(); ++i) {
284     names[existing_size + i] = WebString::FromUTF16(additional_params[i].name);
285     values[existing_size + i] =
286         WebString::FromUTF16(additional_params[i].value);
287   }
288 
289   existing_names->Swap(names);
290   existing_values->Swap(values);
291 }
292 #endif  // BUILDFLAG(ENABLE_PLUGINS)
293 
IsStandaloneContentExtensionProcess()294 bool IsStandaloneContentExtensionProcess() {
295 #if !BUILDFLAG(ENABLE_EXTENSIONS)
296   return false;
297 #else
298   return base::CommandLine::ForCurrentProcess()->HasSwitch(
299       extensions::switches::kExtensionProcess);
300 #endif
301 }
302 
CreateV8Unwinder(v8::Isolate * isolate)303 std::unique_ptr<base::Unwinder> CreateV8Unwinder(v8::Isolate* isolate) {
304   return std::make_unique<V8Unwinder>(isolate);
305 }
306 
307 }  // namespace
308 
ChromeContentRendererClient()309 ChromeContentRendererClient::ChromeContentRendererClient()
310     :
311 #if defined(OS_WIN)
312       remote_module_watcher_(nullptr, base::OnTaskRunnerDeleter(nullptr)),
313 #endif
314       main_thread_profiler_(ThreadProfiler::CreateAndStartOnMainThread()) {
315 #if BUILDFLAG(ENABLE_EXTENSIONS)
316   EnsureExtensionsClientInitialized();
317   extensions::ExtensionsRendererClient::Set(
318       ChromeExtensionsRendererClient::GetInstance());
319 #endif
320 #if BUILDFLAG(ENABLE_PLUGINS)
321   for (const char* origin : kPredefinedAllowedCameraDeviceOrigins)
322     allowed_camera_device_origins_.insert(origin);
323 #endif
324 }
325 
~ChromeContentRendererClient()326 ChromeContentRendererClient::~ChromeContentRendererClient() {}
327 
RenderThreadStarted()328 void ChromeContentRendererClient::RenderThreadStarted() {
329   RenderThread* thread = RenderThread::Get();
330 
331   main_thread_profiler_->SetAuxUnwinderFactory(base::BindRepeating(
332       &CreateV8Unwinder, base::Unretained(v8::Isolate::GetCurrent())));
333 
334   // In the case of single process mode, the v8 unwinding will not work.
335   tracing::TracingSamplerProfiler::SetAuxUnwinderFactoryOnMainThread(
336       base::BindRepeating(&CreateV8Unwinder,
337                           base::Unretained(v8::Isolate::GetCurrent())));
338 
339   thread->SetRendererProcessType(
340       IsStandaloneContentExtensionProcess()
341           ? blink::scheduler::WebRendererProcessType::kExtensionRenderer
342           : blink::scheduler::WebRendererProcessType::kRenderer);
343 
344 #if defined(OS_WIN)
345   mojo::PendingRemote<mojom::ModuleEventSink> module_event_sink;
346   thread->BindHostReceiver(module_event_sink.InitWithNewPipeAndPassReceiver());
347   remote_module_watcher_ = RemoteModuleWatcher::Create(
348       thread->GetIOTaskRunner(), std::move(module_event_sink));
349 #endif
350 
351   browser_interface_broker_ =
352       blink::Platform::Current()->GetBrowserInterfaceBroker();
353 
354   chrome_observer_ = std::make_unique<ChromeRenderThreadObserver>();
355   web_cache_impl_ = std::make_unique<web_cache::WebCacheImpl>();
356 
357 #if BUILDFLAG(ENABLE_EXTENSIONS)
358   ChromeExtensionsRendererClient::GetInstance()->RenderThreadStarted();
359 #endif
360 
361 #if BUILDFLAG(ENABLE_SPELLCHECK)
362   if (!spellcheck_)
363     InitSpellCheck();
364 #endif
365 
366   subresource_filter_ruleset_dealer_.reset(
367       new subresource_filter::UnverifiedRulesetDealer());
368 
369   thread->AddObserver(chrome_observer_.get());
370   thread->AddObserver(subresource_filter_ruleset_dealer_.get());
371 
372   thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get());
373 
374   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
375   if (command_line->HasSwitch(variations::switches::kEnableBenchmarking))
376     thread->RegisterExtension(extensions_v8::BenchmarkingExtension::Get());
377   if (command_line->HasSwitch(switches::kEnableNetBenchmarking))
378     thread->RegisterExtension(extensions_v8::NetBenchmarkingExtension::Get());
379 
380   // chrome: is also to be permitted to embeds https:// things and have them
381   // treated as first-party.
382   // See
383   // ChromeContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel
384   WebString chrome_scheme(WebString::FromASCII(content::kChromeUIScheme));
385   WebSecurityPolicy::RegisterURLSchemeAsFirstPartyWhenTopLevelEmbeddingSecure(
386       chrome_scheme);
387 
388   // chrome-native: is a scheme used for placeholder navigations that allow
389   // UIs to be drawn with platform native widgets instead of HTML.  These pages
390   // should not be accessible.  No code should be runnable in these pages,
391   // so it should not need to access anything nor should it allow javascript
392   // URLs since it should never be visible to the user.
393   // See also ChromeContentClient::AddAdditionalSchemes that adds it as an
394   // empty document scheme.
395   WebString native_scheme(WebString::FromASCII(chrome::kChromeNativeScheme));
396   WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(native_scheme);
397   WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs(
398       native_scheme);
399 
400   // chrome-search: and chrome-distiller: pages  should not be accessible by
401   // normal content, and should also be unable to script anything but themselves
402   // (to help limit the damage that a corrupt page could cause).
403   WebString chrome_search_scheme(
404       WebString::FromASCII(chrome::kChromeSearchScheme));
405 
406   // The Instant process can only display the content but not read it.  Other
407   // processes can't display it or read it.
408   if (!command_line->HasSwitch(switches::kInstantProcess))
409     WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(chrome_search_scheme);
410 
411   WebString dom_distiller_scheme(
412       WebString::FromASCII(dom_distiller::kDomDistillerScheme));
413   // TODO(nyquist): Add test to ensure this happens when the flag is set.
414   WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(dom_distiller_scheme);
415 
416 #if defined(OS_ANDROID)
417   WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer(
418       WebString::FromUTF8(chrome::kAndroidAppScheme));
419 #endif
420 
421   // chrome-search: pages should not be accessible by bookmarklets
422   // or javascript: URLs typed in the omnibox.
423   WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs(
424       chrome_search_scheme);
425 
426 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
427   pdf_print_client_.reset(new ChromePDFPrintClient());
428   pdf::PepperPDFHost::SetPrintClient(pdf_print_client_.get());
429 #endif
430 
431   for (auto& origin_or_hostname_pattern :
432        network::SecureOriginAllowlist::GetInstance().GetCurrentAllowlist()) {
433     WebSecurityPolicy::AddOriginToTrustworthySafelist(
434         WebString::FromUTF8(origin_or_hostname_pattern));
435   }
436 
437   for (auto& scheme :
438        secure_origin_allowlist::GetSchemesBypassingSecureContextCheck()) {
439     WebSecurityPolicy::AddSchemeToSecureContextSafelist(
440         WebString::FromASCII(scheme));
441   }
442 
443   // This doesn't work in single-process mode.
444   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
445           switches::kSingleProcess)) {
446     ThreadProfiler::SetMainThreadTaskRunner(
447         base::ThreadTaskRunnerHandle::Get());
448     mojo::PendingRemote<metrics::mojom::CallStackProfileCollector> collector;
449     thread->BindHostReceiver(collector.InitWithNewPipeAndPassReceiver());
450     ThreadProfiler::SetCollectorForChildProcess(std::move(collector));
451   }
452 
453   blink::IdentifiabilityStudySettings::SetGlobalProvider(
454       std::make_unique<PrivacyBudgetSettingsProvider>());
455 }
456 
ExposeInterfacesToBrowser(mojo::BinderMap * binders)457 void ChromeContentRendererClient::ExposeInterfacesToBrowser(
458     mojo::BinderMap* binders) {
459   // NOTE: Do not add binders directly within this method. Instead, modify the
460   // definition of |ExposeChromeRendererInterfacesToBrowser()| to ensure
461   // security review coverage.
462   ExposeChromeRendererInterfacesToBrowser(this, binders);
463 }
464 
RenderFrameCreated(content::RenderFrame * render_frame)465 void ChromeContentRendererClient::RenderFrameCreated(
466     content::RenderFrame* render_frame) {
467   ChromeRenderFrameObserver* render_frame_observer =
468       new ChromeRenderFrameObserver(render_frame, web_cache_impl_.get());
469   service_manager::BinderRegistry* registry = render_frame_observer->registry();
470 
471   new prerender::PrerenderRenderFrameObserver(render_frame);
472 
473   bool should_whitelist_for_content_settings =
474       base::CommandLine::ForCurrentProcess()->HasSwitch(
475           switches::kInstantProcess);
476   auto content_settings_delegate =
477       std::make_unique<ChromeContentSettingsAgentDelegate>(render_frame);
478 #if BUILDFLAG(ENABLE_EXTENSIONS)
479   content_settings_delegate->SetExtensionDispatcher(
480       ChromeExtensionsRendererClient::GetInstance()->extension_dispatcher());
481 #endif
482   content_settings::ContentSettingsAgentImpl* content_settings =
483       new content_settings::ContentSettingsAgentImpl(
484           render_frame, should_whitelist_for_content_settings,
485           std::move(content_settings_delegate));
486   if (chrome_observer_.get()) {
487     content_settings->SetContentSettingRules(
488         chrome_observer_->content_setting_rules());
489   }
490 
491 #if BUILDFLAG(ENABLE_EXTENSIONS)
492   ChromeExtensionsRendererClient::GetInstance()->RenderFrameCreated(
493       render_frame, registry);
494 #endif
495 
496 #if BUILDFLAG(ENABLE_PLUGINS)
497   new PepperHelper(render_frame);
498 #endif
499 
500 #if BUILDFLAG(ENABLE_NACL)
501   new nacl::NaClHelper(render_frame);
502 #endif
503 
504 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) || BUILDFLAG(SAFE_BROWSING_DB_REMOTE)
505   safe_browsing::ThreatDOMDetails::Create(render_frame, registry);
506 #endif
507 
508 #if BUILDFLAG(ENABLE_PRINTING)
509   new printing::PrintRenderFrameHelper(
510       render_frame, std::make_unique<ChromePrintRenderFrameHelperDelegate>());
511 #endif
512 
513 #if BUILDFLAG(ENABLE_PAINT_PREVIEW)
514   new paint_preview::PaintPreviewRecorderImpl(render_frame);
515 #endif
516 
517 #if defined(OS_ANDROID)
518   SandboxStatusExtension::Create(render_frame);
519 #endif
520 
521 #if !defined(OS_ANDROID)
522   if (base::FeatureList::IsEnabled(
523           switches::kSyncSupportTrustedVaultPassphrase)) {
524     SyncEncryptionKeysExtension::Create(render_frame);
525   }
526 #endif
527 
528   new NetErrorHelper(render_frame);
529 
530 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
531   new SupervisedUserErrorPageControllerDelegateImpl(render_frame);
532 #endif
533 
534   if (!render_frame->IsMainFrame()) {
535     auto* prerender_helper = prerender::PrerenderHelper::Get(
536         render_frame->GetRenderView()->GetMainRenderFrame());
537     if (prerender_helper) {
538       // Avoid any race conditions from having the browser tell subframes that
539       // they're prerendering.
540       new prerender::PrerenderHelper(render_frame,
541                                      prerender_helper->prerender_mode(),
542                                      prerender_helper->histogram_prefix());
543     }
544   }
545 
546   // Set up a render frame observer to test if this page is a distiller page.
547   new dom_distiller::DistillerJsRenderFrameObserver(
548       render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL);
549 
550   if (dom_distiller::ShouldStartDistillabilityService()) {
551     // Create DistillabilityAgent to send distillability updates to
552     // DistillabilityDriver in the browser process.
553     new dom_distiller::DistillabilityAgent(render_frame, DCHECK_IS_ON());
554   }
555 
556 #if BUILDFLAG(BUILD_CONTEXTUAL_SEARCH)
557   // Set up a mojo service to test if this page is a contextual search page.
558   new contextual_search::OverlayJsRenderFrameObserver(render_frame, registry);
559 #endif
560 
561   blink::AssociatedInterfaceRegistry* associated_interfaces =
562       render_frame_observer->associated_interfaces();
563   PasswordAutofillAgent* password_autofill_agent =
564       new PasswordAutofillAgent(render_frame, associated_interfaces);
565   PasswordGenerationAgent* password_generation_agent =
566       new PasswordGenerationAgent(render_frame, password_autofill_agent,
567                                   associated_interfaces);
568   AutofillAssistantAgent* autofill_assistant_agent =
569       new AutofillAssistantAgent(render_frame);
570   new AutofillAgent(render_frame, password_autofill_agent,
571                     password_generation_agent, autofill_assistant_agent,
572                     associated_interfaces);
573 
574   if (content_capture::features::IsContentCaptureEnabled()) {
575     new content_capture::ContentCaptureSender(render_frame,
576                                               associated_interfaces);
577   }
578 
579 #if BUILDFLAG(ENABLE_EXTENSIONS)
580   associated_interfaces->AddInterface(base::BindRepeating(
581       &extensions::MimeHandlerViewContainerManager::BindReceiver,
582       render_frame->GetRoutingID()));
583 #endif
584 
585   // Owned by |render_frame|.
586   page_load_metrics::MetricsRenderFrameObserver* metrics_render_frame_observer =
587       new page_load_metrics::MetricsRenderFrameObserver(render_frame);
588   // There is no render thread, thus no UnverifiedRulesetDealer in
589   // ChromeRenderViewTests.
590   if (subresource_filter_ruleset_dealer_) {
591     // Create AdResourceTracker to tracker ad resource loads at the chrome
592     // layer.
593     auto ad_resource_tracker =
594         std::make_unique<subresource_filter::AdResourceTracker>();
595     metrics_render_frame_observer->SetAdResourceTracker(
596         ad_resource_tracker.get());
597     new subresource_filter::SubresourceFilterAgent(
598         render_frame, subresource_filter_ruleset_dealer_.get(),
599         std::move(ad_resource_tracker));
600   }
601 
602   if (lite_video::IsLiteVideoEnabled())
603     new lite_video::LiteVideoHintAgent(render_frame);
604 
605   new previews::ResourceLoadingHintsAgent(associated_interfaces, render_frame);
606 
607   if (subresource_redirect::IsPublicImageHintsBasedCompressionEnabled())
608     new subresource_redirect::SubresourceRedirectHintsAgent(render_frame);
609 
610   if (translate::IsSubFrameTranslationEnabled()) {
611     new translate::PerFrameTranslateAgent(
612         render_frame, ISOLATED_WORLD_ID_TRANSLATE, associated_interfaces);
613   }
614 
615 #if !defined(OS_ANDROID)
616   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
617   if (command_line->HasSwitch(switches::kInstantProcess) &&
618       render_frame->IsMainFrame()) {
619     new SearchBox(render_frame);
620   }
621 #endif  // !defined(OS_ANDROID)
622 
623 #if BUILDFLAG(ENABLE_SPELLCHECK)
624   new SpellCheckProvider(render_frame, spellcheck_.get(), this);
625 
626 #if BUILDFLAG(HAS_SPELLCHECK_PANEL)
627   new SpellCheckPanel(render_frame, registry, this);
628 #endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
629 #endif
630 }
631 
RenderViewCreated(content::RenderView * render_view)632 void ChromeContentRendererClient::RenderViewCreated(
633     content::RenderView* render_view) {
634   new prerender::PrerendererClient(render_view);
635 }
636 
GetSadPluginBitmap()637 SkBitmap* ChromeContentRendererClient::GetSadPluginBitmap() {
638   return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance()
639                                    .GetImageNamed(IDR_SAD_PLUGIN)
640                                    .ToSkBitmap());
641 }
642 
GetSadWebViewBitmap()643 SkBitmap* ChromeContentRendererClient::GetSadWebViewBitmap() {
644   return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance()
645                                    .GetImageNamed(IDR_SAD_WEBVIEW)
646                                    .ToSkBitmap());
647 }
648 
IsPluginHandledExternally(content::RenderFrame * render_frame,const blink::WebElement & plugin_element,const GURL & original_url,const std::string & mime_type)649 bool ChromeContentRendererClient::IsPluginHandledExternally(
650     content::RenderFrame* render_frame,
651     const blink::WebElement& plugin_element,
652     const GURL& original_url,
653     const std::string& mime_type) {
654 #if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS)
655   DCHECK(plugin_element.HasHTMLTagName("object") ||
656          plugin_element.HasHTMLTagName("embed"));
657   // Blink will next try to load a WebPlugin which would end up in
658   // OverrideCreatePlugin, sending another IPC only to find out the plugin is
659   // not supported. Here it suffices to return false but there should perhaps be
660   // a more unified approach to avoid sending the IPC twice.
661   chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New();
662   GetPluginInfoHost()->GetPluginInfo(
663       render_frame->GetRoutingID(), original_url,
664       render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), mime_type,
665       &plugin_info);
666   // TODO(ekaramad): Not continuing here due to a disallowed status should take
667   // us to CreatePlugin. See if more in depths investigation of |status| is
668   // necessary here (see https://crbug.com/965747). For now, returning false
669   // should take us to CreatePlugin after HTMLPlugInElement which is called
670   // through HTMLPlugInElement::LoadPlugin code path.
671   if (plugin_info->status != chrome::mojom::PluginStatus::kAllowed &&
672       plugin_info->status !=
673           chrome::mojom::PluginStatus::kPlayImportantContent) {
674     // We could get here when a MimeHandlerView is loaded inside a <webview>
675     // which is using permissions API (see WebViewPluginTests).
676     ChromeExtensionsRendererClient::DidBlockMimeHandlerViewForDisallowedPlugin(
677         plugin_element);
678     return false;
679   }
680   return ChromeExtensionsRendererClient::MaybeCreateMimeHandlerView(
681       plugin_element, original_url, plugin_info->actual_mime_type,
682       plugin_info->plugin);
683 #else
684   return false;
685 #endif
686 }
687 
GetScriptableObject(const blink::WebElement & plugin_element,v8::Isolate * isolate)688 v8::Local<v8::Object> ChromeContentRendererClient::GetScriptableObject(
689     const blink::WebElement& plugin_element,
690     v8::Isolate* isolate) {
691 #if BUILDFLAG(ENABLE_EXTENSIONS)
692   return ChromeExtensionsRendererClient::GetInstance()->GetScriptableObject(
693       plugin_element, isolate);
694 #else
695   return v8::Local<v8::Object>();
696 #endif
697 }
698 
OverrideCreatePlugin(content::RenderFrame * render_frame,const WebPluginParams & params,WebPlugin ** plugin)699 bool ChromeContentRendererClient::OverrideCreatePlugin(
700     content::RenderFrame* render_frame,
701     const WebPluginParams& params,
702     WebPlugin** plugin) {
703   std::string orig_mime_type = params.mime_type.Utf8();
704 #if BUILDFLAG(ENABLE_EXTENSIONS)
705   if (!ChromeExtensionsRendererClient::GetInstance()->OverrideCreatePlugin(
706           render_frame, params)) {
707     return false;
708   }
709 #endif
710 
711   GURL url(params.url);
712 #if BUILDFLAG(ENABLE_PLUGINS)
713   chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New();
714   GetPluginInfoHost()->GetPluginInfo(
715       render_frame->GetRoutingID(), url,
716       render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), orig_mime_type,
717       &plugin_info);
718   *plugin = CreatePlugin(render_frame, params, *plugin_info);
719 #else  // !BUILDFLAG(ENABLE_PLUGINS)
720   PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url);
721   if (orig_mime_type == kPDFMimeType) {
722     ReportPDFLoadStatus(
723         PDFLoadStatus::kShowedDisabledPluginPlaceholderForEmbeddedPdf);
724     if (base::FeatureList::IsEnabled(features::kClickToOpenPDFPlaceholder)) {
725       PDFPluginPlaceholder* placeholder =
726           PDFPluginPlaceholder::CreatePDFPlaceholder(render_frame, params);
727       *plugin = placeholder->plugin();
728       return true;
729     }
730   }
731   auto* placeholder = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin(
732       render_frame, params);
733   *plugin = placeholder->plugin();
734 
735 #endif  // BUILDFLAG(ENABLE_PLUGINS)
736   return true;
737 }
738 
CreatePluginReplacement(content::RenderFrame * render_frame,const base::FilePath & plugin_path)739 WebPlugin* ChromeContentRendererClient::CreatePluginReplacement(
740     content::RenderFrame* render_frame,
741     const base::FilePath& plugin_path) {
742   auto* placeholder = NonLoadablePluginPlaceholder::CreateErrorPlugin(
743       render_frame, plugin_path);
744   return placeholder->plugin();
745 }
746 
DeferMediaLoad(content::RenderFrame * render_frame,bool has_played_media_before,base::OnceClosure closure)747 bool ChromeContentRendererClient::DeferMediaLoad(
748     content::RenderFrame* render_frame,
749     bool has_played_media_before,
750     base::OnceClosure closure) {
751   return prerender::DeferMediaLoad(render_frame, has_played_media_before,
752                                    std::move(closure));
753 }
754 
755 #if BUILDFLAG(ENABLE_PLUGINS)
756 
757 mojo::AssociatedRemote<chrome::mojom::PluginInfoHost>&
GetPluginInfoHost()758 ChromeContentRendererClient::GetPluginInfoHost() {
759   struct PluginInfoHostHolder {
760     PluginInfoHostHolder() {
761       RenderThread::Get()->GetChannel()->GetRemoteAssociatedInterface(
762           &plugin_info_host);
763     }
764     ~PluginInfoHostHolder() {}
765     mojo::AssociatedRemote<chrome::mojom::PluginInfoHost> plugin_info_host;
766   };
767   static base::NoDestructor<PluginInfoHostHolder> holder;
768   return holder->plugin_info_host;
769 }
770 
771 // static
CreatePlugin(content::RenderFrame * render_frame,const WebPluginParams & original_params,const chrome::mojom::PluginInfo & plugin_info)772 WebPlugin* ChromeContentRendererClient::CreatePlugin(
773     content::RenderFrame* render_frame,
774     const WebPluginParams& original_params,
775     const chrome::mojom::PluginInfo& plugin_info) {
776   const WebPluginInfo& info = plugin_info.plugin;
777   const std::string& actual_mime_type = plugin_info.actual_mime_type;
778   const base::string16& group_name = plugin_info.group_name;
779   const std::string& identifier = plugin_info.group_identifier;
780   chrome::mojom::PluginStatus status = plugin_info.status;
781   GURL url(original_params.url);
782   std::string orig_mime_type = original_params.mime_type.Utf8();
783   ChromePluginPlaceholder* placeholder = nullptr;
784 
785   // If the browser plugin is to be enabled, this should be handled by the
786   // renderer, so the code won't reach here due to the early exit in
787   // OverrideCreatePlugin.
788   if (status == chrome::mojom::PluginStatus::kNotFound ||
789       orig_mime_type == content::kBrowserPluginMimeType) {
790     // Flash has been thoroughly removed in M88+, so we need to have a special
791     // case here to display a deprecated message instead of a generic
792     // plugin-missing message.
793     if (orig_mime_type == "application/x-shockwave-flash" ||
794         orig_mime_type == "application/futuresplash") {
795       return NonLoadablePluginPlaceholder::CreateFlashDeprecatedPlaceholder(
796                  render_frame, original_params)
797           ->plugin();
798     } else {
799       PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type,
800                                                             url);
801       placeholder = ChromePluginPlaceholder::CreateLoadableMissingPlugin(
802           render_frame, original_params);
803     }
804   } else {
805     // TODO(bauerb): This should be in content/.
806     WebPluginParams params(original_params);
807     for (const auto& mime_type : info.mime_types) {
808       if (mime_type.mime_type == actual_mime_type) {
809         AppendParams(mime_type.additional_params, &params.attribute_names,
810                      &params.attribute_values);
811         break;
812       }
813     }
814     if (params.mime_type.IsNull() && (actual_mime_type.size() > 0)) {
815       // Webkit might say that mime type is null while we already know the
816       // actual mime type via ChromeViewHostMsg_GetPluginInfo. In that case
817       // we should use what we know since WebpluginDelegateProxy does some
818       // specific initializations based on this information.
819       params.mime_type = WebString::FromUTF8(actual_mime_type);
820     }
821 
822     auto* content_settings_agent =
823         content_settings::ContentSettingsAgentImpl::Get(render_frame);
824     auto* content_settings_agent_delegate =
825         ChromeContentSettingsAgentDelegate::Get(render_frame);
826 
827     const ContentSettingsType content_type =
828         ShouldUseJavaScriptSettingForPlugin(info)
829             ? ContentSettingsType::JAVASCRIPT
830             : ContentSettingsType::PLUGINS;
831 
832     if ((status == chrome::mojom::PluginStatus::kUnauthorized ||
833          status == chrome::mojom::PluginStatus::kBlocked) &&
834         content_settings_agent_delegate->IsPluginTemporarilyAllowed(
835             identifier)) {
836       status = chrome::mojom::PluginStatus::kAllowed;
837     }
838 
839     auto create_blocked_plugin = [&render_frame, &params, &info, &identifier,
840                                   &group_name](int template_id,
841                                                const base::string16& message) {
842       return ChromePluginPlaceholder::CreateBlockedPlugin(
843           render_frame, params, info, identifier, group_name, template_id,
844           message);
845     };
846     WebLocalFrame* frame = render_frame->GetWebFrame();
847     switch (status) {
848       case chrome::mojom::PluginStatus::kNotFound: {
849         NOTREACHED();
850         break;
851       }
852       case chrome::mojom::PluginStatus::kAllowed:
853       case chrome::mojom::PluginStatus::kPlayImportantContent: {
854 #if BUILDFLAG(ENABLE_NACL) && BUILDFLAG(ENABLE_EXTENSIONS)
855         const bool is_nacl_plugin =
856             info.name == ASCIIToUTF16(nacl::kNaClPluginName);
857         const bool is_nacl_mime_type =
858             actual_mime_type == nacl::kNaClPluginMimeType;
859         const bool is_pnacl_mime_type =
860             actual_mime_type == nacl::kPnaclPluginMimeType;
861         if (is_nacl_plugin || is_nacl_mime_type || is_pnacl_mime_type) {
862           bool has_enable_nacl_switch =
863               base::CommandLine::ForCurrentProcess()->HasSwitch(
864                   switches::kEnableNaCl);
865           bool is_nacl_unrestricted =
866               has_enable_nacl_switch || is_pnacl_mime_type;
867           GURL manifest_url;
868           GURL app_url;
869           if (is_nacl_mime_type || is_pnacl_mime_type) {
870             // Normal NaCl/PNaCl embed. The app URL is the page URL.
871             manifest_url = url;
872             app_url = frame->GetDocument().Url();
873           } else {
874             // NaCl is being invoked as a content handler. Look up the NaCl
875             // module using the MIME type. The app URL is the manifest URL.
876             manifest_url = GetNaClContentHandlerURL(actual_mime_type, info);
877             app_url = manifest_url;
878           }
879           bool is_module_allowed = false;
880           const Extension* extension =
881               extensions::RendererExtensionRegistry::Get()
882                   ->GetExtensionOrAppByURL(manifest_url);
883           if (extension) {
884             is_module_allowed =
885                 IsNativeNaClAllowed(app_url, is_nacl_unrestricted, extension);
886           } else {
887             WebDocument document = frame->GetDocument();
888             is_module_allowed =
889                 has_enable_nacl_switch ||
890                 (is_pnacl_mime_type &&
891                  blink::WebOriginTrials::isTrialEnabled(&document, "PNaCl"));
892           }
893           if (!is_module_allowed) {
894             WebString error_message;
895             if (is_nacl_mime_type) {
896               error_message =
897                   "Only unpacked extensions and apps installed from the Chrome "
898                   "Web Store can load NaCl modules without enabling Native "
899                   "Client in about:flags.";
900             } else if (is_pnacl_mime_type) {
901               error_message =
902                   "PNaCl modules can only be used on the open web (non-app/"
903                   "extension) when the PNaCl Origin Trial is enabled";
904             }
905             frame->AddMessageToConsole(WebConsoleMessage(
906                 blink::mojom::ConsoleMessageLevel::kError, error_message));
907             placeholder = create_blocked_plugin(
908                 IDR_BLOCKED_PLUGIN_HTML,
909 #if defined(OS_CHROMEOS)
910                 l10n_util::GetStringUTF16(IDS_NACL_PLUGIN_BLOCKED));
911 #else
912                 l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name));
913 #endif
914             break;
915           }
916           ReportNaClAppType(is_pnacl_mime_type, extension,
917                             extension ? extension->is_hosted_app() : false);
918         }
919 #endif  // BUILDFLAG(ENABLE_NACL) && BUILDFLAG(ENABLE_EXTENSIONS)
920 
921         if (GURL(frame->GetDocument().Url()).host_piece() ==
922             extension_misc::kPdfExtensionId) {
923           if (!base::FeatureList::IsEnabled(features::kWebUIDarkMode)) {
924             auto* render_view = render_frame->GetRenderView();
925             auto* web_view = render_view ? render_view->GetWebView() : nullptr;
926             if (web_view) {
927               web_view->GetSettings()->SetPreferredColorScheme(
928                   blink::mojom::PreferredColorScheme::kLight);
929             }
930           }
931         } else if (info.name ==
932                    ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName)) {
933           // Report PDF load metrics. Since the PDF plugin is comprised of an
934           // extension that loads a second plugin, avoid double counting by
935           // ignoring the creation of the second plugin.
936           bool is_main_frame_plugin_document =
937               render_frame->IsMainFrame() &&
938               render_frame->GetWebFrame()->GetDocument().IsPluginDocument();
939           ReportPDFLoadStatus(
940               is_main_frame_plugin_document
941                   ? PDFLoadStatus::kLoadedFullPagePdfWithPdfium
942                   : PDFLoadStatus::kLoadedEmbeddedPdfWithPdfium);
943         }
944 
945         // Delay loading plugins if prerendering.
946         // TODO(mmenke):  In the case of prerendering, feed into
947         //                ChromeContentRendererClient::CreatePlugin instead, to
948         //                reduce the chance of future regressions.
949         bool is_prerendering =
950             prerender::PrerenderHelper::IsPrerendering(render_frame);
951 
952         if (is_prerendering) {
953           placeholder = ChromePluginPlaceholder::CreateBlockedPlugin(
954               render_frame, params, info, identifier, group_name,
955               IDR_BLOCKED_PLUGIN_HTML,
956               l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name));
957           placeholder->set_blocked_for_prerendering(is_prerendering);
958           placeholder->AllowLoading();
959           break;
960         }
961 
962         return render_frame->CreatePlugin(info, params);
963       }
964       case chrome::mojom::PluginStatus::kDisabled: {
965         PluginUMAReporter::GetInstance()->ReportPluginDisabled(orig_mime_type,
966                                                                url);
967         if (info.name ==
968             ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName)) {
969           ReportPDFLoadStatus(
970               PDFLoadStatus::kShowedDisabledPluginPlaceholderForEmbeddedPdf);
971 
972           if (base::FeatureList::IsEnabled(
973                   features::kClickToOpenPDFPlaceholder)) {
974             return PDFPluginPlaceholder::CreatePDFPlaceholder(render_frame,
975                                                               params)
976                 ->plugin();
977           }
978         }
979 
980         placeholder = create_blocked_plugin(
981             IDR_DISABLED_PLUGIN_HTML,
982             l10n_util::GetStringFUTF16(IDS_PLUGIN_DISABLED, group_name));
983         break;
984       }
985       case chrome::mojom::PluginStatus::kFlashHiddenPreferHtml: {
986         placeholder = create_blocked_plugin(
987             IDR_PREFER_HTML_PLUGIN_HTML,
988             l10n_util::GetStringFUTF16(IDS_PLUGIN_PREFER_HTML_BY_DEFAULT,
989                                        group_name));
990         break;
991       }
992       case chrome::mojom::PluginStatus::kOutdatedBlocked: {
993         placeholder = create_blocked_plugin(
994             IDR_BLOCKED_PLUGIN_HTML,
995             l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name));
996         placeholder->AllowLoading();
997         mojo::AssociatedRemote<chrome::mojom::PluginHost> plugin_host;
998         render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
999             plugin_host.BindNewEndpointAndPassReceiver());
1000         plugin_host->BlockedOutdatedPlugin(placeholder->BindPluginRenderer(),
1001                                            identifier);
1002         break;
1003       }
1004       case chrome::mojom::PluginStatus::kOutdatedDisallowed: {
1005         placeholder = create_blocked_plugin(
1006             IDR_BLOCKED_PLUGIN_HTML,
1007             l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name));
1008         break;
1009       }
1010       case chrome::mojom::PluginStatus::kDeprecated: {
1011         // kDeprecatedPlugins act similarly to kOutdatedBlocked ones, but do
1012         // not allow for loading. They still show an infobar.
1013         placeholder = create_blocked_plugin(
1014             IDR_BLOCKED_PLUGIN_HTML,
1015             l10n_util::GetStringFUTF16(IDS_PLUGIN_DEPRECATED, group_name));
1016         mojo::AssociatedRemote<chrome::mojom::PluginHost> plugin_host;
1017         render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
1018             plugin_host.BindNewEndpointAndPassReceiver());
1019         plugin_host->BlockedOutdatedPlugin(placeholder->BindPluginRenderer(),
1020                                            identifier);
1021         break;
1022       }
1023       case chrome::mojom::PluginStatus::kUnauthorized: {
1024         placeholder = create_blocked_plugin(
1025             IDR_BLOCKED_PLUGIN_HTML,
1026             l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name));
1027         placeholder->AllowLoading();
1028         mojo::AssociatedRemote<chrome::mojom::PluginAuthHost> plugin_auth_host;
1029         render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
1030             plugin_auth_host.BindNewEndpointAndPassReceiver());
1031         plugin_auth_host->BlockedUnauthorizedPlugin(group_name, identifier);
1032         content_settings_agent->DidBlockContentType(content_type);
1033         break;
1034       }
1035       case chrome::mojom::PluginStatus::kBlocked: {
1036         placeholder = create_blocked_plugin(
1037             IDR_BLOCKED_PLUGIN_HTML,
1038             l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name));
1039         placeholder->AllowLoading();
1040         RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Blocked"));
1041         content_settings_agent->DidBlockContentType(content_type);
1042         break;
1043       }
1044       case chrome::mojom::PluginStatus::kBlockedByPolicy: {
1045         placeholder = create_blocked_plugin(
1046             IDR_BLOCKED_PLUGIN_HTML,
1047             l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY,
1048                                        group_name));
1049         RenderThread::Get()->RecordAction(
1050             UserMetricsAction("Plugin_BlockedByPolicy"));
1051         content_settings_agent->DidBlockContentType(content_type);
1052         break;
1053       }
1054       case chrome::mojom::PluginStatus::kBlockedNoLoading: {
1055         placeholder = create_blocked_plugin(
1056             IDR_BLOCKED_PLUGIN_HTML,
1057             l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_NO_LOADING,
1058                                        group_name));
1059         content_settings_agent->DidBlockContentType(content_type);
1060         break;
1061       }
1062       case chrome::mojom::PluginStatus::kComponentUpdateRequired: {
1063         placeholder = create_blocked_plugin(
1064             IDR_BLOCKED_PLUGIN_HTML,
1065             l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name));
1066         placeholder->AllowLoading();
1067         mojo::AssociatedRemote<chrome::mojom::PluginHost> plugin_host;
1068         render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
1069             plugin_host.BindNewEndpointAndPassReceiver());
1070         plugin_host->BlockedComponentUpdatedPlugin(
1071             placeholder->BindPluginRenderer(), identifier);
1072         break;
1073       }
1074 
1075       case chrome::mojom::PluginStatus::kRestartRequired: {
1076 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
1077         placeholder =
1078             create_blocked_plugin(IDR_BLOCKED_PLUGIN_HTML,
1079                                   l10n_util::GetStringFUTF16(
1080                                       IDS_PLUGIN_RESTART_REQUIRED, group_name));
1081 #endif
1082         break;
1083       }
1084     }
1085   }
1086   placeholder->SetStatus(status);
1087   return placeholder->plugin();
1088 }
1089 #endif  // BUILDFLAG(ENABLE_PLUGINS)
1090 
1091 // For NaCl content handling plugins, the NaCl manifest is stored in an
1092 // additonal 'nacl' param associated with the MIME type.
1093 //  static
GetNaClContentHandlerURL(const std::string & actual_mime_type,const content::WebPluginInfo & plugin)1094 GURL ChromeContentRendererClient::GetNaClContentHandlerURL(
1095     const std::string& actual_mime_type,
1096     const content::WebPluginInfo& plugin) {
1097   // Look for the manifest URL among the MIME type's additonal parameters.
1098   const char kNaClPluginManifestAttribute[] = "nacl";
1099   base::string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute);
1100   for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
1101     if (plugin.mime_types[i].mime_type == actual_mime_type) {
1102       for (const auto& p : plugin.mime_types[i].additional_params) {
1103         if (p.name == nacl_attr)
1104           return GURL(p.value);
1105       }
1106       break;
1107     }
1108   }
1109   return GURL();
1110 }
1111 
GetInterface(const std::string & interface_name,mojo::ScopedMessagePipeHandle interface_pipe)1112 void ChromeContentRendererClient::GetInterface(
1113     const std::string& interface_name,
1114     mojo::ScopedMessagePipeHandle interface_pipe) {
1115   // TODO(crbug.com/977637): Get rid of the use of this implementation of
1116   // |service_manager::LocalInterfaceProvider|. This was done only to avoid
1117   // churning spellcheck code while eliminting the "chrome" and
1118   // "chrome_renderer" services. Spellcheck is (and should remain) the only
1119   // consumer of this implementation.
1120   RenderThread::Get()->BindHostReceiver(
1121       mojo::GenericPendingReceiver(interface_name, std::move(interface_pipe)));
1122 }
1123 
1124 #if BUILDFLAG(ENABLE_NACL)
1125 //  static
IsNativeNaClAllowed(const GURL & app_url,bool is_nacl_unrestricted,const Extension * extension)1126 bool ChromeContentRendererClient::IsNativeNaClAllowed(
1127     const GURL& app_url,
1128     bool is_nacl_unrestricted,
1129     const Extension* extension) {
1130   bool is_invoked_by_webstore_installed_extension = false;
1131   bool is_extension_unrestricted = false;
1132   bool is_extension_force_installed = false;
1133 #if BUILDFLAG(ENABLE_EXTENSIONS)
1134   bool is_extension_from_webstore = extension && extension->from_webstore();
1135 
1136   bool is_invoked_by_extension = app_url.SchemeIs(extensions::kExtensionScheme);
1137   bool is_invoked_by_hosted_app = extension && extension->is_hosted_app() &&
1138                                   extension->web_extent().MatchesURL(app_url);
1139 
1140   is_invoked_by_webstore_installed_extension =
1141       is_extension_from_webstore &&
1142       (is_invoked_by_extension || is_invoked_by_hosted_app);
1143 
1144   // Allow built-in extensions and developer mode extensions.
1145   is_extension_unrestricted =
1146       extension &&
1147       (extensions::Manifest::IsUnpackedLocation(extension->location()) ||
1148        extensions::Manifest::IsComponentLocation(extension->location()));
1149   // Allow extensions force installed by admin policy.
1150   is_extension_force_installed =
1151       extension &&
1152       extensions::Manifest::IsPolicyLocation(extension->location());
1153 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
1154 
1155   // Allow NaCl under any of the following circumstances:
1156   //  1) An extension is loaded unpacked or built-in (component) to Chrome.
1157   //  2) An extension is force installed by policy.
1158   //  3) An extension is installed from the webstore, and invoked in that
1159   //     context (hosted app URL or chrome-extension:// scheme).
1160   //  4) --enable-nacl is set.
1161   bool is_nacl_allowed_by_location = is_extension_unrestricted ||
1162                                      is_extension_force_installed ||
1163                                      is_invoked_by_webstore_installed_extension;
1164   bool is_nacl_allowed = is_nacl_allowed_by_location || is_nacl_unrestricted;
1165   return is_nacl_allowed;
1166 }
1167 
1168 // static
ReportNaClAppType(bool is_pnacl,bool is_extension_or_app,bool is_hosted_app)1169 void ChromeContentRendererClient::ReportNaClAppType(bool is_pnacl,
1170                                                     bool is_extension_or_app,
1171                                                     bool is_hosted_app) {
1172   // These values are persisted to logs. Entries should not be renumbered and
1173   // numeric values should never be reused.
1174   enum class NaClAppType {
1175     kPNaClOpenWeb = 0,
1176     kPNaClHostedApp = 1,
1177     kPNaClPackagedApp = 2,
1178     kNaClOpenWeb = 3,
1179     kNaClHostedApp = 4,
1180     kNaClPackagedApp = 5,
1181     kMaxValue = kNaClPackagedApp
1182   };
1183   // If it's not an extension/app, it can't be hosted.
1184   DCHECK(!is_hosted_app || is_extension_or_app);
1185   // Not all of the remaining combinations are allowed by default (e.g.
1186   // kNaClOpenWeb) but they can be used with the --enable-nacl flag.
1187   NaClAppType app_type =
1188       is_pnacl ? NaClAppType::kPNaClOpenWeb : NaClAppType::kNaClOpenWeb;
1189   if (is_extension_or_app) {
1190     if (is_pnacl) {
1191       app_type = is_hosted_app ? NaClAppType::kPNaClHostedApp
1192                                : NaClAppType::kPNaClPackagedApp;
1193     } else {
1194       app_type = is_hosted_app ? NaClAppType::kNaClHostedApp
1195                                : NaClAppType::kNaClPackagedApp;
1196     }
1197   }
1198   base::UmaHistogramEnumeration("NaCl.AppType", app_type);
1199 }
1200 #endif  // BUILDFLAG(ENABLE_NACL)
1201 
PrepareErrorPage(content::RenderFrame * render_frame,const blink::WebURLError & web_error,const std::string & http_method,std::string * error_html)1202 void ChromeContentRendererClient::PrepareErrorPage(
1203     content::RenderFrame* render_frame,
1204     const blink::WebURLError& web_error,
1205     const std::string& http_method,
1206     std::string* error_html) {
1207   NetErrorHelper::Get(render_frame)
1208       ->PrepareErrorPage(
1209           error_page::Error::NetError(web_error.url(), web_error.reason(),
1210                                       web_error.resolve_error_info(),
1211                                       web_error.has_copy_in_cache()),
1212           http_method == "POST", error_html);
1213 
1214 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
1215   SupervisedUserErrorPageControllerDelegateImpl::Get(render_frame)
1216       ->PrepareForErrorPage();
1217 #endif
1218 }
1219 
PrepareErrorPageForHttpStatusError(content::RenderFrame * render_frame,const blink::WebURLError & error,const std::string & http_method,int http_status,std::string * error_html)1220 void ChromeContentRendererClient::PrepareErrorPageForHttpStatusError(
1221     content::RenderFrame* render_frame,
1222     const blink::WebURLError& error,
1223     const std::string& http_method,
1224     int http_status,
1225     std::string* error_html) {
1226   NetErrorHelper::Get(render_frame)
1227       ->PrepareErrorPage(error_page::Error::HttpError(error.url(), http_status),
1228                          http_method == "POST", error_html);
1229 }
1230 
PostIOThreadCreated(base::SingleThreadTaskRunner * io_thread_task_runner)1231 void ChromeContentRendererClient::PostIOThreadCreated(
1232     base::SingleThreadTaskRunner* io_thread_task_runner) {
1233   io_thread_task_runner->PostTask(
1234       FROM_HERE, base::BindOnce(&ThreadProfiler::StartOnChildThread,
1235                                 metrics::CallStackProfileParams::IO_THREAD));
1236 }
1237 
PostCompositorThreadCreated(base::SingleThreadTaskRunner * compositor_thread_task_runner)1238 void ChromeContentRendererClient::PostCompositorThreadCreated(
1239     base::SingleThreadTaskRunner* compositor_thread_task_runner) {
1240   compositor_thread_task_runner->PostTask(
1241       FROM_HERE,
1242       base::BindOnce(&ThreadProfiler::StartOnChildThread,
1243                      metrics::CallStackProfileParams::COMPOSITOR_THREAD));
1244 }
1245 
RunIdleHandlerWhenWidgetsHidden()1246 bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
1247   return !IsStandaloneContentExtensionProcess();
1248 }
1249 
AllowPopup()1250 bool ChromeContentRendererClient::AllowPopup() {
1251 #if BUILDFLAG(ENABLE_EXTENSIONS)
1252   return ChromeExtensionsRendererClient::GetInstance()->AllowPopup();
1253 #else
1254   return false;
1255 #endif
1256 }
1257 
1258 blink::ProtocolHandlerSecurityLevel
GetProtocolHandlerSecurityLevel()1259 ChromeContentRendererClient::GetProtocolHandlerSecurityLevel() {
1260 #if BUILDFLAG(ENABLE_EXTENSIONS)
1261   return ChromeExtensionsRendererClient::GetInstance()
1262       ->GetProtocolHandlerSecurityLevel();
1263 #else
1264   return blink::ProtocolHandlerSecurityLevel::kStrict;
1265 #endif
1266 }
1267 
WillSendRequest(WebLocalFrame * frame,ui::PageTransition transition_type,const blink::WebURL & url,const net::SiteForCookies & site_for_cookies,const url::Origin * initiator_origin,GURL * new_url,bool * force_ignore_site_for_cookies)1268 void ChromeContentRendererClient::WillSendRequest(
1269     WebLocalFrame* frame,
1270     ui::PageTransition transition_type,
1271     const blink::WebURL& url,
1272     const net::SiteForCookies& site_for_cookies,
1273     const url::Origin* initiator_origin,
1274     GURL* new_url,
1275     bool* force_ignore_site_for_cookies) {
1276 // Check whether the request should be allowed. If not allowed, we reset the
1277 // URL to something invalid to prevent the request and cause an error.
1278 #if BUILDFLAG(ENABLE_EXTENSIONS)
1279   ChromeExtensionsRendererClient::GetInstance()->WillSendRequest(
1280       frame, transition_type, url, site_for_cookies, initiator_origin, new_url,
1281       force_ignore_site_for_cookies);
1282   if (!new_url->is_empty())
1283     return;
1284 #endif
1285 
1286   if (!url.ProtocolIs(chrome::kChromeSearchScheme))
1287     return;
1288 
1289 #if !defined(OS_ANDROID)
1290   SearchBox* search_box =
1291       SearchBox::Get(content::RenderFrame::FromWebFrame(frame->LocalRoot()));
1292   if (search_box) {
1293     // Note: this GURL copy could be avoided if host() were added to WebURL.
1294     GURL gurl(url);
1295     if (gurl.host_piece() == chrome::kChromeUIFaviconHost)
1296       search_box->GenerateImageURLFromTransientURL(url, new_url);
1297   }
1298 #endif  // !defined(OS_ANDROID)
1299 }
1300 
IsPrefetchOnly(content::RenderFrame * render_frame,const blink::WebURLRequest & request)1301 bool ChromeContentRendererClient::IsPrefetchOnly(
1302     content::RenderFrame* render_frame,
1303     const blink::WebURLRequest& request) {
1304   return prerender::PrerenderHelper::GetPrerenderMode(render_frame) ==
1305          prerender::mojom::PrerenderMode::kPrefetchOnly;
1306 }
1307 
VisitedLinkHash(const char * canonical_url,size_t length)1308 uint64_t ChromeContentRendererClient::VisitedLinkHash(const char* canonical_url,
1309                                                       size_t length) {
1310   return chrome_observer_->visited_link_reader()->ComputeURLFingerprint(
1311       canonical_url, length);
1312 }
1313 
IsLinkVisited(uint64_t link_hash)1314 bool ChromeContentRendererClient::IsLinkVisited(uint64_t link_hash) {
1315   return chrome_observer_->visited_link_reader()->IsVisited(link_hash);
1316 }
1317 
1318 std::unique_ptr<blink::WebPrescientNetworking>
CreatePrescientNetworking(content::RenderFrame * render_frame)1319 ChromeContentRendererClient::CreatePrescientNetworking(
1320     content::RenderFrame* render_frame) {
1321   return std::make_unique<network_hints::WebPrescientNetworkingImpl>(
1322       render_frame);
1323 }
1324 
IsExternalPepperPlugin(const std::string & module_name)1325 bool ChromeContentRendererClient::IsExternalPepperPlugin(
1326     const std::string& module_name) {
1327   // TODO(bbudge) remove this when the trusted NaCl plugin has been removed.
1328   // We must defer certain plugin events for NaCl instances since we switch
1329   // from the in-process to the out-of-process proxy after instantiating them.
1330   return module_name == "Native Client";
1331 }
1332 
IsOriginIsolatedPepperPlugin(const base::FilePath & plugin_path)1333 bool ChromeContentRendererClient::IsOriginIsolatedPepperPlugin(
1334     const base::FilePath& plugin_path) {
1335   return plugin_path.value() == ChromeContentClient::kPDFPluginPath;
1336 }
1337 
1338 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
IsExtensionOrSharedModuleWhitelisted(const GURL & url,const std::set<std::string> & whitelist)1339 bool ChromeContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
1340     const GURL& url,
1341     const std::set<std::string>& whitelist) {
1342   const extensions::ExtensionSet* extension_set =
1343       extensions::RendererExtensionRegistry::Get()->GetMainThreadExtensionSet();
1344   return ::IsExtensionOrSharedModuleWhitelisted(url, extension_set, whitelist);
1345 }
1346 #endif
1347 
1348 #if BUILDFLAG(ENABLE_SPELLCHECK)
InitSpellCheck()1349 void ChromeContentRendererClient::InitSpellCheck() {
1350   spellcheck_ = std::make_unique<SpellCheck>(this);
1351 }
1352 #endif
1353 
GetChromeObserver() const1354 ChromeRenderThreadObserver* ChromeContentRendererClient::GetChromeObserver()
1355     const {
1356   return chrome_observer_.get();
1357 }
1358 
GetWebCache()1359 web_cache::WebCacheImpl* ChromeContentRendererClient::GetWebCache() {
1360   return web_cache_impl_.get();
1361 }
1362 
1363 chrome::WebRtcLoggingAgentImpl*
GetWebRtcLoggingAgent()1364 ChromeContentRendererClient::GetWebRtcLoggingAgent() {
1365   if (!webrtc_logging_agent_impl_) {
1366     webrtc_logging_agent_impl_ =
1367         std::make_unique<chrome::WebRtcLoggingAgentImpl>();
1368   }
1369   return webrtc_logging_agent_impl_.get();
1370 }
1371 
1372 #if BUILDFLAG(ENABLE_SPELLCHECK)
GetSpellCheck()1373 SpellCheck* ChromeContentRendererClient::GetSpellCheck() {
1374   return spellcheck_.get();
1375 }
1376 #endif  // BUILDFLAG(ENABLE_SPELLCHECK)
1377 
1378 std::unique_ptr<content::WebSocketHandshakeThrottleProvider>
CreateWebSocketHandshakeThrottleProvider()1379 ChromeContentRendererClient::CreateWebSocketHandshakeThrottleProvider() {
1380   return std::make_unique<WebSocketHandshakeThrottleProviderImpl>(
1381       browser_interface_broker_.get());
1382 }
1383 
AddSupportedKeySystems(std::vector<std::unique_ptr<::media::KeySystemProperties>> * key_systems)1384 void ChromeContentRendererClient::AddSupportedKeySystems(
1385     std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
1386   key_systems_provider_.AddSupportedKeySystems(key_systems);
1387 }
1388 
IsKeySystemsUpdateNeeded()1389 bool ChromeContentRendererClient::IsKeySystemsUpdateNeeded() {
1390   return key_systems_provider_.IsKeySystemsUpdateNeeded();
1391 }
1392 
ShouldReportDetailedMessageForSource(const base::string16 & source)1393 bool ChromeContentRendererClient::ShouldReportDetailedMessageForSource(
1394     const base::string16& source) {
1395 #if BUILDFLAG(ENABLE_EXTENSIONS)
1396   return extensions::IsSourceFromAnExtension(source);
1397 #else
1398   return false;
1399 #endif
1400 }
1401 
1402 std::unique_ptr<blink::WebContentSettingsClient>
CreateWorkerContentSettingsClient(content::RenderFrame * render_frame)1403 ChromeContentRendererClient::CreateWorkerContentSettingsClient(
1404     content::RenderFrame* render_frame) {
1405   return std::make_unique<WorkerContentSettingsClient>(render_frame);
1406 }
1407 
1408 #if !defined(OS_ANDROID)
1409 std::unique_ptr<media::SpeechRecognitionClient>
CreateSpeechRecognitionClient(content::RenderFrame * render_frame,media::SpeechRecognitionClient::OnReadyCallback callback)1410 ChromeContentRendererClient::CreateSpeechRecognitionClient(
1411     content::RenderFrame* render_frame,
1412     media::SpeechRecognitionClient::OnReadyCallback callback) {
1413   return std::make_unique<ChromeSpeechRecognitionClient>(render_frame,
1414                                                          std::move(callback));
1415 }
1416 #endif
1417 
IsPluginAllowedToUseCameraDeviceAPI(const GURL & url)1418 bool ChromeContentRendererClient::IsPluginAllowedToUseCameraDeviceAPI(
1419     const GURL& url) {
1420 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
1421   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1422           switches::kEnablePepperTesting))
1423     return true;
1424 
1425   if (IsExtensionOrSharedModuleWhitelisted(url, allowed_camera_device_origins_))
1426     return true;
1427 #endif
1428 
1429   return false;
1430 }
1431 
RunScriptsAtDocumentStart(content::RenderFrame * render_frame)1432 void ChromeContentRendererClient::RunScriptsAtDocumentStart(
1433     content::RenderFrame* render_frame) {
1434 #if BUILDFLAG(ENABLE_EXTENSIONS)
1435   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentStart(
1436       render_frame);
1437   // |render_frame| might be dead by now.
1438 #endif
1439 }
1440 
RunScriptsAtDocumentEnd(content::RenderFrame * render_frame)1441 void ChromeContentRendererClient::RunScriptsAtDocumentEnd(
1442     content::RenderFrame* render_frame) {
1443 #if BUILDFLAG(ENABLE_EXTENSIONS)
1444   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentEnd(
1445       render_frame);
1446   // |render_frame| might be dead by now.
1447 #endif
1448 }
1449 
RunScriptsAtDocumentIdle(content::RenderFrame * render_frame)1450 void ChromeContentRendererClient::RunScriptsAtDocumentIdle(
1451     content::RenderFrame* render_frame) {
1452 #if BUILDFLAG(ENABLE_EXTENSIONS)
1453   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentIdle(
1454       render_frame);
1455   // |render_frame| might be dead by now.
1456 #endif
1457 }
1458 
1459 void ChromeContentRendererClient::
SetRuntimeFeaturesDefaultsBeforeBlinkInitialization()1460     SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
1461   // The performance manager service interfaces are provided by the chrome
1462   // embedder only.
1463   blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true);
1464 
1465   // Web Share is conditionally enabled here in chrome/, to avoid it being
1466   // made available in other clients of content/ that do not have a Web Share
1467   // Mojo implementation (e.g. WebView).  Web Share is shipped on Android.
1468 #if defined(OS_CHROMEOS) || defined(OS_WIN)
1469   if (base::FeatureList::IsEnabled(features::kWebShare))
1470 #endif
1471 #if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_ANDROID)
1472     blink::WebRuntimeFeatures::EnableWebShare(true);
1473 #endif
1474 
1475   if (base::FeatureList::IsEnabled(subresource_filter::kAdTagging))
1476     blink::WebRuntimeFeatures::EnableAdTagging(true);
1477 }
1478 
AllowScriptExtensionForServiceWorker(const url::Origin & script_origin)1479 bool ChromeContentRendererClient::AllowScriptExtensionForServiceWorker(
1480     const url::Origin& script_origin) {
1481 #if BUILDFLAG(ENABLE_EXTENSIONS)
1482   return script_origin.scheme() == extensions::kExtensionScheme;
1483 #else
1484   return false;
1485 #endif
1486 }
1487 
1488 void ChromeContentRendererClient::
WillInitializeServiceWorkerContextOnWorkerThread()1489     WillInitializeServiceWorkerContextOnWorkerThread() {
1490   // This is called on the service worker thread.
1491   ThreadProfiler::StartOnChildThread(
1492       metrics::CallStackProfileParams::SERVICE_WORKER_THREAD);
1493 }
1494 
1495 void ChromeContentRendererClient::
DidInitializeServiceWorkerContextOnWorkerThread(blink::WebServiceWorkerContextProxy * context_proxy,const GURL & service_worker_scope,const GURL & script_url)1496     DidInitializeServiceWorkerContextOnWorkerThread(
1497         blink::WebServiceWorkerContextProxy* context_proxy,
1498         const GURL& service_worker_scope,
1499         const GURL& script_url) {
1500 #if BUILDFLAG(ENABLE_EXTENSIONS)
1501   ChromeExtensionsRendererClient::GetInstance()
1502       ->extension_dispatcher()
1503       ->DidInitializeServiceWorkerContextOnWorkerThread(
1504           context_proxy, service_worker_scope, script_url);
1505 #endif
1506 }
1507 
WillEvaluateServiceWorkerOnWorkerThread(blink::WebServiceWorkerContextProxy * context_proxy,v8::Local<v8::Context> v8_context,int64_t service_worker_version_id,const GURL & service_worker_scope,const GURL & script_url)1508 void ChromeContentRendererClient::WillEvaluateServiceWorkerOnWorkerThread(
1509     blink::WebServiceWorkerContextProxy* context_proxy,
1510     v8::Local<v8::Context> v8_context,
1511     int64_t service_worker_version_id,
1512     const GURL& service_worker_scope,
1513     const GURL& script_url) {
1514 #if BUILDFLAG(ENABLE_EXTENSIONS)
1515   ChromeExtensionsRendererClient::GetInstance()
1516       ->extension_dispatcher()
1517       ->WillEvaluateServiceWorkerOnWorkerThread(
1518           context_proxy, v8_context, service_worker_version_id,
1519           service_worker_scope, script_url);
1520 #endif
1521 }
1522 
DidStartServiceWorkerContextOnWorkerThread(int64_t service_worker_version_id,const GURL & service_worker_scope,const GURL & script_url)1523 void ChromeContentRendererClient::DidStartServiceWorkerContextOnWorkerThread(
1524     int64_t service_worker_version_id,
1525     const GURL& service_worker_scope,
1526     const GURL& script_url) {
1527 #if BUILDFLAG(ENABLE_EXTENSIONS)
1528   ChromeExtensionsRendererClient::GetInstance()
1529       ->extension_dispatcher()
1530       ->DidStartServiceWorkerContextOnWorkerThread(
1531           service_worker_version_id, service_worker_scope, script_url);
1532 #endif
1533 }
1534 
WillDestroyServiceWorkerContextOnWorkerThread(v8::Local<v8::Context> context,int64_t service_worker_version_id,const GURL & service_worker_scope,const GURL & script_url)1535 void ChromeContentRendererClient::WillDestroyServiceWorkerContextOnWorkerThread(
1536     v8::Local<v8::Context> context,
1537     int64_t service_worker_version_id,
1538     const GURL& service_worker_scope,
1539     const GURL& script_url) {
1540 #if BUILDFLAG(ENABLE_EXTENSIONS)
1541   ChromeExtensionsRendererClient::GetInstance()
1542       ->extension_dispatcher()
1543       ->WillDestroyServiceWorkerContextOnWorkerThread(
1544           context, service_worker_version_id, service_worker_scope, script_url);
1545 #endif
1546 }
1547 
IsExcludedHeaderForServiceWorkerFetchEvent(const std::string & header_name)1548 bool ChromeContentRendererClient::IsExcludedHeaderForServiceWorkerFetchEvent(
1549     const std::string& header_name) {
1550   return variations::IsVariationsHeader(header_name);
1551 }
1552 
1553 // If we're in an extension, there is no need disabling multiple routes as
1554 // chrome.system.network.getNetworkInterfaces provides the same
1555 // information. Also, the enforcement of sending and binding UDP is already done
1556 // by chrome extension permission model.
ShouldEnforceWebRTCRoutingPreferences()1557 bool ChromeContentRendererClient::ShouldEnforceWebRTCRoutingPreferences() {
1558   return !IsStandaloneContentExtensionProcess();
1559 }
1560 
OverrideFlashEmbedWithHTML(const GURL & url)1561 GURL ChromeContentRendererClient::OverrideFlashEmbedWithHTML(const GURL& url) {
1562   if (!url.is_valid())
1563     return GURL();
1564 
1565   return FlashEmbedRewrite::RewriteFlashEmbedURL(url);
1566 }
1567 
1568 std::unique_ptr<content::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(content::URLLoaderThrottleProviderType provider_type)1569 ChromeContentRendererClient::CreateURLLoaderThrottleProvider(
1570     content::URLLoaderThrottleProviderType provider_type) {
1571   return std::make_unique<URLLoaderThrottleProviderImpl>(
1572       browser_interface_broker_.get(), provider_type, this);
1573 }
1574 
FindFrame(blink::WebLocalFrame * relative_to_frame,const std::string & name)1575 blink::WebFrame* ChromeContentRendererClient::FindFrame(
1576     blink::WebLocalFrame* relative_to_frame,
1577     const std::string& name) {
1578 #if BUILDFLAG(ENABLE_EXTENSIONS)
1579   return ChromeExtensionsRendererClient::FindFrame(relative_to_frame, name);
1580 #else
1581   return nullptr;
1582 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
1583 }
1584 
IsSafeRedirectTarget(const GURL & url)1585 bool ChromeContentRendererClient::IsSafeRedirectTarget(const GURL& url) {
1586 #if BUILDFLAG(ENABLE_EXTENSIONS)
1587   if (url.SchemeIs(extensions::kExtensionScheme)) {
1588     const extensions::Extension* extension =
1589         extensions::RendererExtensionRegistry::Get()->GetByID(url.host());
1590     if (!extension)
1591       return false;
1592     return extensions::WebAccessibleResourcesInfo::IsResourceWebAccessible(
1593         extension, url.path());
1594   }
1595 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
1596   return true;
1597 }
1598 
DidSetUserAgent(const std::string & user_agent)1599 void ChromeContentRendererClient::DidSetUserAgent(
1600     const std::string& user_agent) {
1601 #if BUILDFLAG(ENABLE_PRINTING)
1602   printing::SetAgent(user_agent);
1603 #endif
1604 }
1605 
RequiresHtmlImports(const GURL & url)1606 bool ChromeContentRendererClient::RequiresHtmlImports(const GURL& url) {
1607   if (url.SchemeIs(content::kChromeUIScheme)) {
1608     base::StringPiece host_piece = url.host_piece();
1609     // TODO(crbug.com/1014322): Remove when migrated to Polymer3.
1610     return host_piece == chrome::kChromeUIMdUserManagerHost ||
1611            host_piece == content::kChromeUIResourcesHost ||
1612            // TODO(crbug.com/1006778): Remove when chrome://tracing is fully
1613            // removed.
1614            host_piece == content::kChromeUITracingHost ||
1615            // TODO(crbug.com/1110954): Remove when migrated away from HTML
1616            // imports.
1617            host_piece == chrome::kChromeUIBluetoothInternalsHost ||
1618 #if defined(OS_CHROMEOS)
1619            // TODO(crbug.com/1111430): Remove when migrated to Polymer3.
1620            host_piece == chrome::kChromeUIAccountManagerErrorHost ||
1621            host_piece == chrome::kChromeUIAccountManagerWelcomeHost ||
1622            host_piece == chrome::kChromeUIAccountMigrationWelcomeHost ||
1623            // TODO(crbug.com/1111430): Remove when migrated to Polymer3.
1624            host_piece == chrome::kChromeUIAddSupervisionHost ||
1625            // TODO(crbug.com/1111849): Remove when migrated to Polymer3.
1626            host_piece == chrome::kChromeUIAssistantOptInHost ||
1627            // TODO(crbug.com/1111477): Remove when migrated to Polymer3.
1628            host_piece == chrome::kChromeUICellularSetupHost ||
1629            // TODO(crbug.com/1090884): Remove when migrated to Polymer3.
1630            host_piece == chrome::kChromeUIInternetConfigDialogHost ||
1631            // TODO(crbug.com/1090883): Remove when migrated to Polymer3.
1632            host_piece == chrome::kChromeUIInternetDetailDialogHost ||
1633            // TODO(crbug.com/1022196): Remove when migrated to Polymer3.
1634            host_piece == chrome::kChromeUIMultiDeviceSetupHost ||
1635            // TODO(crbug.com/1111852): Remove when migrated to Polymer3.
1636            host_piece == chrome::kChromeUINetworkHost ||
1637            // TODO(crbug.com/1111387): Remove when migrated away from HTML
1638            // Imports.
1639            host_piece == chrome::kChromeUIOobeHost ||
1640            // TODO(crbug.com/1045266): Remove when migrated to Polymer3.
1641            host_piece == chrome::kChromeUIOSSettingsHost ||
1642            // TODO(crbug.com/1022192): Remove when migrated to Polymer3.
1643            host_piece == chrome::kChromeUIPasswordChangeHost ||
1644 #endif
1645            false;
1646   }
1647   return false;
1648 }
1649 
1650 // When extension is not available, we don't need to proxy the URLLoaderFactory.
1651 #if BUILDFLAG(ENABLE_EXTENSIONS)
MaybeProxyURLLoaderFactory(content::RenderFrame * render_frame,mojo::PendingReceiver<network::mojom::URLLoaderFactory> * factory_receiver)1652 void ChromeContentRendererClient::MaybeProxyURLLoaderFactory(
1653     content::RenderFrame* render_frame,
1654     mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver) {
1655   mojo::PendingRemote<network::mojom::URLLoaderFactory> original_factory;
1656   mojo::PendingReceiver<::network::mojom::URLLoaderFactory> proxied_factory(
1657       std::move(*factory_receiver));
1658   *factory_receiver = original_factory.InitWithNewPipeAndPassReceiver();
1659   mojo::Remote<chrome::mojom::UrlLoaderFactoryProxy> url_loader_factory_proxy;
1660   render_frame->GetBrowserInterfaceBroker()->GetInterface(
1661       url_loader_factory_proxy.BindNewPipeAndPassReceiver());
1662   url_loader_factory_proxy->GetProxiedURLLoaderFactory(
1663       std::move(original_factory), std::move(proxied_factory));
1664 }
1665 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
1666