mirror of
https://github.com/electron/electron.git
synced 2026-10-28 11:44:46 +08:00
* test: emulate the position in the geolocation permission-granted spec The test only ran on official builds, because other builds replace the system location provider with FakeLocationProvider, which always reports an error. On official builds it queried the real network location service, which fails on CI with "Failed to query location from network service." Set the position with the DevTools Emulation.setGeolocationOverride command instead, so the test runs on every build and doesn't depend on the network. The permission request still goes through the session's handler, and the test now checks that it did and that the emulated coordinates come back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: remove FakeLocationProvider It was added to mock geolocation responses in tests. The geolocation spec now sets the position with Emulation.setGeolocationOverride instead, so the fake provider, the enable_fake_location_provider GN arg, and the OVERRIDE_LOCATION_PROVIDER buildflag are no longer needed. The permission-denied spec no longer depends on the fake provider: a denied request fails before any provider is queried. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
429 lines
18 KiB
C++
429 lines
18 KiB
C++
// 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 ELECTRON_SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_
|
|
#define ELECTRON_SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/containers/flat_map.h"
|
|
#include "base/containers/flat_set.h"
|
|
#include "base/memory/raw_ptr.h"
|
|
#include "base/memory/weak_ptr.h"
|
|
#include "content/public/browser/content_browser_client.h"
|
|
#include "content/public/browser/frame_tree_node_id.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"
|
|
|
|
namespace base {
|
|
class FilePath;
|
|
} // namespace base
|
|
|
|
namespace content {
|
|
class ClientCertificateDelegate;
|
|
class NavigationHandle;
|
|
class PlatformNotificationService;
|
|
class NavigationThrottleRegistry;
|
|
} // namespace content
|
|
|
|
namespace net {
|
|
class SSLCertRequestInfo;
|
|
}
|
|
|
|
namespace electron {
|
|
|
|
class ElectronBluetoothDelegate;
|
|
class ElectronHidDelegate;
|
|
class ElectronSerialDelegate;
|
|
class ElectronUsbDelegate;
|
|
class ElectronWebAuthenticationDelegate;
|
|
class NotificationPresenter;
|
|
class PlatformNotificationService;
|
|
|
|
class ElectronBrowserClient : public content::ContentBrowserClient,
|
|
private content::RenderProcessHostObserver {
|
|
public:
|
|
static ElectronBrowserClient* Get();
|
|
static void SetApplicationLocale(const std::string& locale);
|
|
|
|
ElectronBrowserClient();
|
|
~ElectronBrowserClient() override;
|
|
|
|
// disable copy
|
|
ElectronBrowserClient(const ElectronBrowserClient&) = delete;
|
|
ElectronBrowserClient& operator=(const ElectronBrowserClient&) = delete;
|
|
|
|
using Delegate = content::ContentBrowserClient;
|
|
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
|
|
|
|
// Returns the WebContents for pending render processes.
|
|
content::WebContents* GetWebContentsFromProcessID(
|
|
content::ChildProcessId process_id);
|
|
|
|
// Whether the given renderer process was launched with the OS sandbox
|
|
// enabled. Returns nullopt if the launch state of the process is unknown.
|
|
std::optional<bool> IsRendererProcessSandboxed(
|
|
content::ChildProcessId process_id) const;
|
|
|
|
NotificationPresenter* GetNotificationPresenter();
|
|
|
|
void WebNotificationAllowed(content::RenderFrameHost* rfh,
|
|
base::OnceCallback<void(bool, bool)> callback);
|
|
|
|
// content::NavigatorDelegate
|
|
void CreateThrottlesForNavigation(
|
|
content::NavigationThrottleRegistry& registry) override;
|
|
|
|
// content::ContentBrowserClient:
|
|
std::string GetApplicationLocale() override;
|
|
bool* spare_renderer_compatible() { return &spare_renderer_compatible_; }
|
|
|
|
// Ids handed out as webRequest details.id, shared by every proxy and gate.
|
|
uint64_t NextWebRequestId() { return ++next_id_; }
|
|
|
|
bool ShouldEnableStrictSiteIsolation() override;
|
|
bool ShouldUseSpareRenderProcessHost(
|
|
content::BrowserContext* browser_context,
|
|
const GURL& site_url,
|
|
std::optional<
|
|
content::ContentBrowserClient::SpareProcessRefusedByEmbedderReason>&
|
|
refused_reason) override;
|
|
bool ShouldEnableSubframeZoom() override;
|
|
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
|
std::optional<network::CrossOriginEmbedderPolicy>
|
|
MaybeOverrideLocalURLCrossOriginEmbedderPolicy(
|
|
content::NavigationHandle* navigation_handle) override;
|
|
bool IsCrossOriginSubframeAllowedToShowFilePicker(
|
|
content::RenderFrameHost* render_frame_host,
|
|
const url::Origin& requesting_origin) override;
|
|
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
|
bool DoesSiteRequireDedicatedProcess(content::BrowserContext* browser_context,
|
|
const GURL& effective_site_url) override;
|
|
void BindHostReceiverForRenderer(
|
|
content::RenderProcessHost* render_process_host,
|
|
mojo::GenericPendingReceiver receiver) override;
|
|
void ExposeInterfacesToRenderer(
|
|
service_manager::BinderRegistry* registry,
|
|
blink::AssociatedInterfaceRegistry* associated_registry,
|
|
content::RenderProcessHost* render_process_host) override;
|
|
void RegisterBrowserInterfaceBindersForFrame(
|
|
content::RenderFrameHost* render_frame_host,
|
|
mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override;
|
|
void RegisterBrowserInterfaceBindersForServiceWorker(
|
|
content::BrowserContext* browser_context,
|
|
const content::ServiceWorkerVersionBaseInfo& service_worker_version_info,
|
|
mojo::BinderMapWithContext<const content::ServiceWorkerVersionBaseInfo&>*
|
|
map) override;
|
|
#if BUILDFLAG(IS_LINUX)
|
|
void GetAdditionalMappedFilesForChildProcess(
|
|
const base::CommandLine& command_line,
|
|
int child_process_id,
|
|
content::PosixFileDescriptorInfo* mappings) override;
|
|
#endif
|
|
bool IsFullscreenAllowedForUnfocusedWebContents(
|
|
content::WebContents* unfocused_web_contents) override;
|
|
|
|
std::string GetUserAgent() override;
|
|
void SetUserAgent(const std::string& user_agent);
|
|
blink::UserAgentMetadata GetUserAgentMetadata() override;
|
|
|
|
content::SerialDelegate* GetSerialDelegate() override;
|
|
|
|
content::BluetoothDelegate* GetBluetoothDelegate() override;
|
|
|
|
content::HidDelegate* GetHidDelegate() override;
|
|
content::UsbDelegate* GetUsbDelegate() override;
|
|
|
|
content::WebAuthenticationDelegate* GetWebAuthenticationDelegate() override;
|
|
#if !BUILDFLAG(IS_ANDROID)
|
|
std::unique_ptr<content::AuthenticatorRequestClientDelegate>
|
|
GetWebAuthenticationRequestDelegate(
|
|
content::RenderFrameHost* render_frame_host) override;
|
|
#endif
|
|
|
|
#if BUILDFLAG(IS_MAC)
|
|
base::FilePath GetChildProcessPath(int child_flags) override;
|
|
device::GeolocationSystemPermissionManager*
|
|
GetGeolocationSystemPermissionManager() override;
|
|
#endif
|
|
|
|
content::PlatformNotificationService* GetPlatformNotificationService();
|
|
|
|
// content::ContentBrowserClient overrides exposed for net-module client
|
|
// certificate handling (see ClientCertificateResponderDelegate).
|
|
base::OnceClosure SelectClientCertificate(
|
|
content::BrowserContext* browser_context,
|
|
int process_id,
|
|
content::WebContents* web_contents,
|
|
net::SSLCertRequestInfo* cert_request_info,
|
|
net::ClientCertIdentityList client_certs,
|
|
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
|
|
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
|
|
content::BrowserContext* browser_context) override;
|
|
|
|
protected:
|
|
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
|
content::SpeechRecognitionManagerDelegate*
|
|
CreateSpeechRecognitionManagerDelegate() override;
|
|
content::TtsPlatform* GetTtsPlatform() override;
|
|
|
|
void OverrideWebPreferences(content::WebContents* web_contents,
|
|
content::SiteInstance& main_frame_site,
|
|
blink::web_pref::WebPreferences* prefs) override;
|
|
bool WebPreferencesNeedUpdateForColorRelatedStateChanges(
|
|
content::WebContents& web_contents,
|
|
const content::SiteInstance& main_frame_site) 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;
|
|
std::string GetGeolocationApiKey() 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<void(content::CertificateRequestResultType)> callback)
|
|
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<network::ResourceRequestBody>& body,
|
|
bool user_gesture,
|
|
bool opener_suppressed,
|
|
bool* no_javascript_access) override;
|
|
std::optional<mojo_base::BigBuffer> GetExtraCreateNewWindowReplyData(
|
|
content::RenderFrameHost* new_window_main_frame,
|
|
const GURL& target_url) override;
|
|
std::optional<mojo_base::BigBuffer> GetServiceWorkerStartupData(
|
|
content::BrowserContext* browser_context,
|
|
const GURL& scope) override;
|
|
std::unique_ptr<content::VideoOverlayWindow>
|
|
CreateWindowForVideoPictureInPicture(
|
|
content::VideoPictureInPictureWindowController* controller) override;
|
|
void GetAdditionalAllowedSchemesForFileSystem(
|
|
std::vector<std::string>* additional_schemes) override;
|
|
void GetAdditionalWebUISchemes(
|
|
std::vector<std::string>* additional_schemes) override;
|
|
void ConfigureNetworkContextParams(
|
|
content::BrowserContext* browser_context,
|
|
bool in_memory,
|
|
const base::FilePath& relative_partition_path,
|
|
network::mojom::NetworkContextParams* network_context_params,
|
|
cert_verifier::mojom::CertVerifierCreationParams*
|
|
cert_verifier_creation_params) override;
|
|
network::mojom::NetworkContext* GetSystemNetworkContext() override;
|
|
content::MediaObserver* GetMediaObserver() override;
|
|
std::unique_ptr<content::DevToolsManagerDelegate>
|
|
CreateDevToolsManagerDelegate() override;
|
|
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(
|
|
bool /* is_integration_test */) override;
|
|
base::FilePath GetDefaultDownloadDirectory() override;
|
|
base::FilePath GetShaderDiskCacheDirectory() override;
|
|
base::FilePath GetGrShaderDiskCacheDirectory() override;
|
|
base::FilePath GetGraphiteDawnDiskCacheDirectory() override;
|
|
base::FilePath GetGPUPersistentCacheDirectory() override;
|
|
scoped_refptr<network::SharedURLLoaderFactory>
|
|
GetSystemSharedURLLoaderFactory() override;
|
|
void OnNetworkServiceCreated(
|
|
network::mojom::NetworkService* network_service) override;
|
|
std::vector<base::FilePath> GetNetworkContextsParentDirectory() override;
|
|
std::string GetProduct() override;
|
|
std::unique_ptr<content::TracingDelegate> CreateTracingDelegate() override;
|
|
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
|
CreateNonNetworkNavigationURLLoaderFactory(
|
|
const std::string& scheme,
|
|
content::FrameTreeNodeId frame_tree_node_id) override;
|
|
void RegisterNonNetworkWorkerMainResourceURLLoaderFactories(
|
|
content::BrowserContext* browser_context,
|
|
const std::optional<url::Origin>& request_initiator,
|
|
network::mojom::RequestDestination request_destination,
|
|
NonNetworkURLLoaderFactoryMap* factories) override;
|
|
void RegisterNonNetworkSubresourceURLLoaderFactories(
|
|
int render_process_id,
|
|
int render_frame_id,
|
|
const std::optional<url::Origin>& request_initiator_origin,
|
|
NonNetworkURLLoaderFactoryMap* factories) override;
|
|
void RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(
|
|
content::BrowserContext* browser_context,
|
|
NonNetworkURLLoaderFactoryMap* factories) override;
|
|
void CreateWebSocket(
|
|
content::RenderFrameHost* frame,
|
|
WebSocketFactory factory,
|
|
const GURL& url,
|
|
const net::SiteForCookies& site_for_cookies,
|
|
const std::optional<std::string>& user_agent,
|
|
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
|
handshake_client,
|
|
WebSocketOptions options) override;
|
|
bool WillInterceptWebSocket(content::RenderFrameHost*) override;
|
|
void WillCreateURLLoaderFactory(
|
|
content::BrowserContext* browser_context,
|
|
content::RenderFrameHost* frame,
|
|
int render_process_id,
|
|
URLLoaderFactoryType type,
|
|
const url::Origin& request_initiator,
|
|
const net::IsolationInfo& isolation_info,
|
|
std::optional<int64_t> navigation_id,
|
|
ukm::SourceIdObj ukm_source_id,
|
|
network::URLLoaderFactoryBuilder& factory_builder,
|
|
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
|
|
header_client,
|
|
bool* bypass_redirect_checks,
|
|
bool* disable_secure_dns,
|
|
network::mojom::URLLoaderFactoryOverridePtr* factory_override,
|
|
scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner,
|
|
bool is_for_network_service) override;
|
|
std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
|
|
WillCreateURLLoaderRequestInterceptors(
|
|
content::NavigationUIData* navigation_ui_data,
|
|
content::FrameTreeNodeId frame_tree_node_id,
|
|
int64_t navigation_id,
|
|
bool force_no_https_upgrade,
|
|
scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner)
|
|
override;
|
|
bool ShouldTreatAsFirstPartyWhenTopLevel(
|
|
const url::Origin& top_frame_origin,
|
|
bool is_embedded_origin_secure) override;
|
|
void OverrideURLLoaderFactoryParams(
|
|
content::BrowserContext* browser_context,
|
|
const url::Origin& origin,
|
|
bool is_for_isolated_world,
|
|
bool is_for_service_worker,
|
|
network::mojom::URLLoaderFactoryParams* factory_params) override;
|
|
void RegisterAssociatedInterfaceBindersForRenderFrameHost(
|
|
content::RenderFrameHost& render_frame_host,
|
|
blink::AssociatedInterfaceRegistry& associated_registry) override;
|
|
void RegisterAssociatedInterfaceBindersForServiceWorker(
|
|
const content::ServiceWorkerVersionBaseInfo& service_worker_version_info,
|
|
blink::AssociatedInterfaceRegistry& associated_registry) override;
|
|
|
|
#if BUILDFLAG(ENABLE_PROMPT_API)
|
|
void BindAIManager(
|
|
content::BrowserContext* browser_context,
|
|
base::SupportsUserData* context_user_data,
|
|
content::RenderFrameHost* rfh,
|
|
mojo::PendingReceiver<blink::mojom::AIManager> receiver) override;
|
|
#endif // BUILDFLAG(ENABLE_PROMPT_API)
|
|
|
|
bool HandleExternalProtocol(
|
|
const GURL& url,
|
|
content::WebContents::Getter web_contents_getter,
|
|
content::FrameTreeNodeId frame_tree_node_id,
|
|
content::NavigationUIData* navigation_data,
|
|
bool is_primary_main_frame,
|
|
bool is_in_fenced_frame_tree,
|
|
network::mojom::WebSandboxFlags sandbox_flags,
|
|
ui::PageTransition page_transition,
|
|
bool has_user_gesture,
|
|
const std::optional<url::Origin>& initiating_origin,
|
|
content::RenderFrameHost* initiator_document,
|
|
const net::IsolationInfo& isolation_info,
|
|
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory)
|
|
override;
|
|
std::unique_ptr<content::LoginDelegate> CreateLoginDelegate(
|
|
const net::AuthChallengeInfo& auth_info,
|
|
content::WebContents* web_contents,
|
|
content::BrowserContext* browser_context,
|
|
const content::GlobalRequestID& request_id,
|
|
bool is_request_for_primary_main_frame,
|
|
bool is_request_for_navigation,
|
|
const GURL& url,
|
|
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
|
bool first_auth_attempt,
|
|
bool do_not_prompt_for_login,
|
|
content::GuestPageHolder* guest_page_holder,
|
|
content::LoginDelegate::LoginAuthRequiredCallback auth_required_callback)
|
|
override;
|
|
void SiteInstanceGotProcessAndSite(
|
|
content::SiteInstance* site_instance) override;
|
|
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,
|
|
content::FrameTreeNodeId frame_tree_node_id,
|
|
std::optional<int64_t> navigation_id) override;
|
|
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(
|
|
content::BrowserContext* browser_context) override;
|
|
bool IsSuitableHost(
|
|
content::RenderProcessHost* process_host,
|
|
const content::SecurityPrincipal& security_principal) override;
|
|
bool ShouldUseProcessPerSite(
|
|
content::BrowserContext* browser_context,
|
|
const content::SecurityPrincipal& security_principal) override;
|
|
void GetMediaDeviceIDSalt(
|
|
content::RenderFrameHost* rfh,
|
|
const net::SiteForCookies& site_for_cookies,
|
|
const blink::StorageKey& storage_key,
|
|
base::OnceCallback<void(bool, const std::string&)> callback) override;
|
|
base::FilePath GetLoggingFileName(const base::CommandLine& cmd_line) 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:
|
|
bool IsRendererSubFrame(content::ChildProcessId process_id) const;
|
|
|
|
// What ShouldUseSpareRenderProcessHost() answers: set around
|
|
// content::WebContents::Create() from the constructor options and around
|
|
// RegisterPendingSiteInstance() from the WebContents being given a process.
|
|
bool spare_renderer_compatible_ = false;
|
|
|
|
// pending_render_process => web contents.
|
|
base::flat_map<content::ChildProcessId, base::WeakPtr<content::WebContents>>
|
|
pending_processes_;
|
|
|
|
base::flat_set<content::ChildProcessId> renderer_is_subframe_;
|
|
|
|
// Sandbox state each renderer process was launched with.
|
|
base::flat_map<content::ChildProcessId, bool> renderer_process_sandboxed_;
|
|
|
|
std::unique_ptr<PlatformNotificationService> notification_service_;
|
|
std::unique_ptr<NotificationPresenter> notification_presenter_;
|
|
|
|
raw_ptr<Delegate> delegate_ = nullptr;
|
|
|
|
std::string user_agent_override_ = "";
|
|
|
|
// Simple shared ID generator, used by ProxyingURLLoaderFactory and
|
|
// ProxyingWebSocket classes.
|
|
uint64_t next_id_ = 0;
|
|
|
|
std::unique_ptr<ElectronSerialDelegate> serial_delegate_;
|
|
std::unique_ptr<ElectronBluetoothDelegate> bluetooth_delegate_;
|
|
std::unique_ptr<ElectronUsbDelegate> usb_delegate_;
|
|
std::unique_ptr<ElectronHidDelegate> hid_delegate_;
|
|
std::unique_ptr<ElectronWebAuthenticationDelegate>
|
|
web_authentication_delegate_;
|
|
};
|
|
|
|
} // namespace electron
|
|
|
|
#endif // ELECTRON_SHELL_BROWSER_ELECTRON_BROWSER_CLIENT_H_
|