// Copyright (c) 2013 GitHub, Inc. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. #ifndef SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_ #define SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_ #include #include #include #include #include #include "base/files/file_path.h" #include "base/synchronization/lock.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/web_contents.h" #include "electron/buildflags/buildflags.h" #include "net/ssl/client_cert_identity.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "shell/browser/bluetooth/electron_bluetooth_delegate.h" #include "shell/browser/serial/electron_serial_delegate.h" namespace content { class ClientCertificateDelegate; class QuotaPermissionContext; } // namespace content namespace net { class SSLCertRequestInfo; } namespace electron { class NotificationPresenter; class PlatformNotificationService; class ElectronBrowserClient : public content::ContentBrowserClient, public content::RenderProcessHostObserver { public: static ElectronBrowserClient* Get(); static void SetApplicationLocale(const std::string& locale); ElectronBrowserClient(); ~ElectronBrowserClient() override; using Delegate = content::ContentBrowserClient; void set_delegate(Delegate* delegate) { delegate_ = delegate; } // Returns the WebContents for pending render processes. content::WebContents* GetWebContentsFromProcessID(int process_id); // Don't force renderer process to restart for once. static void SuppressRendererProcessRestartForOnce(); NotificationPresenter* GetNotificationPresenter(); void WebNotificationAllowed(int render_process_id, base::OnceCallback callback); // content::NavigatorDelegate std::vector> CreateThrottlesForNavigation(content::NavigationHandle* handle) override; // content::ContentBrowserClient: std::string GetApplicationLocale() override; base::FilePath GetFontLookupTableCacheDir() override; bool ShouldEnableStrictSiteIsolation() override; void BindHostReceiverForRenderer( content::RenderProcessHost* render_process_host, mojo::GenericPendingReceiver receiver) override; void RegisterBrowserInterfaceBindersForFrame( content::RenderFrameHost* render_frame_host, mojo::BinderMapWithContext* map) override; void BindBadgeServiceReceiverFromServiceWorker( content::RenderProcessHost* service_worker_process_host, const GURL& service_worker_scope, mojo::PendingReceiver receiver) override; #if defined(OS_LINUX) void GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings) override; #endif std::string GetUserAgent() override; void SetUserAgent(const std::string& user_agent); void SetCanUseCustomSiteInstance(bool should_disable); bool CanUseCustomSiteInstance() override; content::SerialDelegate* GetSerialDelegate() override; content::BluetoothDelegate* GetBluetoothDelegate() override; protected: void RenderProcessWillLaunch(content::RenderProcessHost* host) override; content::SpeechRecognitionManagerDelegate* CreateSpeechRecognitionManagerDelegate() override; content::TtsPlatform* GetTtsPlatform() override; void OverrideWebkitPrefs(content::WebContents* web_contents, blink::web_pref::WebPreferences* prefs) override; SiteInstanceForNavigationType ShouldOverrideSiteInstanceForNavigation( content::RenderFrameHost* current_rfh, content::RenderFrameHost* speculative_rfh, content::BrowserContext* browser_context, const GURL& url, bool has_navigation_started, bool has_response_started, content::SiteInstance** affinity_site_instance) const override; void RegisterPendingSiteInstance( content::RenderFrameHost* render_frame_host, content::SiteInstance* pending_site_instance) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; std::string GetGeolocationApiKey() override; scoped_refptr CreateQuotaPermissionContext() override; content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; void 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 callback) override; base::OnceClosure SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, std::unique_ptr delegate) override; bool 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, const std::string& raw_features, const scoped_refptr& body, bool user_gesture, bool opener_suppressed, bool* no_javascript_access) override; #if BUILDFLAG(ENABLE_PICTURE_IN_PICTURE) std::unique_ptr CreateWindowForPictureInPicture( content::PictureInPictureWindowController* controller) override; #endif void GetAdditionalAllowedSchemesForFileSystem( std::vector* additional_schemes) override; void GetAdditionalWebUISchemes( std::vector* additional_schemes) override; void SiteInstanceDeleting(content::SiteInstance* site_instance) override; std::unique_ptr CreateClientCertStore( content::BrowserContext* browser_context) override; std::unique_ptr OverrideSystemLocationProvider() override; void ConfigureNetworkContextParams( content::BrowserContext* browser_context, bool in_memory, const base::FilePath& relative_partition_path, network::mojom::NetworkContextParams* network_context_params, network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) override; network::mojom::NetworkContext* GetSystemNetworkContext() override; content::MediaObserver* GetMediaObserver() override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; content::PlatformNotificationService* GetPlatformNotificationService( content::BrowserContext* browser_context) override; std::unique_ptr CreateBrowserMainParts( const content::MainFunctionParams&) override; base::FilePath GetDefaultDownloadDirectory() override; scoped_refptr GetSystemSharedURLLoaderFactory() override; void OnNetworkServiceCreated( network::mojom::NetworkService* network_service) override; std::vector GetNetworkContextsParentDirectory() override; std::string GetProduct() override; void RegisterNonNetworkNavigationURLLoaderFactories( int frame_tree_node_id, ukm::SourceIdObj ukm_source_id, NonNetworkURLLoaderFactoryMap* factories) override; void RegisterNonNetworkWorkerMainResourceURLLoaderFactories( content::BrowserContext* browser_context, NonNetworkURLLoaderFactoryMap* factories) override; void RegisterNonNetworkSubresourceURLLoaderFactories( int render_process_id, int render_frame_id, NonNetworkURLLoaderFactoryMap* factories) override; void CreateWebSocket( content::RenderFrameHost* frame, WebSocketFactory factory, const GURL& url, const net::SiteForCookies& site_for_cookies, const base::Optional& user_agent, mojo::PendingRemote handshake_client) override; bool WillInterceptWebSocket(content::RenderFrameHost*) override; bool WillCreateURLLoaderFactory( content::BrowserContext* browser_context, content::RenderFrameHost* frame, int render_process_id, URLLoaderFactoryType type, const url::Origin& request_initiator, base::Optional navigation_id, ukm::SourceIdObj ukm_source_id, mojo::PendingReceiver* factory_receiver, mojo::PendingRemote* header_client, bool* bypass_redirect_checks, bool* disable_secure_dns, network::mojom::URLLoaderFactoryOverridePtr* factory_override) override; bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel( base::StringPiece scheme, bool is_embedded_origin_secure) override; void OverrideURLLoaderFactoryParams( content::BrowserContext* browser_context, const url::Origin& origin, bool is_for_isolated_world, network::mojom::URLLoaderFactoryParams* factory_params) override; #if defined(OS_WIN) bool PreSpawnChild(sandbox::TargetPolicy* policy, sandbox::policy::SandboxType sandbox_type, ChildSpawnFlags flags) override; #endif bool BindAssociatedReceiverFromFrame( content::RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedInterfaceEndpointHandle* handle) override; bool HandleExternalProtocol( const GURL& url, content::WebContents::OnceGetter web_contents_getter, int child_id, content::NavigationUIData* navigation_data, bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture, const base::Optional& initiating_origin, mojo::PendingRemote* out_factory) override; std::unique_ptr CreateLoginDelegate( const net::AuthChallengeInfo& auth_info, content::WebContents* web_contents, const content::GlobalRequestID& request_id, bool is_main_frame, const GURL& url, scoped_refptr response_headers, bool first_auth_attempt, LoginAuthRequiredCallback auth_required_callback) override; void SiteInstanceGotProcess(content::SiteInstance* site_instance) override; std::vector> CreateURLLoaderThrottles( const network::ResourceRequest& request, content::BrowserContext* browser_context, const base::RepeatingCallback& wc_getter, content::NavigationUIData* navigation_ui_data, int frame_tree_node_id) override; base::flat_set GetPluginMimeTypesWithExternalHandlers( content::BrowserContext* browser_context) override; bool IsSuitableHost(content::RenderProcessHost* process_host, const GURL& site_url) override; bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url) override; bool ArePersistentMediaDeviceIDsAllowed( content::BrowserContext* browser_context, const GURL& scope, const GURL& site_for_cookies, const base::Optional& top_frame_origin) override; // content::RenderProcessHostObserver: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; void RenderProcessReady(content::RenderProcessHost* host) override; void RenderProcessExited( content::RenderProcessHost* host, const content::ChildProcessTerminationInfo& info) override; private: struct ProcessPreferences { bool sandbox = false; bool native_window_open = false; bool disable_popups = false; bool web_security = true; content::BrowserContext* browser_context = nullptr; }; bool ShouldForceNewSiteInstance(content::RenderFrameHost* current_rfh, content::RenderFrameHost* speculative_rfh, content::BrowserContext* browser_context, const GURL& dest_url, bool has_response_started) const; bool NavigationWasRedirectedCrossSite( content::BrowserContext* browser_context, content::SiteInstance* current_instance, content::SiteInstance* speculative_instance, const GURL& dest_url, bool has_response_started) const; void AddProcessPreferences(int process_id, ProcessPreferences prefs); void RemoveProcessPreferences(int process_id); bool IsProcessObserved(int process_id) const; bool IsRendererSandboxed(int process_id) const; bool RendererUsesNativeWindowOpen(int process_id) const; bool RendererDisablesPopups(int process_id) const; std::string GetAffinityPreference(content::RenderFrameHost* rfh) const; content::SiteInstance* GetSiteInstanceFromAffinity( content::BrowserContext* browser_context, const GURL& url, content::RenderFrameHost* rfh) const; void ConsiderSiteInstanceForAffinity(content::RenderFrameHost* rfh, content::SiteInstance* site_instance); bool IsRendererSubFrame(int process_id) const; // pending_render_process => web contents. std::map pending_processes_; std::set renderer_is_subframe_; // list of site per affinity. weak_ptr to prevent instance locking std::map site_per_affinities_; std::unique_ptr notification_service_; std::unique_ptr notification_presenter_; Delegate* delegate_ = nullptr; std::map process_preferences_; std::string user_agent_override_ = ""; bool disable_process_restart_tricks_ = true; // Simple shared ID generator, used by ProxyingURLLoaderFactory and // ProxyingWebSocket classes. uint64_t next_id_ = 0; std::unique_ptr serial_delegate_; std::unique_ptr bluetooth_delegate_; DISALLOW_COPY_AND_ASSIGN(ElectronBrowserClient); }; } // namespace electron #endif // SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_