| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_RENDERER_RENDER_VIEW_IMPL_H_ |
| #define CONTENT_RENDERER_RENDER_VIEW_IMPL_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/containers/id_map.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/observer_list.h" |
| #include "base/process/process.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/string_piece.h" |
| #include "base/timer/timer.h" |
| #include "build/build_config.h" |
| #include "cc/input/browser_controls_state.h" |
| #include "content/common/content_export.h" |
| #include "content/public/common/browser_controls_state.h" |
| #include "content/public/common/drop_data.h" |
| #include "content/public/common/page_visibility_state.h" |
| #include "content/public/common/page_zoom.h" |
| #include "content/public/common/referrer.h" |
| #include "content/public/renderer/render_view.h" |
| #include "content/renderer/render_frame_impl.h" |
| #include "content/renderer/render_widget.h" |
| #include "content/renderer/render_widget_delegate.h" |
| #include "ipc/ipc_platform_file.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/remote_set.h" |
| #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" |
| #include "third_party/blink/public/common/feature_policy/feature_policy_features.h" |
| #include "third_party/blink/public/common/input/web_input_event.h" |
| #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" |
| #include "third_party/blink/public/common/web_preferences/web_preferences.h" |
| #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h" |
| #include "third_party/blink/public/platform/web_security_origin.h" |
| #include "third_party/blink/public/web/web_ax_object.h" |
| #include "third_party/blink/public/web/web_console_message.h" |
| #include "third_party/blink/public/web/web_element.h" |
| #include "third_party/blink/public/web/web_history_item.h" |
| #include "third_party/blink/public/web/web_navigation_type.h" |
| #include "third_party/blink/public/web/web_node.h" |
| #include "third_party/blink/public/web/web_view_client.h" |
| #include "third_party/blink/public/web/web_widget_client.h" |
| #include "ui/base/window_open_disposition.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| #include "ui/surface/transport_dib.h" |
| |
| namespace blink { |
| class WebURLRequest; |
| struct WebWindowFeatures; |
| } // namespace blink |
| |
| namespace content { |
| class AgentSchedulingGroup; |
| class RenderViewImplTest; |
| class RenderViewObserver; |
| class RenderViewTest; |
| |
| namespace mojom { |
| class CreateViewParams; |
| } |
| |
| // RenderViewImpl (the implementation of RenderView) is the renderer process |
| // object that owns the blink frame tree. |
| // |
| // Each top-level web container has a frame tree, and thus a RenderViewImpl. |
| // Typically such a container is a browser tab, or a tab-less window. It can |
| // also be other cases such as a background page or extension. |
| // |
| // Under site isolation, frames in the main frame's tree may be moved out |
| // to a separate frame tree (possibly in another process), leaving remote |
| // placeholders behind. Each such frame tree also includes a RenderViewImpl as |
| // the owner of it. Thus a tab may have multiple RenderViewImpls, one for the |
| // main frame, and one for each other frame tree generated. |
| // |
| // When the main frame is part of this RenderViewImpl's frame tree, then this |
| // object acts as the RenderWidgetDelegate for that frame's RenderWidget. Other |
| // RenderWidgets would have a null RenderWidgetDelegate. |
| // |
| // Note: There are cases where there may be multiple main frames in tab. For |
| // example, both Portals and GuestViews create their own RenderView that's |
| // nested within another RenderView's frame tree. In these cases, the |
| // RenderWidget for the nested view will have a non-null RenderWidgetDelegate, |
| // despite the fact that it isn't the root of the hierarchy. |
| class CONTENT_EXPORT RenderViewImpl : public blink::WebViewClient, |
| public IPC::Listener, |
| public RenderWidgetDelegate, |
| public RenderView { |
| public: |
| // Creates a new RenderView. Note that if the original opener has been closed, |
| // |params.window_was_created_with_opener| will be true and |
| // |params.opener_frame_route_id| will be MSG_ROUTING_NONE. |
| // When |params.proxy_routing_id| instead of |params.main_frame_routing_id| is |
| // specified, a RenderFrameProxy will be created for this RenderView's main |
| // RenderFrame. |
| // The opener should provide a non-null value for |show_callback| if it needs |
| // to send an additional IPC to finish making this view visible. |
| static RenderViewImpl* Create( |
| AgentSchedulingGroup& agent_scheduling_group, |
| CompositorDependencies* compositor_deps, |
| mojom::CreateViewParamsPtr params, |
| bool was_created_by_renderer, |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| |
| // Instances of this object are created by and destroyed by the browser |
| // process. This method must be called exactly once by the IPC subsystem when |
| // the browser wishes the object to be destroyed. |
| void Destroy(); |
| |
| // Used by web_test_support to hook into the creation of RenderViewImpls. |
| static void InstallCreateHook(RenderViewImpl* (*create_render_view_impl)( |
| AgentSchedulingGroup&, |
| CompositorDependencies*, |
| const mojom::CreateViewParams&)); |
| |
| // Returns the RenderViewImpl for the given routing ID. |
| static RenderViewImpl* FromRoutingID(int routing_id); |
| |
| // When true, a hint to all RenderWidgets that they will never be |
| // user-visible and thus never need to produce pixels for display. This is |
| // separate from page visibility, as background pages can be marked visible in |
| // blink even though they are not user-visible. Page visibility controls blink |
| // behaviour for javascript, timers, and such to inform blink it is in the |
| // foreground or background. Whereas this bit refers to user-visibility and |
| // whether the tab needs to produce pixels to put on the screen at some point |
| // or not. |
| bool widgets_never_composited() const { return widgets_never_composited_; } |
| |
| void set_send_content_state_immediately(bool value) { |
| send_content_state_immediately_ = value; |
| } |
| |
| // Functions to add and remove observers for this object. |
| void AddObserver(RenderViewObserver* observer); |
| void RemoveObserver(RenderViewObserver* observer); |
| |
| // Passes along the page zoom to the WebView to set it on a newly attached |
| // LocalFrame. |
| void PropagatePageZoomToNewlyAttachedFrame(bool use_zoom_for_dsf, |
| float device_scale_factor); |
| |
| // Starts a timer to send an UpdateState message on behalf of |frame|, if the |
| // timer isn't already running. This allows multiple state changing events to |
| // be coalesced into one update. |
| void StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame); |
| |
| // Returns the length of the session history of this RenderView. Note that |
| // this only coincides with the actual length of the session history if this |
| // RenderView is the currently active RenderView of a WebContents. |
| unsigned GetLocalSessionHistoryLengthForTesting() const; |
| |
| // Registers a watcher to observe changes in the |
| // blink::RendererPreferences. |
| void RegisterRendererPreferenceWatcher( |
| mojo::PendingRemote<blink::mojom::RendererPreferenceWatcher> watcher); |
| |
| // Returns the current instance of blink::RendererPreferences. |
| const blink::RendererPreferences& GetRendererPreferences() const; |
| |
| // IPC::Listener implementation. |
| bool OnMessageReceived(const IPC::Message& msg) override; |
| |
| // blink::WebViewClient implementation -------------------------------------- |
| |
| blink::WebView* CreateView( |
| blink::WebLocalFrame* creator, |
| const blink::WebURLRequest& request, |
| const blink::WebWindowFeatures& features, |
| const blink::WebString& frame_name, |
| blink::WebNavigationPolicy policy, |
| network::mojom::WebSandboxFlags sandbox_flags, |
| const blink::FeaturePolicyFeatureState& opener_feature_state, |
| const blink::SessionStorageNamespaceId& session_storage_namespace_id, |
| bool& consumed_user_gesture) override; |
| blink::WebPagePopup* CreatePopup(blink::WebLocalFrame* creator) override; |
| base::StringPiece GetSessionStorageNamespaceId() override; |
| void PrintPage(blink::WebLocalFrame* frame) override; |
| void SetValidationMessageDirection(base::string16* main_text, |
| base::i18n::TextDirection main_text_hint, |
| base::string16* sub_text, |
| base::i18n::TextDirection sub_text_hint); |
| bool AcceptsLoadDrops() override; |
| bool CanUpdateLayout() override; |
| void DidUpdateMainFrameLayout() override; |
| blink::WebString AcceptLanguages() override; |
| int HistoryBackListCount() override; |
| int HistoryForwardListCount() override; |
| bool CanHandleGestureEvent() override; |
| void OnPageVisibilityChanged(PageVisibilityState visibility) override; |
| void OnPageFrozenChanged(bool frozen) override; |
| void DidUpdateRendererPreferences() override; |
| void ZoomLevelChanged() override; |
| void DidCommitCompositorFrameForLocalMainFrame( |
| base::TimeTicks commit_start_time) override; |
| void OnSetHistoryOffsetAndLength(int history_offset, |
| int history_length) override; |
| |
| // RenderView implementation ------------------------------------------------- |
| |
| bool Send(IPC::Message* message) override; |
| RenderFrameImpl* GetMainRenderFrame() override; |
| int GetRoutingID() override; |
| float GetZoomLevel() override; |
| const blink::web_pref::WebPreferences& GetBlinkPreferences() override; |
| void SetBlinkPreferences( |
| const blink::web_pref::WebPreferences& preferences) override; |
| blink::WebView* GetWebView() override; |
| |
| // Please do not add your stuff randomly to the end here. If there is an |
| // appropriate section, add it there. If not, there are some random functions |
| // nearer to the top you can add it to. |
| |
| bool renderer_wide_named_frame_lookup() { |
| return renderer_wide_named_frame_lookup_; |
| } |
| |
| protected: |
| RenderViewImpl(AgentSchedulingGroup& agent_scheduling_group, |
| CompositorDependencies* compositor_deps, |
| const mojom::CreateViewParams& params); |
| ~RenderViewImpl() override; |
| |
| private: |
| // For unit tests. |
| friend class DevToolsAgentTest; |
| friend class RenderViewImplScaleFactorTest; |
| friend class RenderViewImplTest; |
| friend class RenderViewTest; |
| friend class RendererAccessibilityTest; |
| |
| // TODO(nasko): Temporarily friend RenderFrameImpl, so we don't duplicate |
| // utility functions needed in both classes, while we move frame specific |
| // code away from this class. |
| friend class RenderFrameImpl; |
| |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, EmulatingPopupRect); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, RenderFrameMessageAfterDetach); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, BeginNavigationForWebUI); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| DidFailProvisionalLoadWithErrorForError); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| DidFailProvisionalLoadWithErrorForCancellation); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, ImeComposition); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, InsertCharacters); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, JSBlockSentAfterPageLoad); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, LastCommittedUpdateState); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, OnHandleKeyboardEvent); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, OnImeTypeChanged); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, OnNavStateChanged); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, SetBlinkPreferences); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| SetEditableSelectionAndComposition); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, StaleNavigationsIgnored); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| DontIgnoreBackAfterNavEntryLimit); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| GetCompositionCharacterBoundsTest); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, OnNavigationHttpPost); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, UpdateDSFAfterSwapIn); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| BeginNavigationHandlesAllTopLevel); |
| #if defined(OS_MAC) |
| FRIEND_TEST_ALL_PREFIXES(RenderViewTest, MacTestCmdUp); |
| #endif |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, SetHistoryLengthAndOffset); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, NavigateFrame); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, BasicRenderFrame); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, TextInputTypeWithPepper); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| MessageOrderInDidChangeSelection); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, SendCandidateWindowEvents); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, RenderFrameClearedAfterClose); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, PaintAfterSwapOut); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplTest, |
| SetZoomLevelAfterCrossProcessNavigation); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest, |
| ConverViewportToScreenWithZoomForDSF); |
| FRIEND_TEST_ALL_PREFIXES(RenderViewImplEnableZoomForDSFTest, |
| GetCompositionCharacterBoundsTest); |
| |
| enum ErrorPageType { |
| DNS_ERROR, |
| HTTP_404, |
| CONNECTION_ERROR, |
| }; |
| |
| // Initialize() is separated out from the constructor because it is possible |
| // to accidentally call virtual functions. All RenderViewImpl creation is |
| // fronted by the Create() method which ensures Initialize() is always called |
| // before any other code can interact with instances of this call. |
| void Initialize(CompositorDependencies* compositor_deps, |
| mojom::CreateViewParamsPtr params, |
| bool was_created_by_renderer, |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| |
| // RenderWidgetDelegate implementation ---------------------------------- |
| |
| bool SupportsMultipleWindowsForWidget() override; |
| |
| // Old WebLocalFrameClient implementations |
| // ---------------------------------------- |
| |
| // RenderViewImpl used to be a WebLocalFrameClient, but now RenderFrameImpl is |
| // the WebLocalFrameClient. However, many implementations of |
| // WebLocalFrameClient methods still live here and are called from |
| // RenderFrameImpl. These implementations are to be moved to RenderFrameImpl |
| // <http://crbug.com/361761>. |
| |
| static WindowOpenDisposition NavigationPolicyToDisposition( |
| blink::WebNavigationPolicy policy); |
| |
| // Misc private functions ---------------------------------------------------- |
| |
| #if defined(OS_ANDROID) |
| // Make the video capture devices (e.g. webcam) stop/resume delivering video |
| // frames to their clients, depending on flag |suspend|. This is called in |
| // response to a RenderView PageHidden/Shown(). |
| void SuspendVideoCaptureDevices(bool suspend); |
| #endif |
| |
| // In OOPIF-enabled modes, this tells each RenderFrame with a pending state |
| // update to inform the browser process. |
| void SendFrameStateUpdates(); |
| |
| // --------------------------------------------------------------------------- |
| // ADDING NEW FUNCTIONS? Please keep private functions alphabetized and put |
| // it in the same order in the .cc file as it was in the header. |
| // --------------------------------------------------------------------------- |
| |
| // Becomes true when Destroy() is called. |
| bool destroying_ = false; |
| |
| // Routing ID that allows us to communicate with the corresponding |
| // RenderViewHost in the parent browser process. |
| const int32_t routing_id_; |
| |
| // Whether lookup of frames in the created RenderView (e.g. lookup via |
| // window.open or via <a target=...>) should be renderer-wide (i.e. going |
| // beyond the usual opener-relationship-based BrowsingInstance boundaries). |
| const bool renderer_wide_named_frame_lookup_; |
| |
| // A value provided by the browser to state that all RenderWidgets in this |
| // RenderView's frame tree will never be user-visible and thus never need to |
| // produce pixels for display. This is separate from Page visibility, as |
| // non-user-visible pages can still be marked visible for blink. Page |
| // visibility controls blink behaviour for javascript, timers, and such to |
| // inform blink it is in the foreground or background. Whereas this bit refers |
| // to user-visibility and whether the tab needs to produce pixels to put on |
| // the screen at some point or not. |
| const bool widgets_never_composited_; |
| |
| // Dependency injection for RenderWidget and compositing to inject behaviour |
| // and not depend on RenderThreadImpl in tests. |
| CompositorDependencies* const compositor_deps_; |
| |
| // Settings ------------------------------------------------------------------ |
| |
| // 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; |
| |
| // Loading state ------------------------------------------------------------- |
| |
| // Timer used to delay the updating of nav state (see |
| // StartNavStateSyncTimerIfNecessary). |
| base::OneShotTimer nav_state_sync_timer_; |
| |
| // Set of RenderFrame routing IDs for frames that having pending UpdateState |
| // messages to send when the next |nav_state_sync_timer_| fires. |
| std::set<int> frames_with_pending_state_; |
| |
| // History list -------------------------------------------------------------- |
| |
| // The offset of the current item in the history list. |
| int history_list_offset_ = -1; |
| |
| // The RenderView's current impression of the history length. This includes |
| // any items that have committed in this process, but because of cross-process |
| // navigations, the history may have some entries that were committed in other |
| // processes. We won't know about them until the next navigation in this |
| // process. |
| int history_list_length_ = 0; |
| |
| // View ---------------------------------------------------------------------- |
| |
| // This class owns this member, and is responsible for calling |
| // WebView::Close(). |
| blink::WebView* webview_ = nullptr; |
| |
| // Helper objects ------------------------------------------------------------ |
| |
| // The `AgentSchedulingGroup` this view is associated with. |
| AgentSchedulingGroup& agent_scheduling_group_; |
| |
| RenderFrameImpl* main_render_frame_ = nullptr; |
| |
| #if defined(OS_ANDROID) |
| // Android Specific ---------------------------------------------------------- |
| |
| // Whether this was a renderer-created or browser-created RenderView. |
| bool was_created_by_renderer_ = false; |
| #endif |
| |
| // Misc ---------------------------------------------------------------------- |
| |
| // The SessionStorage namespace that we're assigned to has an ID, and that ID |
| // is passed to us upon creation. WebKit asks for this ID upon first use and |
| // uses it whenever asking the browser process to allocate new storage areas. |
| blink::SessionStorageNamespaceId session_storage_namespace_id_; |
| |
| // All the registered observers. We expect this list to be small, so vector |
| // is fine. |
| base::ObserverList<RenderViewObserver>::Unchecked observers_; |
| |
| // --------------------------------------------------------------------------- |
| // ADDING NEW DATA? Please see if it fits appropriately in one of the above |
| // sections rather than throwing it randomly at the end. If you're adding a |
| // bunch of stuff, you should probably create a helper class and put your |
| // data and methods on that to avoid bloating RenderView more. You can |
| // use the Observer interface to filter IPC messages and receive frame change |
| // notifications. |
| // --------------------------------------------------------------------------- |
| |
| base::WeakPtrFactory<RenderViewImpl> weak_ptr_factory_{this}; |
| |
| DISALLOW_COPY_AND_ASSIGN(RenderViewImpl); |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_RENDERER_RENDER_VIEW_IMPL_H_ |