// Copyright 2013 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_RENDERER_RENDER_FRAME_IMPL_H_ #define CONTENT_RENDERER_RENDER_FRAME_IMPL_H_ #include #include #include #include #include #include #include #include #include #include "base/callback.h" #include "base/containers/id_map.h" #include "base/files/file_path.h" #include "base/gtest_prod_util.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/process/process_handle.h" #include "base/task/single_thread_task_runner.h" #include "base/timer/timer.h" #include "base/unguessable_token.h" #include "build/build_config.h" #include "cc/input/browser_controls_state.h" #include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/download/mhtml_file_writer.mojom.h" #include "content/common/frame.mojom.h" #include "content/common/navigation_client.mojom.h" #include "content/common/renderer.mojom.h" #include "content/common/web_ui.mojom.h" #include "content/public/common/alternative_error_page_override_info.mojom.h" #include "content/public/common/extra_mojo_js_features.mojom.h" #include "content/public/common/referrer.h" #include "content/public/common/stop_find_action.h" #include "content/public/common/widget_type.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_media_playback_options.h" #include "content/renderer/content_security_policy_util.h" #include "content/renderer/media/media_factory.h" #include "ipc/ipc_message.h" #include "ipc/ipc_platform_file.h" #include "media/base/routing_token_callback.h" #include "media/base/speech_recognition_client.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe.h" #include "ppapi/buildflags/buildflags.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/public/mojom/url_response_head.mojom-forward.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/loader/loading_behavior_flag.h" #include "third_party/blink/public/common/permissions_policy/document_policy.h" #include "third_party/blink/public/common/permissions_policy/permissions_policy.h" #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/common/unique_name/unique_name_helper.h" #include "third_party/blink/public/mojom/autoplay/autoplay.mojom.h" #include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom.h" #include "third_party/blink/public/mojom/browser_interface_broker.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/commit_result/commit_result.mojom.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-forward.h" #include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h" #include "third_party/blink/public/mojom/frame/policy_container.mojom-shared.h" #include "third_party/blink/public/mojom/frame/triggering_event_info.mojom-shared.h" #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-forward.h" #include "third_party/blink/public/mojom/loader/code_cache.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom.h" #include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom-forward.h" #include "third_party/blink/public/mojom/render_accessibility.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom.h" #include "third_party/blink/public/platform/child_url_loader_factory_bundle.h" #include "third_party/blink/public/platform/web_media_player.h" #include "third_party/blink/public/platform/websocket_handshake_throttle_provider.h" #include "third_party/blink/public/web/web_ax_object.h" #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_frame_load_type.h" #include "third_party/blink/public/web/web_frame_serializer_client.h" #include "third_party/blink/public/web/web_history_commit_type.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/public/web/web_meaningful_layout.h" #include "ui/accessibility/ax_event.h" #include "ui/accessibility/ax_mode.h" #include "ui/accessibility/ax_node_id_forward.h" #include "ui/gfx/range/range.h" #include "url/gurl.h" #include "url/origin.h" #include "v8/include/v8-forward.h" #if BUILDFLAG(ENABLE_PPAPI) #include "content/common/pepper_plugin.mojom.h" #endif namespace blink { namespace scheduler { class WebAgentGroupScheduler; } // namespace scheduler class WeakWrapperResourceLoadInfoNotifier; class WebComputedAXTree; class WebContentDecryptionModule; class WebElement; class WebFrameRequestBlocker; class WebLocalFrame; class WebMediaStreamDeviceObserver; class WebString; class WebURL; struct FramePolicy; } // namespace blink namespace gfx { class Point; class Range; } // namespace gfx namespace media { class MediaPermission; } namespace url { class Origin; class SchemeHostPort; } // namespace url namespace content { class AgentSchedulingGroup; class AXTreeDistiller; class BlinkInterfaceRegistryImpl; class DocumentState; class MediaPermissionDispatcher; class NavigationClient; class PepperPluginInstanceImpl; class RendererPpapiHost; class RenderAccessibilityManager; class RenderFrameObserver; class CONTENT_EXPORT RenderFrameImpl : public RenderFrame, public blink::mojom::ResourceLoadInfoNotifier, blink::mojom::AutoplayConfigurationClient, public mojom::Frame, mojom::FrameBindingsControl, mojom::MhtmlFileWriter, public blink::WebLocalFrameClient, service_manager::mojom::InterfaceProvider { public: // Creates a new RenderFrame as the main frame of `web_view`. static RenderFrameImpl* CreateMainFrame( AgentSchedulingGroup& agent_scheduling_group, blink::WebView* web_view, blink::WebFrame* opener, bool is_for_nested_main_frame, bool is_for_scalable_page, blink::mojom::FrameReplicationStatePtr replication_state, const base::UnguessableToken& devtools_frame_token, mojom::CreateLocalMainFrameParamsPtr params); // Creates a new RenderFrame with |routing_id|. If |previous_frame_token| is // not provided, it creates the Blink WebLocalFrame and inserts it into // the frame tree after the frame identified by |previous_sibling_routing_id|, // or as the first child if |previous_sibling_routing_id| is MSG_ROUTING_NONE. // Otherwise, the frame is semi-orphaned until it commits, at which point it // replaces the previous object identified by |previous_frame_token|. The // previous object can either be a RenderFrame or a RenderFrameProxy. // The frame's opener is set to the frame identified by |opener_routing_id|. // The frame is created as a child of the RenderFrame identified by // |parent_routing_id| or as the top-level frame if // the latter is MSG_ROUTING_NONE. // |devtools_frame_token| is passed from the browser and corresponds to the // owner FrameTreeNode. It can only be used for tagging requests and calls // for context frame attribution. It should never be passed back to the // browser as a frame identifier in the control flows calls. // The |widget_params| is not null if the frame is to be a local root, which // means it will own a RenderWidget, in which case the |widget_params| hold // the routing id and initialization properties for the RenderWidget. // // Note: This is called only when RenderFrame is being created in response // to IPC message from the browser process. All other frame creation is driven // through Blink and Create. static void CreateFrame( AgentSchedulingGroup& agent_scheduling_group, const blink::LocalFrameToken& token, int routing_id, mojo::PendingAssociatedReceiver frame_receiver, mojo::PendingRemote browser_interface_broker, mojo::PendingAssociatedRemote associated_interface_provider, const absl::optional& previous_frame_token, const absl::optional& opener_frame_token, const absl::optional& parent_frame_token, const absl::optional& previous_sibling_frame_token, const base::UnguessableToken& devtools_frame_token, blink::mojom::TreeScopeType tree_scope_type, blink::mojom::FrameReplicationStatePtr replicated_state, mojom::CreateFrameWidgetParamsPtr widget_params, blink::mojom::FrameOwnerPropertiesPtr frame_owner_properties, bool is_on_initial_empty_document, const blink::DocumentToken& document_token, blink::mojom::PolicyContainerPtr policy_container); // Returns the RenderFrameImpl for the given routing ID. static RenderFrameImpl* FromRoutingID(int routing_id); // Just like RenderFrame::FromWebFrame but returns the implementation. static RenderFrameImpl* FromWebFrame(blink::WebFrame* web_frame); // Constructor parameters are bundled into a struct. struct CONTENT_EXPORT CreateParams { CreateParams( AgentSchedulingGroup& agent_scheduling_group, int32_t routing_id, mojo::PendingAssociatedReceiver frame_receiver, mojo::PendingRemote browser_interface_broker, mojo::PendingAssociatedRemote associated_interface_provider, const base::UnguessableToken& devtools_frame_token); ~CreateParams(); CreateParams(CreateParams&&); CreateParams& operator=(CreateParams&&); AgentSchedulingGroup* agent_scheduling_group; int32_t routing_id; mojo::PendingAssociatedReceiver frame_receiver; mojo::PendingRemote browser_interface_broker; mojo::PendingAssociatedRemote associated_interface_provider; base::UnguessableToken devtools_frame_token; }; using CreateRenderFrameImplFunction = RenderFrameImpl* (*)(CreateParams); // Web tests override the creation of RenderFrames in order to inject a // partial testing fake. static void InstallCreateHook(CreateRenderFrameImplFunction create_frame); // Overwrites the given URL to use an HTML5 embed if possible. blink::WebURL OverrideFlashEmbedWithHTML(const blink::WebURL& url) override; RenderFrameImpl(const RenderFrameImpl&) = delete; RenderFrameImpl& operator=(const RenderFrameImpl&) = delete; ~RenderFrameImpl() override; // Returns the unique name of the RenderFrame. const std::string& unique_name() const { return unique_name_helper_.value(); } // Returns the blink::WebFrameWidget attached to the local root of this // frame. blink::WebFrameWidget* GetLocalRootWebFrameWidget(); // This method must be called after the WebLocalFrame backing this RenderFrame // has been created and added to the frame tree. It creates all objects that // depend on the frame being at its proper spot. // // Virtual for web tests to inject their own behaviour into the WebLocalFrame. virtual void Initialize(blink::WebFrame* parent); // Start/Stop loading notifications. // TODO(nasko): Those are page-level methods at this time and come from // WebViewClient. We should move them to be WebLocalFrameClient calls and put // logic in the browser side to balance starts/stops. void DidStartLoading() override; void DidStopLoading() override; // Returns the object implementing the RenderAccessibility mojo interface and // serves as a bridge between RenderFrameImpl and RenderAccessibilityImpl. RenderAccessibilityManager* GetRenderAccessibilityManager() { return render_accessibility_manager_.get(); } // Called from RenderAccessibilityManager to let the RenderFrame know when the // accessibility mode has changed, so that it can notify its observers. void NotifyAccessibilityModeChange(ui::AXMode new_mode); // Whether or not the frame is currently swapped into the frame tree. If // this is false, this is a provisional frame which has not committed yet, // and which will swap with a proxy when it commits. // // TODO(https://crbug.com/578349): Remove this once provisional frames are // gone, and clean up code that depends on it. bool in_frame_tree() { return in_frame_tree_; } #if BUILDFLAG(ENABLE_PPAPI) mojom::PepperHost* GetPepperHost(); // Notification that a PPAPI plugin has been created. void PepperPluginCreated(RendererPpapiHost* host); // Informs the render view that a PPAPI plugin has changed text input status. void PepperTextInputTypeChanged(PepperPluginInstanceImpl* instance); void PepperCaretPositionChanged(PepperPluginInstanceImpl* instance); // Cancels current composition. void PepperCancelComposition(PepperPluginInstanceImpl* instance); // Informs the render view that a PPAPI plugin has changed selection. void PepperSelectionChanged(PepperPluginInstanceImpl* instance); #endif // BUILDFLAG(ENABLE_PPAPI) // IPC::Sender bool Send(IPC::Message* msg) override; // IPC::Listener bool OnMessageReceived(const IPC::Message& msg) override; void OnAssociatedInterfaceRequest( const std::string& interface_name, mojo::ScopedInterfaceEndpointHandle handle) override; // RenderFrame implementation: RenderFrame* GetMainRenderFrame() override; RenderAccessibility* GetRenderAccessibility() override; std::unique_ptr CreateAXTreeSnapshotter( ui::AXMode ax_mode) override; int GetRoutingID() override; blink::WebLocalFrame* GetWebFrame() override; const blink::WebLocalFrame* GetWebFrame() const override; blink::WebView* GetWebView() override; const blink::WebView* GetWebView() const override; const blink::web_pref::WebPreferences& GetBlinkPreferences() override; void ShowVirtualKeyboard() override; blink::WebPlugin* CreatePlugin(const WebPluginInfo& info, const blink::WebPluginParams& params) override; void ExecuteJavaScript(const std::u16string& javascript) override; bool IsMainFrame() override; bool IsInFencedFrameTree() const override; bool IsHidden() override; void BindLocalInterface( const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; blink::AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry() override; blink::AssociatedInterfaceProvider* GetRemoteAssociatedInterfaces() override; void SetSelectedText(const std::u16string& selection_text, size_t offset, const gfx::Range& range, bool user_initiated) override; void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level, const std::string& message) override; bool IsPasting() override; bool IsBrowserSideNavigationPending() override; void LoadHTMLStringForTesting(const std::string& html, const GURL& base_url, const std::string& text_encoding, const GURL& unreachable_url, bool replace_current_item) override; scoped_refptr GetTaskRunner( blink::TaskType task_type) override; int GetEnabledBindings() override; void SetAccessibilityModeForTest(ui::AXMode new_mode) override; scoped_refptr GetURLLoaderFactory() override; const RenderFrameMediaPlaybackOptions& GetRenderFrameMediaPlaybackOptions() override; void SetRenderFrameMediaPlaybackOptions( const RenderFrameMediaPlaybackOptions& opts) override; void SetAllowsCrossBrowsingInstanceFrameLookup() override; gfx::RectF ElementBoundsInWindow(const blink::WebElement& element) override; void ConvertViewportToWindow(gfx::Rect* rect) override; float GetDeviceScaleFactor() override; blink::scheduler::WebAgentGroupScheduler& GetAgentGroupScheduler() override; // blink::mojom::AutoplayConfigurationClient implementation: void AddAutoplayFlags(const url::Origin& origin, const int32_t flags) override; // blink::mojom::ResourceLoadInfoNotifier implementation: #if BUILDFLAG(IS_ANDROID) void NotifyUpdateUserGestureCarryoverInfo() override; #endif void NotifyResourceRedirectReceived( const net::RedirectInfo& redirect_info, network::mojom::URLResponseHeadPtr redirect_response) override; void NotifyResourceResponseReceived( int64_t request_id, const url::SchemeHostPort& final_response_url, network::mojom::URLResponseHeadPtr head, network::mojom::RequestDestination request_destination) override; void NotifyResourceTransferSizeUpdated(int64_t request_id, int32_t transfer_size_diff) override; void NotifyResourceLoadCompleted( blink::mojom::ResourceLoadInfoPtr resource_load_info, const ::network::URLLoaderCompletionStatus& status) override; void NotifyResourceLoadCanceled(int64_t request_id) override; void Clone(mojo::PendingReceiver pending_resource_load_info_notifier) override; // mojom::FrameBindingsControl implementation: void AllowBindings(int32_t enabled_bindings_flags) override; void EnableMojoJsBindings( content::mojom::ExtraMojoJsFeaturesPtr features) override; void EnableMojoJsBindingsWithBroker( mojo::PendingRemote) override; void BindWebUI( mojo::PendingAssociatedReceiver Receiver, mojo::PendingAssociatedRemote remote) override; // These mirror mojom::NavigationClient, called by NavigationClient. void CommitNavigation( blink::mojom::CommonNavigationParamsPtr common_params, blink::mojom::CommitNavigationParamsPtr commit_params, network::mojom::URLResponseHeadPtr response_head, mojo::ScopedDataPipeConsumerHandle response_body, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr subresource_loader_factories, absl::optional> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, mojo::PendingRemote prefetch_loader_factory, const blink::DocumentToken& document_token, const base::UnguessableToken& devtools_navigation_token, const absl::optional& permissions_policy, blink::mojom::PolicyContainerPtr policy_container, mojo::PendingRemote code_cache_host, mojom::CookieManagerInfoPtr cookie_manager_info, mojom::StorageInfoPtr storage_info, blink::mojom::BackForwardCacheNotRestoredReasonsPtr not_restored_reasons, mojom::NavigationClient::CommitNavigationCallback commit_callback); void CommitFailedNavigation( blink::mojom::CommonNavigationParamsPtr common_params, blink::mojom::CommitNavigationParamsPtr commit_params, bool has_stale_copy_in_cache, int error_code, int extended_error_code, net::ResolveErrorInfo resolve_error_info, const absl::optional& error_page_content, std::unique_ptr subresource_loader_factories, const blink::DocumentToken& document_token, blink::mojom::PolicyContainerPtr policy_container, mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info, mojom::NavigationClient::CommitFailedNavigationCallback per_navigation_mojo_interface_callback); // mojom::MhtmlFileWriter implementation: void SerializeAsMHTML(const mojom::SerializeAsMHTMLParamsPtr params, SerializeAsMHTMLCallback callback) override; // blink::WebLocalFrameClient implementation: void BindToFrame(blink::WebNavigationControl* frame) override; blink::WebPlugin* CreatePlugin(const blink::WebPluginParams& params) override; blink::WebMediaPlayer* CreateMediaPlayer( const blink::WebMediaPlayerSource& source, blink::WebMediaPlayerClient* client, blink::MediaInspectorContext* inspector_context, blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, blink::WebContentDecryptionModule* initial_cdm, const blink::WebString& sink_id, const cc::LayerTreeSettings& settings, scoped_refptr compositor_worker_task_runner) override; std::unique_ptr CreateWorkerContentSettingsClient() override; #if !BUILDFLAG(IS_ANDROID) std::unique_ptr CreateSpeechRecognitionClient( media::SpeechRecognitionClient::OnReadyCallback callback) override; #endif scoped_refptr CreateWorkerFetchContext() override; scoped_refptr CreateWorkerFetchContextForPlzDedicatedWorker( blink::WebDedicatedWorkerHostFactoryClient* factory_client) override; std::unique_ptr CreatePrescientNetworking() override; std::unique_ptr CreateResourceLoadInfoNotifierWrapper() override; std::unique_ptr CreateServiceWorkerProvider() override; blink::AssociatedInterfaceProvider* GetRemoteNavigationAssociatedInterfaces() override; blink::WebLocalFrame* CreateChildFrame( blink::mojom::TreeScopeType scope, const blink::WebString& name, const blink::WebString& fallback_name, const blink::FramePolicy& frame_policy, const blink::WebFrameOwnerProperties& frame_owner_properties, blink::FrameOwnerElementType frame_owner_element_type, blink::WebPolicyContainerBindParams policy_container_bind_params, FinishChildFrameCreationFn finish_creation) override; void DidCreateFencedFrame( const blink::RemoteFrameToken& frame_token) override; blink::WebFrame* FindFrame(const blink::WebString& name) override; void WillDetach() override; void FrameDetached() override; void DidChangeName(const blink::WebString& name) override; void DidMatchCSS( const blink::WebVector& newly_matching_selectors, const blink::WebVector& stopped_matching_selectors) override; bool ShouldReportDetailedMessageForSourceAndSeverity( blink::mojom::ConsoleMessageLevel log_level, const blink::WebString& source) override; void DidAddMessageToConsole(const blink::WebConsoleMessage& message, const blink::WebString& source_name, unsigned source_line, const blink::WebString& stack_trace) override; void BeginNavigation(std::unique_ptr info) override; void DidCreateDocumentLoader( blink::WebDocumentLoader* document_loader) override; bool SwapIn(blink::WebFrame* previous_web_frame) override; void DidCommitNavigation( blink::WebHistoryCommitType commit_type, bool should_reset_browser_interface_broker, const blink::ParsedPermissionsPolicy& permissions_policy_header, const blink::DocumentPolicyFeatureState& document_policy_header) override; void DidCommitDocumentReplacementNavigation( blink::WebDocumentLoader* document_loader) override; void DidClearWindowObject() override; void DidCreateDocumentElement() override; void RunScriptsAtDocumentElementAvailable() override; void DidReceiveTitle(const blink::WebString& title) override; void DidDispatchDOMContentLoadedEvent() override; void RunScriptsAtDocumentReady() override; void RunScriptsAtDocumentIdle() override; void DidHandleOnloadEvents() override; void DidFinishLoad() override; void DidFinishLoadForPrinting() override; void DidFinishSameDocumentNavigation( blink::WebHistoryCommitType commit_type, bool is_synchronously_committed, blink::mojom::SameDocumentNavigationType same_document_navigation_type, bool is_client_redirect) override; void WillFreezePage() override; void DidOpenDocumentInputStream(const blink::WebURL& url) override; void DidSetPageLifecycleState() override; void NotifyCurrentHistoryItemChanged() override; void DidUpdateCurrentHistoryItem() override; base::UnguessableToken GetDevToolsFrameToken() override; void AbortClientNavigation() override; void DidChangeSelection(bool is_empty_selection, blink::SyncCondition force_sync) override; void FocusedElementChanged(const blink::WebElement& element) override; void OnMainFrameIntersectionChanged( const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) override; void WillSendRequest(blink::WebURLRequest& request, ForRedirect for_redirect) override; void OnOverlayPopupAdDetected() override; void OnLargeStickyAdDetected() override; void DidLoadResourceFromMemoryCache( const blink::WebURLRequest& request, const blink::WebURLResponse& response) override; void DidChangePerformanceTiming() override; void DidObserveInputDelay(base::TimeDelta input_delay) override; void DidObserveUserInteraction( base::TimeDelta max_event_duration, blink::UserInteractionType interaction_type) override; void DidChangeCpuTiming(base::TimeDelta time) override; void DidObserveLoadingBehavior(blink::LoadingBehaviorFlag behavior) override; void DidObserveNewFeatureUsage( const blink::UseCounterFeature& feature) override; void DidObserveSoftNavigation(uint32_t count) override; void DidObserveLayoutShift(double score, bool after_input_or_scroll) override; void DidObserveLayoutNg(uint32_t all_block_count, uint32_t ng_block_count, uint32_t all_call_count, uint32_t ng_call_count) override; void DidCreateScriptContext(v8::Local context, int world_id) override; void WillReleaseScriptContext(v8::Local context, int world_id) override; void DidChangeScrollOffset() override; void PreloadSubresourceOptimizationsForOrigins( const std::vector& origins) override; blink::WebMediaStreamDeviceObserver* MediaStreamDeviceObserver() override; blink::WebEncryptedMediaClient* EncryptedMediaClient() override; blink::WebString UserAgentOverride() override; absl::optional UserAgentMetadataOverride() override; blink::mojom::RendererAudioInputStreamFactory* GetAudioInputStreamFactory(); bool AllowContentInitiatedDataUrlNavigations( const blink::WebURL& url) override; void PostAccessibilityEvent(const ui::AXEvent& event) override; void NotifyWebAXObjectMarkedDirty(const blink::WebAXObject& object) override; void CheckIfAudioSinkExistsAndIsAuthorized( const blink::WebString& sink_id, blink::WebSetSinkIdCompleteCallback callback) override; std::unique_ptr CreateURLLoaderFactory() override; void OnStopLoading() override; void DraggableRegionsChanged() override; blink::BrowserInterfaceBrokerProxy* GetBrowserInterfaceBroker() override; blink::WebView* CreateNewWindow( const blink::WebURLRequest& request, const blink::WebWindowFeatures& features, const blink::WebString& frame_name, blink::WebNavigationPolicy policy, network::mojom::WebSandboxFlags sandbox_flags, const blink::SessionStorageNamespaceId& session_storage_namespace_id, bool& consumed_user_gesture, const absl::optional& impression, const absl::optional& pip_options) override; // Dispatches the current state of selection on the webpage to the browser if // it has changed or if the forced flag is passed. The forced flag is used // when the browser selection may be out of sync with the renderer due to // incorrect prediction. void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection, bool user_initiated) override; void CreateAudioInputStream( blink::CrossVariantMojoRemote< blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase> client, const base::UnguessableToken& session_id, const media::AudioParameters& params, bool automatic_gain_control, uint32_t shared_memory_count, blink::CrossVariantMojoReceiver< media::mojom::AudioProcessorControlsInterfaceBase> controls_receiver, const media::AudioProcessingSettings* settings) override; void AssociateInputAndOutputForAec( const base::UnguessableToken& input_stream_id, const std::string& output_device_id) override; void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override; void DidCommitAndDrawCompositorFrame() override; void WasHidden() override; void WasShown() override; void SetUpSharedMemoryForSmoothness( base::ReadOnlySharedMemoryRegion shared_memory) override; blink::WebURL LastCommittedUrlForUKM() override; void ScriptedPrint() override; // Possibly defers the loading of media resources. // // This function defers in two cases: // - In the normal case, it calls ContentRendererClient::DeferMediaLoad() // to give the embedder a chance to defer. // - If the frame is prerendering, this function defers the load. It // calls ContentRendererClient::DeferMediaLoad() once activation // occurs. // // `closure` is run when loading should proceed. Returns true if running // of |closure| is deferred; false if run immediately. // // If `has_played_media_before` is true, the render frame has previously // started media playback (i.e. played audio and video). bool DeferMediaLoad(bool has_played_media_before, base::OnceClosure closure); // Binds to the MHTML file generation service in the browser. void BindMhtmlFileWriter( mojo::PendingAssociatedReceiver receiver); // Binds to the autoplay configuration service in the browser. void BindAutoplayConfiguration( mojo::PendingAssociatedReceiver receiver); void BindFrameBindingsControl( mojo::PendingAssociatedReceiver receiver); void BindNavigationClient( mojo::PendingAssociatedReceiver receiver); // Virtual so that a TestRenderFrame can mock out the interface. virtual mojom::FrameHost* GetFrameHost(); media::MediaPermission* GetMediaPermission(); // Sends the current frame's navigation state to the browser. void SendUpdateState(); // Creates a MojoBindingsController if Mojo bindings have been enabled for // this frame. For WebUI, this allows the page to communicate with the browser // process; for layout tests, this allows the test to mock out services at // the Mojo IPC layer. void MaybeEnableMojoBindings(); void NotifyObserversOfFailedProvisionalLoad(); // Plugin-related functions -------------------------------------------------- #if BUILDFLAG(ENABLE_PPAPI) PepperPluginInstanceImpl* focused_pepper_plugin() { return focused_pepper_plugin_; } // Indicates that the given instance has been created. void PepperInstanceCreated( PepperPluginInstanceImpl* instance, mojo::PendingAssociatedRemote mojo_instance, mojo::PendingAssociatedReceiver mojo_host); // Indicates that the given instance is being destroyed. This is called from // the destructor, so it's important that the instance is not dereferenced // from this call. void PepperInstanceDeleted(PepperPluginInstanceImpl* instance); // Notification that the given plugin is focused or unfocused. void PepperFocusChanged(PepperPluginInstanceImpl* instance, bool focused); void OnSetPepperVolume(int32_t pp_instance, double volume); #endif // BUILDFLAG(ENABLE_PPAPI) const blink::RendererPreferences& GetRendererPreferences() const; // Called when an ongoing renderer-initiated navigation was dropped by the // browser. void OnDroppedNavigation(); void DidStartResponse(const url::SchemeHostPort& final_response_url, int request_id, network::mojom::URLResponseHeadPtr response_head, network::mojom::RequestDestination request_destination); void DidCompleteResponse(int request_id, const network::URLLoaderCompletionStatus& status); void DidCancelResponse(int request_id); void DidReceiveTransferSizeUpdate(int request_id, int received_data_length); bool GetCaretBoundsFromFocusedPlugin(gfx::Rect& rect) override; // Used in tests to install a fake WebURLLoaderFactory via // RenderViewTest::CreateFakeWebURLLoaderFactory(). void SetWebURLLoaderFactoryOverrideForTest( std::unique_ptr factory); // Clones and returns `this` frame's blink::ChildURLLoaderFactoryBundle. scoped_refptr CloneLoaderFactories(); url::Origin GetSecurityOriginOfTopFrame(); void set_send_content_state_immediately(bool value) { send_content_state_immediately_ = value; } base::WeakPtr GetMediaDecoderFactory(); protected: explicit RenderFrameImpl(CreateParams params); bool IsLocalRoot() const; const RenderFrameImpl* GetLocalRoot() const; private: friend class RenderFrameImplTest; friend class RenderFrameObserver; friend class TestRenderFrame; FRIEND_TEST_ALL_PREFIXES(RenderAccessibilityImplTest, AccessibilityMessagesQueueWhileSwappedOut); FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, LocalChildFrameWasShown); FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, ZoomLimit); FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, TestOverlayRoutingTokenSendsLater); FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, TestOverlayRoutingTokenSendsNow); FRIEND_TEST_ALL_PREFIXES(RenderFrameImplTest, SendUpdateCancelsPending); // Similar to base::AutoReset, but skips restoration of the original value if // |this| is already destroyed. template class AutoResetMember { public: AutoResetMember(RenderFrameImpl* frame, T RenderFrameImpl::*member, T new_value) : weak_frame_(frame->weak_factory_.GetWeakPtr()), scoped_variable_(&(frame->*member)), original_value_(*scoped_variable_) { *scoped_variable_ = new_value; } ~AutoResetMember() { if (weak_frame_) *scoped_variable_ = original_value_; } private: base::WeakPtr weak_frame_; T* scoped_variable_; T original_value_; }; class FrameURLLoaderFactory; // Creates a new RenderFrame. |browser_interface_broker| is the // RenderFrameHost's BrowserInterfaceBroker through which services are exposed // to the RenderFrame. static RenderFrameImpl* Create( AgentSchedulingGroup& agent_scheduling_group, int32_t routing_id, mojo::PendingAssociatedReceiver frame_receiver, mojo::PendingRemote browser_interface_broker, mojo::PendingAssociatedRemote associated_interface_provider, const base::UnguessableToken& devtools_frame_token); // Functions to add and remove observers for this object. void AddObserver(RenderFrameObserver* observer); void RemoveObserver(RenderFrameObserver* observer); // Checks whether accessibility support for this frame is currently enabled. bool IsAccessibilityEnabled() const; // mojom::Frame implementation: void CommitSameDocumentNavigation( blink::mojom::CommonNavigationParamsPtr common_params, blink::mojom::CommitNavigationParamsPtr commit_params, CommitSameDocumentNavigationCallback callback) override; void UpdateSubresourceLoaderFactories( std::unique_ptr subresource_loader_factories) override; void SetWantErrorMessageStackTrace() override; void Unload( bool is_loading, blink::mojom::FrameReplicationStatePtr replicated_frame_state, const blink::RemoteFrameToken& frame_token, blink::mojom::RemoteFrameInterfacesFromBrowserPtr remote_frame_interfaces, blink::mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces) override; void Delete(mojom::FrameDeleteIntention intent) override; void UndoCommitNavigation( bool is_loading, blink::mojom::FrameReplicationStatePtr replicated_frame_state, const blink::RemoteFrameToken& frame_token, blink::mojom::RemoteFrameInterfacesFromBrowserPtr remote_frame_interfaces, blink::mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces) override; void BlockRequests() override; void ResumeBlockedRequests() override; void GetInterfaceProvider( mojo::PendingReceiver receiver) override; void SnapshotAccessibilityTree( mojom::SnapshotAccessibilityTreeParamsPtr params, SnapshotAccessibilityTreeCallback callback) override; void SnapshotAndDistillAXTree( SnapshotAndDistillAXTreeCallback callback) override; void GetSerializedHtmlWithLocalLinks( const base::flat_map& url_map, const base::flat_map& frame_token_map, bool save_with_empty_url, mojo::PendingRemote handler_remote) override; // Callback scheduled from SerializeAsMHTML for when writing serialized // MHTML to the handle has been completed in the file thread. void OnWriteMHTMLComplete( SerializeAsMHTMLCallback callback, std::unordered_set serialized_resources_uri_digests, base::TimeDelta main_thread_use_time, mojom::MhtmlSaveStatus save_status); // Requests that the browser process navigates to |url|. void OpenURL(std::unique_ptr info); // Returns a blink::ChildURLLoaderFactoryBundle which can be used to request // subresources for this frame. // // The returned bundle was typically sent by the browser process when // committing a navigation, but in some cases (about:srcdoc, initial empty // document) it may be inherited from the parent or opener. blink::ChildURLLoaderFactoryBundle* GetLoaderFactoryBundle(); scoped_refptr CreateLoaderFactoryBundle( std::unique_ptr info, absl::optional> subresource_overrides, mojo::PendingRemote prefetch_loader_factory); // Update current main frame's encoding and send it to browser window. // Since we want to let users see the right encoding info from menu // before finishing loading, we call the UpdateEncoding in // a) function:DidCommitLoadForFrame. When this function is called, // that means we have got first data. In here we try to get encoding // of page if it has been specified in http header. // b) function:DidReceiveTitle. When this function is called, // that means we have got specified title. Because in most of webpages, // title tags will follow meta tags. In here we try to get encoding of // page if it has been specified in meta tag. // c) function:DidDispatchDOMContentLoadedEvent. When this function is // called, that means we have got whole html page. In here we should // finally get right encoding of page. void UpdateEncoding(blink::WebFrame* frame, const std::string& encoding_name); void InitializeMediaStreamDeviceObserver(); // Sends a FrameHostMsg_BeginNavigation to the browser void BeginNavigationInternal(std::unique_ptr info, bool is_history_navigation_in_new_child_frame, base::TimeTicks renderer_before_unload_start, base::TimeTicks renderer_before_unload_end); // TODO(https://crbug.com/778318): When creating a new browsing context, Blink // always populates it with an initial empty document synchronously, as // required by the HTML spec. However, for both iframe and window creation, // there is an additional special case that currently requires completing an // about:blank navigation synchronously. // // 1. Inserting an // // will *not* be in the |kInitialEmptyDocument| state: while it initially // starts at the initial empty document, the initial empty document is then // synchronously replaced with a navigation to about:blank. In contrast: // // // // will be in |kInitialEmptyDocument| until the navigation to // https://slow.example.com commits. kInitialEmptyDocument, // No commit in progress. This state also implies that the frame is not // displaying the initial empty document. kNone, // Marks that an active commit attempt is on the stack. kWillCommit, // Marks an active commit attempt as successful. kDidCommit, }; enum MayReplaceInitialEmptyDocumentTag { kMayReplaceInitialEmptyDocument, }; class CONTENT_EXPORT AssertNavigationCommits { public: // Construct a new scoper to verify that a navigation commit attempt // succeeds. Asserts that: // - no navigation is in progress // - the frame is not displaying the initial empty document. explicit AssertNavigationCommits(RenderFrameImpl* frame); // Similar to the previous constructor but allows transitions from the // initial empty document. explicit AssertNavigationCommits(RenderFrameImpl* frame, MayReplaceInitialEmptyDocumentTag); ~AssertNavigationCommits(); private: explicit AssertNavigationCommits( RenderFrameImpl* frame, bool allow_transition_from_initial_empty_document); const base::WeakPtr frame_; }; NavigationCommitState navigation_commit_state_ = NavigationCommitState::kInitialEmptyDocument; // Timer used to delay the updating of frame state. base::OneShotTimer delayed_state_sync_timer_; // Whether content state (such as form state, scroll position and page // contents) should be sent to the browser immediately. This is normally // false, but set to true by some tests. bool send_content_state_immediately_ = false; base::WeakPtrFactory weak_factory_{this}; }; } // namespace content #endif // CONTENT_RENDERER_RENDER_FRAME_IMPL_H_