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 "libcef/browser/alloy/alloy_content_browser_client.h"
6
7 #include <algorithm>
8 #include <tuple>
9 #include <utility>
10
11 #include "include/cef_version.h"
12 #include "libcef/browser/alloy/alloy_browser_context.h"
13 #include "libcef/browser/alloy/alloy_browser_host_impl.h"
14 #include "libcef/browser/alloy/alloy_browser_main.h"
15 #include "libcef/browser/browser_context.h"
16 #include "libcef/browser/browser_frame.h"
17 #include "libcef/browser/browser_info.h"
18 #include "libcef/browser/browser_info_manager.h"
19 #include "libcef/browser/browser_manager.h"
20 #include "libcef/browser/browser_platform_delegate.h"
21 #include "libcef/browser/context.h"
22 #include "libcef/browser/devtools/devtools_manager_delegate.h"
23 #include "libcef/browser/extensions/extension_system.h"
24 #include "libcef/browser/extensions/extension_web_contents_observer.h"
25 #include "libcef/browser/media_capture_devices_dispatcher.h"
26 #include "libcef/browser/net/chrome_scheme_handler.h"
27 #include "libcef/browser/net/throttle_handler.h"
28 #include "libcef/browser/net_service/cookie_manager_impl.h"
29 #include "libcef/browser/net_service/login_delegate.h"
30 #include "libcef/browser/net_service/proxy_url_loader_factory.h"
31 #include "libcef/browser/net_service/resource_request_handler_wrapper.h"
32 #include "libcef/browser/prefs/renderer_prefs.h"
33 #include "libcef/browser/printing/print_view_manager.h"
34 #include "libcef/browser/speech_recognition_manager_delegate.h"
35 #include "libcef/browser/ssl_info_impl.h"
36 #include "libcef/browser/thread_util.h"
37 #include "libcef/browser/x509_certificate_impl.h"
38 #include "libcef/common/alloy/alloy_content_client.h"
39 #include "libcef/common/app_manager.h"
40 #include "libcef/common/cef_switches.h"
41 #include "libcef/common/command_line_impl.h"
42 #include "libcef/common/extensions/extensions_util.h"
43 #include "libcef/common/frame_util.h"
44 #include "libcef/common/net/scheme_registration.h"
45 #include "libcef/common/request_impl.h"
46
47 #include "base/base_switches.h"
48 #include "base/command_line.h"
49 #include "base/files/file_path.h"
50 #include "base/json/json_reader.h"
51 #include "base/path_service.h"
52 #include "base/stl_util.h"
53 #include "base/threading/thread_restrictions.h"
54 #include "cef/grit/cef_resources.h"
55 #include "chrome/browser/browser_process.h"
56 #include "chrome/browser/content_settings/cookie_settings_factory.h"
57 #include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
58 #include "chrome/browser/net/profile_network_context_service.h"
59 #include "chrome/browser/net/profile_network_context_service_factory.h"
60 #include "chrome/browser/net/system_network_context_manager.h"
61 #include "chrome/browser/pdf/chrome_pdf_stream_delegate.h"
62 #include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"
63 #include "chrome/browser/plugins/plugin_info_host_impl.h"
64 #include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h"
65 #include "chrome/browser/plugins/plugin_utils.h"
66 #include "chrome/browser/profiles/profile.h"
67 #include "chrome/browser/profiles/renderer_updater.h"
68 #include "chrome/browser/profiles/renderer_updater_factory.h"
69 #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
70 #include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
71 #include "chrome/common/chrome_content_client.h"
72 #include "chrome/common/chrome_paths.h"
73 #include "chrome/common/chrome_switches.h"
74 #include "chrome/common/google_url_loader_throttle.h"
75 #include "chrome/common/pdf_util.h"
76 #include "chrome/common/pref_names.h"
77 #include "chrome/common/webui_url_constants.h"
78 #include "chrome/grit/browser_resources.h"
79 #include "chrome/grit/generated_resources.h"
80 #include "chrome/services/printing/printing_service.h"
81 #include "components/content_settings/core/browser/cookie_settings.h"
82 #include "components/embedder_support/switches.h"
83 #include "components/embedder_support/user_agent_utils.h"
84 #include "components/pdf/browser/pdf_navigation_throttle.h"
85 #include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
86 #include "components/pdf/browser/pdf_web_contents_helper.h"
87 #include "components/pdf/common/internal_plugin_helpers.h"
88 #include "components/spellcheck/common/spellcheck.mojom.h"
89 #include "components/version_info/version_info.h"
90 #include "content/browser/plugin_service_impl.h"
91 #include "content/browser/renderer_host/render_frame_host_impl.h"
92 #include "content/public/browser/browser_context.h"
93 #include "content/public/browser/browser_ppapi_host.h"
94 #include "content/public/browser/browser_thread.h"
95 #include "content/public/browser/client_certificate_delegate.h"
96 #include "content/public/browser/navigation_handle.h"
97 #include "content/public/browser/overlay_window.h"
98 #include "content/public/browser/page_navigator.h"
99 #include "content/public/browser/quota_permission_context.h"
100 #include "content/public/browser/render_frame_host.h"
101 #include "content/public/browser/render_process_host.h"
102 #include "content/public/browser/render_view_host.h"
103 #include "content/public/browser/render_widget_host.h"
104 #include "content/public/browser/render_widget_host_view.h"
105 #include "content/public/browser/storage_partition.h"
106 #include "content/public/browser/web_ui_url_loader_factory.h"
107 #include "content/public/common/content_switches.h"
108 #include "content/public/common/storage_quota_params.h"
109 #include "content/public/common/url_constants.h"
110 #include "content/public/common/user_agent.h"
111 #include "crypto/crypto_buildflags.h"
112 #include "extensions/browser/event_router.h"
113 #include "extensions/browser/extension_message_filter.h"
114 #include "extensions/browser/extension_protocols.h"
115 #include "extensions/browser/extension_registry.h"
116 #include "extensions/browser/extension_web_contents_observer.h"
117 #include "extensions/browser/extensions_browser_client.h"
118 #include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
119 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
120 #include "extensions/browser/info_map.h"
121 #include "extensions/browser/process_map.h"
122 #include "extensions/browser/url_loader_factory_manager.h"
123 #include "extensions/common/constants.h"
124 #include "extensions/common/switches.h"
125 #include "mojo/public/cpp/bindings/remote.h"
126 #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
127 #include "net/base/auth.h"
128 #include "net/ssl/ssl_cert_request_info.h"
129 #include "net/ssl/ssl_private_key.h"
130 #include "pdf/pdf_features.h"
131 #include "ppapi/host/ppapi_host.h"
132 #include "sandbox/policy/switches.h"
133 #include "services/network/public/cpp/network_switches.h"
134 #include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
135 #include "services/service_manager/public/mojom/connector.mojom.h"
136 #include "storage/browser/quota/quota_settings.h"
137 #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
138 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
139 #include "third_party/blink/public/mojom/prerender/prerender.mojom.h"
140 #include "third_party/blink/public/web/web_window_features.h"
141 #include "ui/base/l10n/l10n_util.h"
142 #include "ui/base/resource/resource_bundle.h"
143 #include "ui/base/ui_base_switches.h"
144 #include "url/gurl.h"
145
146 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
147 #include "base/debug/leak_annotations.h"
148 #include "chrome/common/chrome_paths.h"
149 #include "components/crash/content/browser/crash_handler_host_linux.h"
150 #include "components/crash/core/app/breakpad_linux.h"
151 #include "content/public/common/content_descriptors.h"
152 #endif
153
154 #if BUILDFLAG(IS_MAC)
155 #include "net/ssl/client_cert_store_mac.h"
156 #include "services/video_capture/public/mojom/constants.mojom.h"
157 #endif
158
159 #if BUILDFLAG(IS_WIN)
160 #include "net/ssl/client_cert_store_win.h"
161 #include "sandbox/win/src/sandbox_policy.h"
162 #endif
163
164 #if BUILDFLAG(USE_NSS_CERTS)
165 #include "net/ssl/client_cert_store_nss.h"
166 #endif
167
168 #if BUILDFLAG(HAS_SPELLCHECK_PANEL)
169 #include "chrome/browser/spellchecker/spell_check_panel_host_impl.h"
170 #endif
171
172 namespace {
173
174 class CefQuotaCallbackImpl : public CefCallback {
175 public:
176 using CallbackType = content::QuotaPermissionContext::PermissionCallback;
177
CefQuotaCallbackImpl(CallbackType callback)178 explicit CefQuotaCallbackImpl(CallbackType callback)
179 : callback_(std::move(callback)) {}
180
181 CefQuotaCallbackImpl(const CefQuotaCallbackImpl&) = delete;
182 CefQuotaCallbackImpl& operator=(const CefQuotaCallbackImpl&) = delete;
183
~CefQuotaCallbackImpl()184 ~CefQuotaCallbackImpl() {
185 if (!callback_.is_null()) {
186 // The callback is still pending. Cancel it now.
187 if (CEF_CURRENTLY_ON_IOT()) {
188 RunNow(std::move(callback_), false);
189 } else {
190 CEF_POST_TASK(CEF_IOT, base::BindOnce(&CefQuotaCallbackImpl::RunNow,
191 std::move(callback_), false));
192 }
193 }
194 }
195
Continue()196 void Continue() override { ContinueNow(true); }
197
Cancel()198 void Cancel() override { ContinueNow(false); }
199
Disconnect()200 CallbackType Disconnect() WARN_UNUSED_RESULT { return std::move(callback_); }
201
202 private:
ContinueNow(bool allow)203 void ContinueNow(bool allow) {
204 if (CEF_CURRENTLY_ON_IOT()) {
205 if (!callback_.is_null()) {
206 RunNow(std::move(callback_), allow);
207 }
208 } else {
209 CEF_POST_TASK(CEF_IOT, base::BindOnce(&CefQuotaCallbackImpl::ContinueNow,
210 this, allow));
211 }
212 }
213
RunNow(CallbackType callback,bool allow)214 static void RunNow(CallbackType callback, bool allow) {
215 CEF_REQUIRE_IOT();
216 std::move(callback).Run(
217 allow ? content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
218 : content::QuotaPermissionContext::
219 QUOTA_PERMISSION_RESPONSE_DISALLOW);
220 }
221
222 CallbackType callback_;
223
224 IMPLEMENT_REFCOUNTING(CefQuotaCallbackImpl);
225 };
226
227 class CefAllowCertificateErrorCallbackImpl : public CefCallback {
228 public:
229 using CallbackType =
230 base::OnceCallback<void(content::CertificateRequestResultType)>;
231
CefAllowCertificateErrorCallbackImpl(CallbackType callback)232 explicit CefAllowCertificateErrorCallbackImpl(CallbackType callback)
233 : callback_(std::move(callback)) {}
234
235 CefAllowCertificateErrorCallbackImpl(
236 const CefAllowCertificateErrorCallbackImpl&) = delete;
237 CefAllowCertificateErrorCallbackImpl& operator=(
238 const CefAllowCertificateErrorCallbackImpl&) = delete;
239
~CefAllowCertificateErrorCallbackImpl()240 ~CefAllowCertificateErrorCallbackImpl() {
241 if (!callback_.is_null()) {
242 // The callback is still pending. Cancel it now.
243 if (CEF_CURRENTLY_ON_UIT()) {
244 RunNow(std::move(callback_), false);
245 } else {
246 CEF_POST_TASK(
247 CEF_UIT,
248 base::BindOnce(&CefAllowCertificateErrorCallbackImpl::RunNow,
249 std::move(callback_), false));
250 }
251 }
252 }
253
Continue()254 void Continue() override { ContinueNow(true); }
255
Cancel()256 void Cancel() override { ContinueNow(false); }
257
Disconnect()258 CallbackType Disconnect() WARN_UNUSED_RESULT { return std::move(callback_); }
259
260 private:
ContinueNow(bool allow)261 void ContinueNow(bool allow) {
262 if (CEF_CURRENTLY_ON_UIT()) {
263 if (!callback_.is_null()) {
264 RunNow(std::move(callback_), allow);
265 }
266 } else {
267 CEF_POST_TASK(
268 CEF_UIT,
269 base::BindOnce(&CefAllowCertificateErrorCallbackImpl::ContinueNow,
270 this, allow));
271 }
272 }
273
RunNow(CallbackType callback,bool allow)274 static void RunNow(CallbackType callback, bool allow) {
275 CEF_REQUIRE_UIT();
276 std::move(callback).Run(
277 allow ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE
278 : content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
279 }
280
281 CallbackType callback_;
282
283 IMPLEMENT_REFCOUNTING(CefAllowCertificateErrorCallbackImpl);
284 };
285
286 class CefSelectClientCertificateCallbackImpl
287 : public CefSelectClientCertificateCallback {
288 public:
CefSelectClientCertificateCallbackImpl(std::unique_ptr<content::ClientCertificateDelegate> delegate)289 explicit CefSelectClientCertificateCallbackImpl(
290 std::unique_ptr<content::ClientCertificateDelegate> delegate)
291 : delegate_(std::move(delegate)) {}
292
293 CefSelectClientCertificateCallbackImpl(
294 const CefSelectClientCertificateCallbackImpl&) = delete;
295 CefSelectClientCertificateCallbackImpl& operator=(
296 const CefSelectClientCertificateCallbackImpl&) = delete;
297
~CefSelectClientCertificateCallbackImpl()298 ~CefSelectClientCertificateCallbackImpl() {
299 // If Select has not been called, call it with NULL to continue without any
300 // client certificate.
301 if (delegate_)
302 DoSelect(nullptr);
303 }
304
Select(CefRefPtr<CefX509Certificate> cert)305 void Select(CefRefPtr<CefX509Certificate> cert) override {
306 if (delegate_)
307 DoSelect(cert);
308 }
309
310 private:
DoSelect(CefRefPtr<CefX509Certificate> cert)311 void DoSelect(CefRefPtr<CefX509Certificate> cert) {
312 if (CEF_CURRENTLY_ON_UIT()) {
313 RunNow(std::move(delegate_), cert);
314 } else {
315 CEF_POST_TASK(
316 CEF_UIT,
317 base::BindOnce(&CefSelectClientCertificateCallbackImpl::RunNow,
318 std::move(delegate_), cert));
319 }
320 }
321
RunNow(std::unique_ptr<content::ClientCertificateDelegate> delegate,CefRefPtr<CefX509Certificate> cert)322 static void RunNow(
323 std::unique_ptr<content::ClientCertificateDelegate> delegate,
324 CefRefPtr<CefX509Certificate> cert) {
325 CEF_REQUIRE_UIT();
326
327 if (cert) {
328 CefX509CertificateImpl* certImpl =
329 static_cast<CefX509CertificateImpl*>(cert.get());
330 certImpl->AcquirePrivateKey(base::BindOnce(
331 &CefSelectClientCertificateCallbackImpl::RunWithPrivateKey,
332 std::move(delegate), cert));
333 return;
334 }
335
336 delegate->ContinueWithCertificate(nullptr, nullptr);
337 }
338
RunWithPrivateKey(std::unique_ptr<content::ClientCertificateDelegate> delegate,CefRefPtr<CefX509Certificate> cert,scoped_refptr<net::SSLPrivateKey> key)339 static void RunWithPrivateKey(
340 std::unique_ptr<content::ClientCertificateDelegate> delegate,
341 CefRefPtr<CefX509Certificate> cert,
342 scoped_refptr<net::SSLPrivateKey> key) {
343 CEF_REQUIRE_UIT();
344 DCHECK(cert);
345
346 if (key) {
347 CefX509CertificateImpl* certImpl =
348 static_cast<CefX509CertificateImpl*>(cert.get());
349 delegate->ContinueWithCertificate(certImpl->GetInternalCertObject(), key);
350 } else {
351 delegate->ContinueWithCertificate(nullptr, nullptr);
352 }
353 }
354
355 std::unique_ptr<content::ClientCertificateDelegate> delegate_;
356
357 IMPLEMENT_REFCOUNTING(CefSelectClientCertificateCallbackImpl);
358 };
359
360 class CefQuotaPermissionContext : public content::QuotaPermissionContext {
361 public:
362 CefQuotaPermissionContext() = default;
363
364 CefQuotaPermissionContext(const CefQuotaPermissionContext&) = delete;
365 CefQuotaPermissionContext& operator=(const CefQuotaPermissionContext&) =
366 delete;
367
368 // The callback will be dispatched on the IO thread.
RequestQuotaPermission(const content::StorageQuotaParams & params,int render_process_id,PermissionCallback callback)369 void RequestQuotaPermission(const content::StorageQuotaParams& params,
370 int render_process_id,
371 PermissionCallback callback) override {
372 if (params.storage_type != blink::mojom::StorageType::kPersistent) {
373 // To match Chrome behavior we only support requesting quota with this
374 // interface for Persistent storage type.
375 std::move(callback).Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
376 return;
377 }
378
379 bool handled = false;
380
381 CefRefPtr<AlloyBrowserHostImpl> browser =
382 AlloyBrowserHostImpl::GetBrowserForGlobalId(frame_util::MakeGlobalId(
383 render_process_id, params.render_frame_id));
384 if (browser) {
385 if (auto client = browser->GetClient()) {
386 if (auto handler = client->GetRequestHandler()) {
387 CefRefPtr<CefQuotaCallbackImpl> callbackImpl(
388 new CefQuotaCallbackImpl(std::move(callback)));
389 handled = handler->OnQuotaRequest(
390 browser.get(), params.origin_url.spec(), params.requested_size,
391 callbackImpl.get());
392 if (!handled) {
393 // May return nullptr if the client has already executed the
394 // callback.
395 callback = callbackImpl->Disconnect();
396 }
397 }
398 }
399 }
400
401 if (!handled && !callback.is_null()) {
402 // Disallow the request by default.
403 std::move(callback).Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
404 }
405 }
406
407 private:
408 ~CefQuotaPermissionContext() override = default;
409 };
410
411 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
CreateCrashHandlerHost(const std::string & process_type)412 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
413 const std::string& process_type) {
414 base::FilePath dumps_path;
415 base::PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
416 {
417 ANNOTATE_SCOPED_MEMORY_LEAK;
418 // Uploads will only occur if a non-empty crash URL is specified in
419 // AlloyMainDelegate::InitCrashReporter.
420 breakpad::CrashHandlerHostLinux* crash_handler =
421 new breakpad::CrashHandlerHostLinux(process_type, dumps_path,
422 true /* upload */);
423 crash_handler->StartUploaderThread();
424 return crash_handler;
425 }
426 }
427
GetCrashSignalFD(const base::CommandLine & command_line)428 int GetCrashSignalFD(const base::CommandLine& command_line) {
429 if (!breakpad::IsCrashReporterEnabled())
430 return -1;
431
432 // Extensions have the same process type as renderers.
433 if (command_line.HasSwitch(extensions::switches::kExtensionProcess)) {
434 static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
435 if (!crash_handler)
436 crash_handler = CreateCrashHandlerHost("extension");
437 return crash_handler->GetDeathSignalSocket();
438 }
439
440 std::string process_type =
441 command_line.GetSwitchValueASCII(switches::kProcessType);
442
443 if (process_type == switches::kRendererProcess) {
444 static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
445 if (!crash_handler)
446 crash_handler = CreateCrashHandlerHost(process_type);
447 return crash_handler->GetDeathSignalSocket();
448 }
449
450 if (process_type == switches::kPpapiPluginProcess) {
451 static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
452 if (!crash_handler)
453 crash_handler = CreateCrashHandlerHost(process_type);
454 return crash_handler->GetDeathSignalSocket();
455 }
456
457 if (process_type == switches::kGpuProcess) {
458 static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
459 if (!crash_handler)
460 crash_handler = CreateCrashHandlerHost(process_type);
461 return crash_handler->GetDeathSignalSocket();
462 }
463
464 return -1;
465 }
466 #endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
467
468 // From chrome/browser/plugins/chrome_content_browser_client_plugins_part.cc.
BindPluginInfoHost(int render_process_id,mojo::PendingAssociatedReceiver<chrome::mojom::PluginInfoHost> receiver)469 void BindPluginInfoHost(
470 int render_process_id,
471 mojo::PendingAssociatedReceiver<chrome::mojom::PluginInfoHost> receiver) {
472 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
473 content::RenderProcessHost* host =
474 content::RenderProcessHost::FromID(render_process_id);
475 if (!host)
476 return;
477
478 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
479 mojo::MakeSelfOwnedAssociatedReceiver(
480 std::make_unique<PluginInfoHostImpl>(render_process_id, profile),
481 std::move(receiver));
482 }
483
GetRootCachePath()484 base::FilePath GetRootCachePath() {
485 // The CefContext::ValidateCachePath method enforces the requirement that all
486 // cache_path values be either equal to or a child of root_cache_path.
487 return base::FilePath(
488 CefString(&CefContext::Get()->settings().root_cache_path));
489 }
490
GetEnabledExtensionFromSiteURL(content::BrowserContext * context,const GURL & site_url)491 const extensions::Extension* GetEnabledExtensionFromSiteURL(
492 content::BrowserContext* context,
493 const GURL& site_url) {
494 if (!site_url.SchemeIs(extensions::kExtensionScheme))
495 return nullptr;
496
497 auto registry = extensions::ExtensionRegistry::Get(context);
498 if (!registry)
499 return nullptr;
500
501 return registry->enabled_extensions().GetByID(site_url.host());
502 }
503
504 } // namespace
505
506 AlloyContentBrowserClient::AlloyContentBrowserClient() = default;
507
508 AlloyContentBrowserClient::~AlloyContentBrowserClient() = default;
509
510 std::unique_ptr<content::BrowserMainParts>
CreateBrowserMainParts(content::MainFunctionParams parameters)511 AlloyContentBrowserClient::CreateBrowserMainParts(
512 content::MainFunctionParams parameters) {
513 browser_main_parts_ = new AlloyBrowserMainParts(std::move(parameters));
514 return base::WrapUnique(browser_main_parts_);
515 }
516
RenderProcessWillLaunch(content::RenderProcessHost * host)517 void AlloyContentBrowserClient::RenderProcessWillLaunch(
518 content::RenderProcessHost* host) {
519 const int id = host->GetID();
520 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
521
522 if (extensions::ExtensionsEnabled()) {
523 host->AddFilter(new extensions::ExtensionMessageFilter(id, profile));
524 host->AddFilter(
525 new extensions::ExtensionsGuestViewMessageFilter(id, profile));
526 }
527
528 // If the renderer process crashes then the host may already have
529 // CefBrowserInfoManager as an observer. Try to remove it first before adding
530 // to avoid DCHECKs.
531 host->RemoveObserver(CefBrowserInfoManager::GetInstance());
532 host->AddObserver(CefBrowserInfoManager::GetInstance());
533
534 // Forwards dynamic parameters to CefRenderThreadObserver.
535 Profile* original_profile = profile->GetOriginalProfile();
536 RendererUpdaterFactory::GetForProfile(original_profile)
537 ->InitializeRenderer(host);
538 }
539
ShouldUseProcessPerSite(content::BrowserContext * browser_context,const GURL & site_url)540 bool AlloyContentBrowserClient::ShouldUseProcessPerSite(
541 content::BrowserContext* browser_context,
542 const GURL& site_url) {
543 if (extensions::ExtensionsEnabled()) {
544 if (auto profile = Profile::FromBrowserContext(browser_context)) {
545 return extensions::ChromeContentBrowserClientExtensionsPart::
546 ShouldUseProcessPerSite(profile, site_url);
547 }
548 }
549
550 return content::ContentBrowserClient::ShouldUseProcessPerSite(browser_context,
551 site_url);
552 }
553
ShouldUseSpareRenderProcessHost(content::BrowserContext * browser_context,const GURL & site_url)554 bool AlloyContentBrowserClient::ShouldUseSpareRenderProcessHost(
555 content::BrowserContext* browser_context,
556 const GURL& site_url) {
557 if (extensions::ExtensionsEnabled()) {
558 if (auto profile = Profile::FromBrowserContext(browser_context)) {
559 return extensions::ChromeContentBrowserClientExtensionsPart::
560 ShouldUseSpareRenderProcessHost(profile, site_url);
561 }
562 }
563
564 return content::ContentBrowserClient::ShouldUseSpareRenderProcessHost(
565 browser_context, site_url);
566 }
567
DoesSiteRequireDedicatedProcess(content::BrowserContext * browser_context,const GURL & effective_site_url)568 bool AlloyContentBrowserClient::DoesSiteRequireDedicatedProcess(
569 content::BrowserContext* browser_context,
570 const GURL& effective_site_url) {
571 if (extensions::ExtensionsEnabled()) {
572 return extensions::ChromeContentBrowserClientExtensionsPart::
573 DoesSiteRequireDedicatedProcess(browser_context, effective_site_url);
574 }
575
576 return content::ContentBrowserClient::DoesSiteRequireDedicatedProcess(
577 browser_context, effective_site_url);
578 }
579
ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(base::StringPiece scheme,bool is_embedded_origin_secure)580 bool AlloyContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
581 base::StringPiece scheme,
582 bool is_embedded_origin_secure) {
583 // This is needed to bypass the normal SameSite rules for any chrome:// page
584 // embedding a secure origin, regardless of the registrable domains of any
585 // intervening frames. For example, this is needed for browser UI to interact
586 // with SameSite cookies on accounts.google.com, which are used for logging
587 // into Cloud Print from chrome://print, for displaying a list of available
588 // accounts on the NTP (chrome://new-tab-page), etc.
589 if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
590 return true;
591
592 if (extensions::ExtensionsEnabled())
593 return scheme == extensions::kExtensionScheme;
594
595 return false;
596 }
597
598 bool AlloyContentBrowserClient::
ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel(base::StringPiece scheme,bool is_embedded_origin_secure)599 ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel(
600 base::StringPiece scheme,
601 bool is_embedded_origin_secure) {
602 return is_embedded_origin_secure && scheme == content::kChromeUIScheme;
603 }
604
OverrideURLLoaderFactoryParams(content::BrowserContext * browser_context,const url::Origin & origin,bool is_for_isolated_world,network::mojom::URLLoaderFactoryParams * factory_params)605 void AlloyContentBrowserClient::OverrideURLLoaderFactoryParams(
606 content::BrowserContext* browser_context,
607 const url::Origin& origin,
608 bool is_for_isolated_world,
609 network::mojom::URLLoaderFactoryParams* factory_params) {
610 if (extensions::ExtensionsEnabled()) {
611 extensions::URLLoaderFactoryManager::OverrideURLLoaderFactoryParams(
612 browser_context, origin, is_for_isolated_world, factory_params);
613 }
614 }
615
GetAdditionalWebUISchemes(std::vector<std::string> * additional_schemes)616 void AlloyContentBrowserClient::GetAdditionalWebUISchemes(
617 std::vector<std::string>* additional_schemes) {
618 // Any schemes listed here are treated as WebUI schemes but do not get WebUI
619 // bindings. Also, view-source is allowed for these schemes. WebUI schemes
620 // will not be passed to HandleExternalProtocol.
621 }
622
GetAdditionalViewSourceSchemes(std::vector<std::string> * additional_schemes)623 void AlloyContentBrowserClient::GetAdditionalViewSourceSchemes(
624 std::vector<std::string>* additional_schemes) {
625 GetAdditionalWebUISchemes(additional_schemes);
626
627 additional_schemes->push_back(extensions::kExtensionScheme);
628 }
629
GetAdditionalAllowedSchemesForFileSystem(std::vector<std::string> * additional_allowed_schemes)630 void AlloyContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
631 std::vector<std::string>* additional_allowed_schemes) {
632 ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
633 additional_allowed_schemes);
634 additional_allowed_schemes->push_back(content::kChromeDevToolsScheme);
635 additional_allowed_schemes->push_back(content::kChromeUIScheme);
636 additional_allowed_schemes->push_back(content::kChromeUIUntrustedScheme);
637 }
638
IsWebUIAllowedToMakeNetworkRequests(const url::Origin & origin)639 bool AlloyContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests(
640 const url::Origin& origin) {
641 return scheme::IsWebUIAllowedToMakeNetworkRequests(origin);
642 }
643
IsHandledURL(const GURL & url)644 bool AlloyContentBrowserClient::IsHandledURL(const GURL& url) {
645 if (!url.is_valid())
646 return false;
647 const std::string& scheme = url.scheme();
648 DCHECK_EQ(scheme, base::ToLowerASCII(scheme));
649
650 if (scheme::IsInternalHandledScheme(scheme))
651 return true;
652
653 return CefAppManager::Get()->HasCustomScheme(scheme);
654 }
655
SiteInstanceGotProcess(content::SiteInstance * site_instance)656 void AlloyContentBrowserClient::SiteInstanceGotProcess(
657 content::SiteInstance* site_instance) {
658 if (!extensions::ExtensionsEnabled())
659 return;
660
661 CHECK(site_instance->HasProcess());
662
663 auto context = site_instance->GetBrowserContext();
664
665 // Only add the process to the map if the SiteInstance's site URL is already
666 // a chrome-extension:// URL. This includes hosted apps, except in rare cases
667 // that a URL in the hosted app's extent is not treated as a hosted app (e.g.,
668 // for isolated origins or cross-site iframes). For that case, don't look up
669 // the hosted app's Extension from the site URL using GetExtensionOrAppByURL,
670 // since it isn't treated as a hosted app.
671 const auto extension =
672 GetEnabledExtensionFromSiteURL(context, site_instance->GetSiteURL());
673 if (!extension)
674 return;
675
676 extensions::ProcessMap::Get(context)->Insert(
677 extension->id(), site_instance->GetProcess()->GetID(),
678 site_instance->GetId());
679 }
680
SiteInstanceDeleting(content::SiteInstance * site_instance)681 void AlloyContentBrowserClient::SiteInstanceDeleting(
682 content::SiteInstance* site_instance) {
683 if (!extensions::ExtensionsEnabled())
684 return;
685
686 if (!site_instance->HasProcess())
687 return;
688
689 auto context = site_instance->GetBrowserContext();
690 auto registry = extensions::ExtensionRegistry::Get(context);
691 if (!registry)
692 return;
693
694 auto extension = registry->enabled_extensions().GetExtensionOrAppByURL(
695 site_instance->GetSiteURL());
696 if (!extension)
697 return;
698
699 extensions::ProcessMap::Get(context)->Remove(
700 extension->id(), site_instance->GetProcess()->GetID(),
701 site_instance->GetId());
702 }
703
BindHostReceiverForRenderer(content::RenderProcessHost * render_process_host,mojo::GenericPendingReceiver receiver)704 void AlloyContentBrowserClient::BindHostReceiverForRenderer(
705 content::RenderProcessHost* render_process_host,
706 mojo::GenericPendingReceiver receiver) {
707 if (auto host_receiver = receiver.As<spellcheck::mojom::SpellCheckHost>()) {
708 SpellCheckHostChromeImpl::Create(render_process_host->GetID(),
709 std::move(host_receiver));
710 return;
711 }
712
713 #if BUILDFLAG(HAS_SPELLCHECK_PANEL)
714 if (auto panel_host_receiver =
715 receiver.As<spellcheck::mojom::SpellCheckPanelHost>()) {
716 SpellCheckPanelHostImpl::Create(render_process_host->GetID(),
717 std::move(panel_host_receiver));
718 return;
719 }
720 #endif // BUILDFLAG(HAS_SPELLCHECK_PANEL)
721 }
722
AppendExtraCommandLineSwitches(base::CommandLine * command_line,int child_process_id)723 void AlloyContentBrowserClient::AppendExtraCommandLineSwitches(
724 base::CommandLine* command_line,
725 int child_process_id) {
726 const base::CommandLine* browser_cmd = base::CommandLine::ForCurrentProcess();
727
728 {
729 // Propagate the following switches to all command lines (along with any
730 // associated values) if present in the browser command line.
731 static const char* const kSwitchNames[] = {
732 switches::kDisablePackLoading,
733 #if BUILDFLAG(IS_MAC)
734 switches::kFrameworkDirPath,
735 switches::kMainBundlePath,
736 #endif
737 switches::kLocalesDirPath,
738 switches::kLogSeverity,
739 switches::kResourcesDirPath,
740 embedder_support::kUserAgent,
741 switches::kUserAgentProductAndVersion,
742 };
743 command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
744 base::size(kSwitchNames));
745 }
746
747 const std::string& process_type =
748 command_line->GetSwitchValueASCII(switches::kProcessType);
749 if (process_type == switches::kRendererProcess) {
750 // Propagate the following switches to the renderer command line (along with
751 // any associated values) if present in the browser command line.
752 static const char* const kSwitchNames[] = {
753 switches::kDisableExtensions,
754 switches::kDisablePdfExtension,
755 switches::kDisablePlugins,
756 switches::kDisablePrintPreview,
757 switches::kDisableScrollBounce,
758 switches::kDisableSpellChecking,
759 switches::kEnableSpeechInput,
760 switches::kUncaughtExceptionStackSize,
761 network::switches::kUnsafelyTreatInsecureOriginAsSecure,
762 };
763 command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
764 base::size(kSwitchNames));
765
766 if (extensions::ExtensionsEnabled()) {
767 content::RenderProcessHost* process =
768 content::RenderProcessHost::FromID(child_process_id);
769 auto browser_context = process->GetBrowserContext();
770 CefBrowserContext* cef_browser_context =
771 process ? CefBrowserContext::FromBrowserContext(browser_context)
772 : nullptr;
773 if (cef_browser_context) {
774 if (cef_browser_context->IsPrintPreviewSupported()) {
775 command_line->AppendSwitch(switches::kEnablePrintPreview);
776 }
777
778 // Based on ChromeContentBrowserClientExtensionsPart::
779 // AppendExtraRendererCommandLineSwitches
780 if (extensions::ProcessMap::Get(browser_context)
781 ->Contains(process->GetID())) {
782 command_line->AppendSwitch(extensions::switches::kExtensionProcess);
783 }
784 }
785 }
786 } else {
787 // Propagate the following switches to non-renderer command line (along with
788 // any associated values) if present in the browser command line.
789 static const char* const kSwitchNames[] = {
790 switches::kLang,
791 };
792 command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
793 base::size(kSwitchNames));
794 }
795
796 // Necessary to populate DIR_USER_DATA in sub-processes.
797 // See resource_util.cc GetUserDataPath.
798 base::FilePath user_data_dir;
799 if (base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
800 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
801 }
802
803 #if BUILDFLAG(IS_LINUX)
804 if (process_type == switches::kZygoteProcess) {
805 if (browser_cmd->HasSwitch(switches::kBrowserSubprocessPath)) {
806 // Force use of the sub-process executable path for the zygote process.
807 const base::FilePath& subprocess_path =
808 browser_cmd->GetSwitchValuePath(switches::kBrowserSubprocessPath);
809 if (!subprocess_path.empty())
810 command_line->SetProgram(subprocess_path);
811 }
812
813 // Propagate the following switches to the zygote command line (along with
814 // any associated values) if present in the browser command line.
815 static const char* const kSwitchNames[] = {
816 switches::kLogFile,
817 };
818 command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
819 base::size(kSwitchNames));
820 }
821 #endif // BUILDFLAG(IS_LINUX)
822
823 CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
824 if (app.get()) {
825 CefRefPtr<CefBrowserProcessHandler> handler =
826 app->GetBrowserProcessHandler();
827 if (handler.get()) {
828 CefRefPtr<CefCommandLineImpl> commandLinePtr(
829 new CefCommandLineImpl(command_line, false, false));
830 handler->OnBeforeChildProcessLaunch(commandLinePtr.get());
831 std::ignore = commandLinePtr->Detach(nullptr);
832 }
833 }
834 }
835
GetApplicationLocale()836 std::string AlloyContentBrowserClient::GetApplicationLocale() {
837 return g_browser_process->GetApplicationLocale();
838 }
839
840 scoped_refptr<network::SharedURLLoaderFactory>
GetSystemSharedURLLoaderFactory()841 AlloyContentBrowserClient::GetSystemSharedURLLoaderFactory() {
842 DCHECK(
843 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI) ||
844 !content::BrowserThread::IsThreadInitialized(content::BrowserThread::UI));
845
846 if (!SystemNetworkContextManager::GetInstance())
847 return nullptr;
848
849 return SystemNetworkContextManager::GetInstance()
850 ->GetSharedURLLoaderFactory();
851 }
852
853 network::mojom::NetworkContext*
GetSystemNetworkContext()854 AlloyContentBrowserClient::GetSystemNetworkContext() {
855 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
856 DCHECK(SystemNetworkContextManager::GetInstance());
857 return SystemNetworkContextManager::GetInstance()->GetContext();
858 }
859
860 scoped_refptr<content::QuotaPermissionContext>
CreateQuotaPermissionContext()861 AlloyContentBrowserClient::CreateQuotaPermissionContext() {
862 return new CefQuotaPermissionContext();
863 }
864
GetMediaObserver()865 content::MediaObserver* AlloyContentBrowserClient::GetMediaObserver() {
866 return CefMediaCaptureDevicesDispatcher::GetInstance();
867 }
868
869 content::SpeechRecognitionManagerDelegate*
CreateSpeechRecognitionManagerDelegate()870 AlloyContentBrowserClient::CreateSpeechRecognitionManagerDelegate() {
871 const base::CommandLine* command_line =
872 base::CommandLine::ForCurrentProcess();
873 if (command_line->HasSwitch(switches::kEnableSpeechInput))
874 return new CefSpeechRecognitionManagerDelegate();
875
876 return nullptr;
877 }
878
879 content::GeneratedCodeCacheSettings
GetGeneratedCodeCacheSettings(content::BrowserContext * context)880 AlloyContentBrowserClient::GetGeneratedCodeCacheSettings(
881 content::BrowserContext* context) {
882 // If we pass 0 for size, disk_cache will pick a default size using the
883 // heuristics based on available disk size. These are implemented in
884 // disk_cache::PreferredCacheSize in net/disk_cache/cache_util.cc.
885 const base::FilePath& cache_path = context->GetPath();
886 return content::GeneratedCodeCacheSettings(!cache_path.empty() /* enabled */,
887 0 /* size */, cache_path);
888 }
889
AllowCertificateError(content::WebContents * web_contents,int cert_error,const net::SSLInfo & ssl_info,const GURL & request_url,bool is_main_frame_request,bool strict_enforcement,base::OnceCallback<void (content::CertificateRequestResultType)> callback)890 void AlloyContentBrowserClient::AllowCertificateError(
891 content::WebContents* web_contents,
892 int cert_error,
893 const net::SSLInfo& ssl_info,
894 const GURL& request_url,
895 bool is_main_frame_request,
896 bool strict_enforcement,
897 base::OnceCallback<void(content::CertificateRequestResultType)> callback) {
898 CEF_REQUIRE_UIT();
899
900 if (!is_main_frame_request) {
901 // A sub-resource has a certificate error. The user doesn't really
902 // have a context for making the right decision, so block the request
903 // hard.
904 std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
905 return;
906 }
907
908 CefRefPtr<AlloyBrowserHostImpl> browser =
909 AlloyBrowserHostImpl::GetBrowserForContents(web_contents);
910 if (!browser.get())
911 return;
912 CefRefPtr<CefClient> client = browser->GetClient();
913 if (!client.get())
914 return;
915 CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
916 if (!handler.get())
917 return;
918
919 CefRefPtr<CefSSLInfo> cef_ssl_info = new CefSSLInfoImpl(ssl_info);
920
921 CefRefPtr<CefAllowCertificateErrorCallbackImpl> callbackImpl(
922 new CefAllowCertificateErrorCallbackImpl(std::move(callback)));
923
924 bool proceed = handler->OnCertificateError(
925 browser.get(), static_cast<cef_errorcode_t>(cert_error),
926 request_url.spec(), cef_ssl_info, callbackImpl.get());
927 if (!proceed) {
928 // |callback| may be null if the user executed it despite returning false.
929 callback = callbackImpl->Disconnect();
930 if (!callback.is_null()) {
931 std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
932 }
933 }
934 }
935
SelectClientCertificate(content::WebContents * web_contents,net::SSLCertRequestInfo * cert_request_info,net::ClientCertIdentityList client_certs,std::unique_ptr<content::ClientCertificateDelegate> delegate)936 base::OnceClosure AlloyContentBrowserClient::SelectClientCertificate(
937 content::WebContents* web_contents,
938 net::SSLCertRequestInfo* cert_request_info,
939 net::ClientCertIdentityList client_certs,
940 std::unique_ptr<content::ClientCertificateDelegate> delegate) {
941 CEF_REQUIRE_UIT();
942
943 CefRefPtr<CefRequestHandler> handler;
944 CefRefPtr<AlloyBrowserHostImpl> browser =
945 AlloyBrowserHostImpl::GetBrowserForContents(web_contents);
946 if (browser.get()) {
947 CefRefPtr<CefClient> client = browser->GetClient();
948 if (client.get())
949 handler = client->GetRequestHandler();
950 }
951
952 if (!handler.get()) {
953 delegate->ContinueWithCertificate(nullptr, nullptr);
954 return base::OnceClosure();
955 }
956
957 CefRequestHandler::X509CertificateList certs;
958 for (net::ClientCertIdentityList::iterator iter = client_certs.begin();
959 iter != client_certs.end(); iter++) {
960 certs.push_back(new CefX509CertificateImpl(std::move(*iter)));
961 }
962
963 CefRefPtr<CefSelectClientCertificateCallbackImpl> callbackImpl(
964 new CefSelectClientCertificateCallbackImpl(std::move(delegate)));
965
966 bool proceed = handler->OnSelectClientCertificate(
967 browser.get(), cert_request_info->is_proxy,
968 cert_request_info->host_and_port.host(),
969 cert_request_info->host_and_port.port(), certs, callbackImpl.get());
970
971 if (!proceed && !certs.empty()) {
972 callbackImpl->Select(certs[0]);
973 }
974 return base::OnceClosure();
975 }
976
CanCreateWindow(content::RenderFrameHost * opener,const GURL & opener_url,const GURL & opener_top_level_frame_url,const url::Origin & source_origin,content::mojom::WindowContainerType container_type,const GURL & target_url,const content::Referrer & referrer,const std::string & frame_name,WindowOpenDisposition disposition,const blink::mojom::WindowFeatures & features,bool user_gesture,bool opener_suppressed,bool * no_javascript_access)977 bool AlloyContentBrowserClient::CanCreateWindow(
978 content::RenderFrameHost* opener,
979 const GURL& opener_url,
980 const GURL& opener_top_level_frame_url,
981 const url::Origin& source_origin,
982 content::mojom::WindowContainerType container_type,
983 const GURL& target_url,
984 const content::Referrer& referrer,
985 const std::string& frame_name,
986 WindowOpenDisposition disposition,
987 const blink::mojom::WindowFeatures& features,
988 bool user_gesture,
989 bool opener_suppressed,
990 bool* no_javascript_access) {
991 CEF_REQUIRE_UIT();
992 *no_javascript_access = false;
993
994 return CefBrowserInfoManager::GetInstance()->CanCreateWindow(
995 opener, target_url, referrer, frame_name, disposition, features,
996 user_gesture, opener_suppressed, no_javascript_access);
997 }
998
OverrideWebkitPrefs(content::WebContents * web_contents,blink::web_pref::WebPreferences * prefs)999 void AlloyContentBrowserClient::OverrideWebkitPrefs(
1000 content::WebContents* web_contents,
1001 blink::web_pref::WebPreferences* prefs) {
1002 auto rvh = web_contents->GetRenderViewHost();
1003
1004 // Using RVH instead of RFH here because rvh->GetMainFrame() may be nullptr
1005 // when this method is called.
1006 SkColor base_background_color;
1007 renderer_prefs::PopulateWebPreferences(rvh, *prefs, base_background_color);
1008
1009 web_contents->SetPageBaseBackgroundColor(base_background_color);
1010 }
1011
OverrideWebPreferencesAfterNavigation(content::WebContents * web_contents,blink::web_pref::WebPreferences * prefs)1012 bool AlloyContentBrowserClient::OverrideWebPreferencesAfterNavigation(
1013 content::WebContents* web_contents,
1014 blink::web_pref::WebPreferences* prefs) {
1015 return renderer_prefs::PopulateWebPreferencesAfterNavigation(web_contents,
1016 *prefs);
1017 }
1018
BrowserURLHandlerCreated(content::BrowserURLHandler * handler)1019 void AlloyContentBrowserClient::BrowserURLHandlerCreated(
1020 content::BrowserURLHandler* handler) {
1021 scheme::BrowserURLHandlerCreated(handler);
1022 }
1023
GetDefaultDownloadName()1024 std::string AlloyContentBrowserClient::GetDefaultDownloadName() {
1025 return "download";
1026 }
1027
DidCreatePpapiPlugin(content::BrowserPpapiHost * browser_host)1028 void AlloyContentBrowserClient::DidCreatePpapiPlugin(
1029 content::BrowserPpapiHost* browser_host) {
1030 browser_host->GetPpapiHost()->AddHostFactoryFilter(
1031 std::unique_ptr<ppapi::host::HostFactory>(
1032 new ChromeBrowserPepperHostFactory(browser_host)));
1033 }
1034
1035 std::unique_ptr<content::DevToolsManagerDelegate>
CreateDevToolsManagerDelegate()1036 AlloyContentBrowserClient::CreateDevToolsManagerDelegate() {
1037 return std::make_unique<CefDevToolsManagerDelegate>();
1038 }
1039
1040 void AlloyContentBrowserClient::
RegisterAssociatedInterfaceBindersForRenderFrameHost(content::RenderFrameHost & render_frame_host,blink::AssociatedInterfaceRegistry & associated_registry)1041 RegisterAssociatedInterfaceBindersForRenderFrameHost(
1042 content::RenderFrameHost& render_frame_host,
1043 blink::AssociatedInterfaceRegistry& associated_registry) {
1044 associated_registry.AddInterface(base::BindRepeating(
1045 [](content::RenderFrameHost* render_frame_host,
1046 mojo::PendingAssociatedReceiver<extensions::mojom::LocalFrameHost>
1047 receiver) {
1048 extensions::ExtensionWebContentsObserver::BindLocalFrameHost(
1049 std::move(receiver), render_frame_host);
1050 },
1051 &render_frame_host));
1052
1053 associated_registry.AddInterface(base::BindRepeating(
1054 [](content::RenderFrameHost* render_frame_host,
1055 mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost>
1056 receiver) {
1057 printing::CefPrintViewManager::BindPrintManagerHost(std::move(receiver),
1058 render_frame_host);
1059 },
1060 &render_frame_host));
1061
1062 associated_registry.AddInterface(base::BindRepeating(
1063 [](content::RenderFrameHost* render_frame_host,
1064 mojo::PendingAssociatedReceiver<pdf::mojom::PdfService> receiver) {
1065 pdf::PDFWebContentsHelper::BindPdfService(std::move(receiver),
1066 render_frame_host);
1067 },
1068 &render_frame_host));
1069 }
1070
1071 std::vector<std::unique_ptr<content::NavigationThrottle>>
CreateThrottlesForNavigation(content::NavigationHandle * navigation_handle)1072 AlloyContentBrowserClient::CreateThrottlesForNavigation(
1073 content::NavigationHandle* navigation_handle) {
1074 throttle::NavigationThrottleList throttles;
1075
1076 if (extensions::ExtensionsEnabled()) {
1077 auto pdf_iframe_throttle =
1078 PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(navigation_handle);
1079 if (pdf_iframe_throttle)
1080 throttles.push_back(std::move(pdf_iframe_throttle));
1081
1082 auto pdf_throttle = pdf::PdfNavigationThrottle::MaybeCreateThrottleFor(
1083 navigation_handle, std::make_unique<ChromePdfStreamDelegate>());
1084 if (pdf_throttle)
1085 throttles.push_back(std::move(pdf_throttle));
1086 }
1087
1088 throttle::CreateThrottlesForNavigation(navigation_handle, throttles);
1089
1090 return throttles;
1091 }
1092
1093 std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
CreateURLLoaderThrottles(const network::ResourceRequest & request,content::BrowserContext * browser_context,const base::RepeatingCallback<content::WebContents * ()> & wc_getter,content::NavigationUIData * navigation_ui_data,int frame_tree_node_id)1094 AlloyContentBrowserClient::CreateURLLoaderThrottles(
1095 const network::ResourceRequest& request,
1096 content::BrowserContext* browser_context,
1097 const base::RepeatingCallback<content::WebContents*()>& wc_getter,
1098 content::NavigationUIData* navigation_ui_data,
1099 int frame_tree_node_id) {
1100 std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
1101
1102 // Used to substitute View ID for PDF contents when using the PDF plugin.
1103 result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
1104 request.destination, frame_tree_node_id));
1105
1106 Profile* profile = Profile::FromBrowserContext(browser_context);
1107
1108 chrome::mojom::DynamicParams dynamic_params = {
1109 profile->GetPrefs()->GetBoolean(prefs::kForceGoogleSafeSearch),
1110 profile->GetPrefs()->GetInteger(prefs::kForceYouTubeRestrict),
1111 profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps)};
1112 result.push_back(
1113 std::make_unique<GoogleURLLoaderThrottle>(std::move(dynamic_params)));
1114
1115 return result;
1116 }
1117
1118 std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
WillCreateURLLoaderRequestInterceptors(content::NavigationUIData * navigation_ui_data,int frame_tree_node_id,const scoped_refptr<network::SharedURLLoaderFactory> & network_loader_factory)1119 AlloyContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
1120 content::NavigationUIData* navigation_ui_data,
1121 int frame_tree_node_id,
1122 const scoped_refptr<network::SharedURLLoaderFactory>&
1123 network_loader_factory) {
1124 std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
1125 interceptors;
1126
1127 if (extensions::ExtensionsEnabled()) {
1128 auto pdf_interceptor =
1129 pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor(
1130 frame_tree_node_id, std::make_unique<ChromePdfStreamDelegate>());
1131 if (pdf_interceptor)
1132 interceptors.push_back(std::move(pdf_interceptor));
1133 }
1134
1135 return interceptors;
1136 }
1137
1138 #if BUILDFLAG(IS_LINUX)
GetAdditionalMappedFilesForChildProcess(const base::CommandLine & command_line,int child_process_id,content::PosixFileDescriptorInfo * mappings)1139 void AlloyContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
1140 const base::CommandLine& command_line,
1141 int child_process_id,
1142 content::PosixFileDescriptorInfo* mappings) {
1143 int crash_signal_fd = GetCrashSignalFD(command_line);
1144 if (crash_signal_fd >= 0) {
1145 mappings->Share(kCrashDumpSignal, crash_signal_fd);
1146 }
1147 }
1148 #endif // BUILDFLAG(IS_LINUX)
1149
ExposeInterfacesToRenderer(service_manager::BinderRegistry * registry,blink::AssociatedInterfaceRegistry * associated_registry,content::RenderProcessHost * host)1150 void AlloyContentBrowserClient::ExposeInterfacesToRenderer(
1151 service_manager::BinderRegistry* registry,
1152 blink::AssociatedInterfaceRegistry* associated_registry,
1153 content::RenderProcessHost* host) {
1154 associated_registry->AddInterface(
1155 base::BindRepeating(&BindPluginInfoHost, host->GetID()));
1156
1157 if (extensions::ExtensionsEnabled()) {
1158 associated_registry->AddInterface(base::BindRepeating(
1159 &extensions::EventRouter::BindForRenderer, host->GetID()));
1160 }
1161
1162 CefBrowserManager::ExposeInterfacesToRenderer(registry, associated_registry,
1163 host);
1164 }
1165
1166 std::unique_ptr<net::ClientCertStore>
CreateClientCertStore(content::BrowserContext * browser_context)1167 AlloyContentBrowserClient::CreateClientCertStore(
1168 content::BrowserContext* browser_context) {
1169 // Match the logic in ProfileNetworkContextService::CreateClientCertStore.
1170 #if BUILDFLAG(USE_NSS_CERTS)
1171 // TODO: Add support for client implementation of crypto password dialog.
1172 return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(
1173 net::ClientCertStoreNSS::PasswordDelegateFactory()));
1174 #elif BUILDFLAG(IS_WIN)
1175 return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
1176 #elif BUILDFLAG(IS_MAC)
1177 return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
1178 #else
1179 #error Unknown platform.
1180 #endif
1181 }
1182
1183 std::unique_ptr<content::LoginDelegate>
CreateLoginDelegate(const net::AuthChallengeInfo & auth_info,content::WebContents * web_contents,const content::GlobalRequestID & request_id,bool is_request_for_main_frame,const GURL & url,scoped_refptr<net::HttpResponseHeaders> response_headers,bool first_auth_attempt,LoginAuthRequiredCallback auth_required_callback)1184 AlloyContentBrowserClient::CreateLoginDelegate(
1185 const net::AuthChallengeInfo& auth_info,
1186 content::WebContents* web_contents,
1187 const content::GlobalRequestID& request_id,
1188 bool is_request_for_main_frame,
1189 const GURL& url,
1190 scoped_refptr<net::HttpResponseHeaders> response_headers,
1191 bool first_auth_attempt,
1192 LoginAuthRequiredCallback auth_required_callback) {
1193 return std::make_unique<net_service::LoginDelegate>(
1194 auth_info, web_contents, request_id, url,
1195 std::move(auth_required_callback));
1196 }
1197
RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id,ukm::SourceIdObj ukm_source_id,NonNetworkURLLoaderFactoryMap * factories)1198 void AlloyContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
1199 int frame_tree_node_id,
1200 ukm::SourceIdObj ukm_source_id,
1201 NonNetworkURLLoaderFactoryMap* factories) {
1202 if (!extensions::ExtensionsEnabled())
1203 return;
1204
1205 content::WebContents* web_contents =
1206 content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
1207 factories->emplace(
1208 extensions::kExtensionScheme,
1209 extensions::CreateExtensionNavigationURLLoaderFactory(
1210 web_contents->GetBrowserContext(), ukm_source_id,
1211 !!extensions::WebViewGuest::FromWebContents(web_contents)));
1212 }
1213
RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id,int render_frame_id,const absl::optional<url::Origin> & request_initiator_origin,NonNetworkURLLoaderFactoryMap * factories)1214 void AlloyContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
1215 int render_process_id,
1216 int render_frame_id,
1217 const absl::optional<url::Origin>& request_initiator_origin,
1218 NonNetworkURLLoaderFactoryMap* factories) {
1219 if (!extensions::ExtensionsEnabled())
1220 return;
1221
1222 auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
1223 render_frame_id);
1224 if (factory)
1225 factories->emplace(extensions::kExtensionScheme, std::move(factory));
1226
1227 content::RenderFrameHost* frame_host =
1228 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
1229 content::WebContents* web_contents =
1230 content::WebContents::FromRenderFrameHost(frame_host);
1231 if (!web_contents)
1232 return;
1233
1234 extensions::CefExtensionWebContentsObserver* web_observer =
1235 extensions::CefExtensionWebContentsObserver::FromWebContents(
1236 web_contents);
1237
1238 // There is nothing to do if no CefExtensionWebContentsObserver is attached
1239 // to the |web_contents|.
1240 if (!web_observer)
1241 return;
1242
1243 const extensions::Extension* extension =
1244 web_observer->GetExtensionFromFrame(frame_host, false);
1245 if (!extension)
1246 return;
1247
1248 std::vector<std::string> allowed_webui_hosts;
1249 // Support for chrome:// scheme if appropriate.
1250 if ((extension->is_extension() || extension->is_platform_app()) &&
1251 extensions::Manifest::IsComponentLocation(extension->location())) {
1252 // Components of chrome that are implemented as extensions or platform apps
1253 // are allowed to use chrome://resources/ and chrome://theme/ URLs.
1254 // See also HasCrossOriginWhitelistEntry.
1255 allowed_webui_hosts.emplace_back(content::kChromeUIResourcesHost);
1256 allowed_webui_hosts.emplace_back(chrome::kChromeUIThemeHost);
1257 }
1258 if (!allowed_webui_hosts.empty()) {
1259 factories->emplace(content::kChromeUIScheme,
1260 content::CreateWebUIURLLoaderFactory(
1261 frame_host, content::kChromeUIScheme,
1262 std::move(allowed_webui_hosts)));
1263 }
1264 }
1265
WillCreateURLLoaderFactory(content::BrowserContext * browser_context,content::RenderFrameHost * frame,int render_process_id,URLLoaderFactoryType type,const url::Origin & request_initiator,absl::optional<int64_t> navigation_id,ukm::SourceIdObj ukm_source_id,mojo::PendingReceiver<network::mojom::URLLoaderFactory> * factory_receiver,mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient> * header_client,bool * bypass_redirect_checks,bool * disable_secure_dns,network::mojom::URLLoaderFactoryOverridePtr * factory_override)1266 bool AlloyContentBrowserClient::WillCreateURLLoaderFactory(
1267 content::BrowserContext* browser_context,
1268 content::RenderFrameHost* frame,
1269 int render_process_id,
1270 URLLoaderFactoryType type,
1271 const url::Origin& request_initiator,
1272 absl::optional<int64_t> navigation_id,
1273 ukm::SourceIdObj ukm_source_id,
1274 mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
1275 mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
1276 header_client,
1277 bool* bypass_redirect_checks,
1278 bool* disable_secure_dns,
1279 network::mojom::URLLoaderFactoryOverridePtr* factory_override) {
1280 auto request_handler = net_service::CreateInterceptedRequestHandler(
1281 browser_context, frame, render_process_id,
1282 type == URLLoaderFactoryType::kNavigation,
1283 type == URLLoaderFactoryType::kDownload, request_initiator);
1284
1285 net_service::ProxyURLLoaderFactory::CreateProxy(
1286 browser_context, factory_receiver, header_client,
1287 std::move(request_handler));
1288 return true;
1289 }
1290
OnNetworkServiceCreated(network::mojom::NetworkService * network_service)1291 void AlloyContentBrowserClient::OnNetworkServiceCreated(
1292 network::mojom::NetworkService* network_service) {
1293 DCHECK(g_browser_process);
1294 PrefService* local_state = g_browser_process->local_state();
1295 DCHECK(local_state);
1296
1297 // Need to set up global NetworkService state before anything else uses it.
1298 DCHECK(SystemNetworkContextManager::GetInstance());
1299 SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated(
1300 network_service);
1301 }
1302
ConfigureNetworkContextParams(content::BrowserContext * context,bool in_memory,const base::FilePath & relative_partition_path,network::mojom::NetworkContextParams * network_context_params,cert_verifier::mojom::CertVerifierCreationParams * cert_verifier_creation_params)1303 bool AlloyContentBrowserClient::ConfigureNetworkContextParams(
1304 content::BrowserContext* context,
1305 bool in_memory,
1306 const base::FilePath& relative_partition_path,
1307 network::mojom::NetworkContextParams* network_context_params,
1308 cert_verifier::mojom::CertVerifierCreationParams*
1309 cert_verifier_creation_params) {
1310 // This method may be called during shutdown when using multi-threaded
1311 // message loop mode. In that case exit early to avoid crashes.
1312 if (!SystemNetworkContextManager::GetInstance()) {
1313 // Cancel NetworkContext creation in
1314 // StoragePartitionImpl::InitNetworkContext.
1315 return false;
1316 }
1317
1318 auto cef_context = CefBrowserContext::FromBrowserContext(context);
1319
1320 Profile* profile = cef_context->AsProfile();
1321 ProfileNetworkContextService* service =
1322 ProfileNetworkContextServiceFactory::GetForContext(profile);
1323 if (service) {
1324 service->ConfigureNetworkContextParams(in_memory, relative_partition_path,
1325 network_context_params,
1326 cert_verifier_creation_params);
1327 } else {
1328 // Set default params.
1329 network_context_params->user_agent = GetUserAgent();
1330 network_context_params->accept_language = GetApplicationLocale();
1331 }
1332
1333 network_context_params->cookieable_schemes =
1334 cef_context->GetCookieableSchemes();
1335
1336 // TODO(cef): Remove this and add required NetworkIsolationKeys,
1337 // this is currently not the case and this was not required pre M84.
1338 network_context_params->require_network_isolation_key = false;
1339
1340 return true;
1341 }
1342
1343 // The sandbox may block read/write access from the NetworkService to
1344 // directories that are not returned by this method.
1345 std::vector<base::FilePath>
GetNetworkContextsParentDirectory()1346 AlloyContentBrowserClient::GetNetworkContextsParentDirectory() {
1347 base::FilePath user_data_path;
1348 base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path);
1349 DCHECK(!user_data_path.empty());
1350
1351 const auto& root_cache_path = GetRootCachePath();
1352
1353 // root_cache_path may sometimes be empty or a child of user_data_path, so
1354 // only return the one path in that case.
1355 if (root_cache_path.empty() || user_data_path.IsParent(root_cache_path)) {
1356 return {user_data_path};
1357 }
1358
1359 return {user_data_path, root_cache_path};
1360 }
1361
HandleExternalProtocol(const GURL & url,content::WebContents::Getter web_contents_getter,int child_id,int frame_tree_node_id,content::NavigationUIData * navigation_data,bool is_main_frame,network::mojom::WebSandboxFlags sandbox_flags,ui::PageTransition page_transition,bool has_user_gesture,const absl::optional<url::Origin> & initiating_origin,content::RenderFrameHost * initiator_document,mojo::PendingRemote<network::mojom::URLLoaderFactory> * out_factory)1362 bool AlloyContentBrowserClient::HandleExternalProtocol(
1363 const GURL& url,
1364 content::WebContents::Getter web_contents_getter,
1365 int child_id,
1366 int frame_tree_node_id,
1367 content::NavigationUIData* navigation_data,
1368 bool is_main_frame,
1369 network::mojom::WebSandboxFlags sandbox_flags,
1370 ui::PageTransition page_transition,
1371 bool has_user_gesture,
1372 const absl::optional<url::Origin>& initiating_origin,
1373 content::RenderFrameHost* initiator_document,
1374 mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) {
1375 // Call the other HandleExternalProtocol variant.
1376 return false;
1377 }
1378
HandleExternalProtocol(content::WebContents::Getter web_contents_getter,int frame_tree_node_id,content::NavigationUIData * navigation_data,network::mojom::WebSandboxFlags sandbox_flags,const network::ResourceRequest & resource_request,const absl::optional<url::Origin> & initiating_origin,content::RenderFrameHost * initiator_document,mojo::PendingRemote<network::mojom::URLLoaderFactory> * out_factory)1379 bool AlloyContentBrowserClient::HandleExternalProtocol(
1380 content::WebContents::Getter web_contents_getter,
1381 int frame_tree_node_id,
1382 content::NavigationUIData* navigation_data,
1383 network::mojom::WebSandboxFlags sandbox_flags,
1384 const network::ResourceRequest& resource_request,
1385 const absl::optional<url::Origin>& initiating_origin,
1386 content::RenderFrameHost* initiator_document,
1387 mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) {
1388 mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
1389 out_factory->InitWithNewPipeAndPassReceiver();
1390
1391 // CefBrowserPlatformDelegate::HandleExternalProtocol may be called if
1392 // nothing handles the request.
1393 auto request_handler = net_service::CreateInterceptedRequestHandler(
1394 web_contents_getter, frame_tree_node_id, resource_request,
1395 base::BindRepeating(CefBrowserPlatformDelegate::HandleExternalProtocol,
1396 resource_request.url));
1397
1398 net_service::ProxyURLLoaderFactory::CreateProxy(
1399 web_contents_getter, std::move(receiver), std::move(request_handler));
1400 return true;
1401 }
1402
1403 std::unique_ptr<content::OverlayWindow>
CreateWindowForPictureInPicture(content::PictureInPictureWindowController * controller)1404 AlloyContentBrowserClient::CreateWindowForPictureInPicture(
1405 content::PictureInPictureWindowController* controller) {
1406 // Note: content::OverlayWindow::Create() is defined by platform-specific
1407 // implementation in chrome/browser/ui/views. This layering hack, which goes
1408 // through //content and ContentBrowserClient, allows us to work around the
1409 // dependency constraints that disallow directly calling
1410 // chrome/browser/ui/views code either from here or from other code in
1411 // chrome/browser.
1412 return content::OverlayWindow::Create(controller);
1413 }
1414
RegisterBrowserInterfaceBindersForFrame(content::RenderFrameHost * render_frame_host,mojo::BinderMapWithContext<content::RenderFrameHost * > * map)1415 void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
1416 content::RenderFrameHost* render_frame_host,
1417 mojo::BinderMapWithContext<content::RenderFrameHost*>* map) {
1418 CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host,
1419 map);
1420
1421 if (!extensions::ExtensionsEnabled())
1422 return;
1423
1424 content::WebContents* web_contents =
1425 content::WebContents::FromRenderFrameHost(render_frame_host);
1426 if (!web_contents)
1427 return;
1428
1429 const GURL& site = render_frame_host->GetSiteInstance()->GetSiteURL();
1430 if (!site.SchemeIs(extensions::kExtensionScheme))
1431 return;
1432
1433 content::BrowserContext* browser_context =
1434 render_frame_host->GetProcess()->GetBrowserContext();
1435 auto* extension = extensions::ExtensionRegistry::Get(browser_context)
1436 ->enabled_extensions()
1437 .GetByID(site.host());
1438 if (!extension)
1439 return;
1440 extensions::ExtensionsBrowserClient::Get()
1441 ->RegisterBrowserInterfaceBindersForFrame(map, render_frame_host,
1442 extension);
1443 }
1444
1445 base::FilePath
GetSandboxedStorageServiceDataDirectory()1446 AlloyContentBrowserClient::GetSandboxedStorageServiceDataDirectory() {
1447 return GetRootCachePath();
1448 }
1449
GetProduct()1450 std::string AlloyContentBrowserClient::GetProduct() {
1451 return embedder_support::GetProduct();
1452 }
1453
GetChromeProduct()1454 std::string AlloyContentBrowserClient::GetChromeProduct() {
1455 return version_info::GetProductNameAndVersionForUserAgent();
1456 }
1457
GetUserAgent()1458 std::string AlloyContentBrowserClient::GetUserAgent() {
1459 return embedder_support::GetUserAgent();
1460 }
1461
GetReducedUserAgent()1462 std::string AlloyContentBrowserClient::GetReducedUserAgent() {
1463 return embedder_support::GetReducedUserAgent();
1464 }
1465
GetUserAgentMetadata()1466 blink::UserAgentMetadata AlloyContentBrowserClient::GetUserAgentMetadata() {
1467 blink::UserAgentMetadata metadata;
1468
1469 metadata.brand_version_list = {blink::UserAgentBrandVersion{
1470 version_info::GetProductName(), version_info::GetMajorVersionNumber()}};
1471 metadata.full_version = version_info::GetVersionNumber();
1472 metadata.platform = version_info::GetOSType();
1473
1474 // TODO(mkwst): Poke at BuildUserAgentFromProduct to split out these pieces.
1475 metadata.architecture = "";
1476 metadata.model = "";
1477
1478 return metadata;
1479 }
1480
1481 base::flat_set<std::string>
GetPluginMimeTypesWithExternalHandlers(content::BrowserContext * browser_context)1482 AlloyContentBrowserClient::GetPluginMimeTypesWithExternalHandlers(
1483 content::BrowserContext* browser_context) {
1484 base::flat_set<std::string> mime_types;
1485 auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
1486 for (const auto& pair : map)
1487 mime_types.insert(pair.first);
1488 if (pdf::IsInternalPluginExternallyHandled())
1489 mime_types.insert(pdf::kInternalPluginMimeType);
1490 return mime_types;
1491 }
1492
ArePersistentMediaDeviceIDsAllowed(content::BrowserContext * browser_context,const GURL & url,const net::SiteForCookies & site_for_cookies,const absl::optional<url::Origin> & top_frame_origin)1493 bool AlloyContentBrowserClient::ArePersistentMediaDeviceIDsAllowed(
1494 content::BrowserContext* browser_context,
1495 const GURL& url,
1496 const net::SiteForCookies& site_for_cookies,
1497 const absl::optional<url::Origin>& top_frame_origin) {
1498 // Persistent MediaDevice IDs are allowed if cookies are allowed.
1499 return CookieSettingsFactory::GetForProfile(
1500 Profile::FromBrowserContext(browser_context))
1501 ->IsFullCookieAccessAllowed(url, site_for_cookies, top_frame_origin);
1502 }
1503
ShouldAllowPluginCreation(const url::Origin & embedder_origin,const content::PepperPluginInfo & plugin_info)1504 bool AlloyContentBrowserClient::ShouldAllowPluginCreation(
1505 const url::Origin& embedder_origin,
1506 const content::PepperPluginInfo& plugin_info) {
1507 if (plugin_info.name == ChromeContentClient::kPDFInternalPluginName) {
1508 return IsPdfInternalPluginAllowedOrigin(embedder_origin);
1509 }
1510
1511 return true;
1512 }
1513
OnWebContentsCreated(content::WebContents * web_contents)1514 void AlloyContentBrowserClient::OnWebContentsCreated(
1515 content::WebContents* web_contents) {
1516 // Attach universal WebContentsObservers. These are quite rare, and in most
1517 // cases CefBrowserPlatformDelegateAlloy::BrowserCreated and/or
1518 // CefExtensionsAPIClient::AttachWebContentsHelpers should be used instead.
1519
1520 if (extensions::ExtensionsEnabled()) {
1521 extensions::CefExtensionWebContentsObserver::CreateForWebContents(
1522 web_contents);
1523 }
1524 }
1525
IsFindInPageDisabledForOrigin(const url::Origin & origin)1526 bool AlloyContentBrowserClient::IsFindInPageDisabledForOrigin(
1527 const url::Origin& origin) {
1528 // For PDF viewing with the PPAPI-free PDF Viewer, find-in-page should only
1529 // display results from the PDF content, and not from the UI.
1530 return base::FeatureList::IsEnabled(chrome_pdf::features::kPdfUnseasoned) &&
1531 IsPdfExtensionOrigin(origin);
1532 }
1533
request_context() const1534 CefRefPtr<CefRequestContextImpl> AlloyContentBrowserClient::request_context()
1535 const {
1536 return browser_main_parts_->request_context();
1537 }
1538
devtools_delegate() const1539 CefDevToolsDelegate* AlloyContentBrowserClient::devtools_delegate() const {
1540 return browser_main_parts_->devtools_delegate();
1541 }
1542
1543 scoped_refptr<base::SingleThreadTaskRunner>
background_task_runner() const1544 AlloyContentBrowserClient::background_task_runner() const {
1545 return browser_main_parts_->background_task_runner();
1546 }
1547
1548 scoped_refptr<base::SingleThreadTaskRunner>
user_visible_task_runner() const1549 AlloyContentBrowserClient::user_visible_task_runner() const {
1550 return browser_main_parts_->user_visible_task_runner();
1551 }
1552
1553 scoped_refptr<base::SingleThreadTaskRunner>
user_blocking_task_runner() const1554 AlloyContentBrowserClient::user_blocking_task_runner() const {
1555 return browser_main_parts_->user_blocking_task_runner();
1556 }
1557
GetExtension(content::SiteInstance * site_instance)1558 const extensions::Extension* AlloyContentBrowserClient::GetExtension(
1559 content::SiteInstance* site_instance) {
1560 extensions::ExtensionRegistry* registry =
1561 extensions::ExtensionRegistry::Get(site_instance->GetBrowserContext());
1562 if (!registry)
1563 return nullptr;
1564 return registry->enabled_extensions().GetExtensionOrAppByURL(
1565 site_instance->GetSiteURL());
1566 }
1567