• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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