1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_PUBLIC_RENDERER_RENDER_FRAME_OBSERVER_H_ 6 #define CONTENT_PUBLIC_RENDERER_RENDER_FRAME_OBSERVER_H_ 7 8 #include <stdint.h> 9 10 #include "base/compiler_specific.h" 11 #include "base/macros.h" 12 #include "base/memory/read_only_shared_memory_region.h" 13 #include "base/optional.h" 14 #include "base/strings/string16.h" 15 #include "content/common/content_export.h" 16 #include "ipc/ipc_listener.h" 17 #include "ipc/ipc_sender.h" 18 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 19 #include "mojo/public/cpp/system/message_pipe.h" 20 #include "services/network/public/mojom/url_response_head.mojom-forward.h" 21 #include "third_party/blink/public/common/loader/loading_behavior_flag.h" 22 #include "third_party/blink/public/common/loader/previews_state.h" 23 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" 24 #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom.h" 25 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" 26 #include "third_party/blink/public/platform/web_vector.h" 27 #include "third_party/blink/public/web/web_local_frame_client.h" 28 #include "third_party/blink/public/web/web_meaningful_layout.h" 29 #include "third_party/blink/public/web/web_navigation_type.h" 30 #include "ui/accessibility/ax_mode.h" 31 #include "ui/base/page_transition_types.h" 32 #include "v8/include/v8.h" 33 34 class GURL; 35 36 namespace blink { 37 class WebDocumentLoader; 38 class WebElement; 39 class WebFormElement; 40 class WebString; 41 class WebWorkerFetchContext; 42 } // namespace blink 43 44 namespace network { 45 struct URLLoaderCompletionStatus; 46 } // namespace network 47 48 namespace content { 49 50 class RendererPpapiHost; 51 class RenderFrame; 52 class RenderFrameImpl; 53 54 // Base class for objects that want to filter incoming IPCs, and also get 55 // notified of changes to the frame. 56 class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener, 57 public IPC::Sender { 58 public: 59 // A subclass can use this to delete itself. If it does not, the subclass must 60 // always null-check each call to render_frame() because the RenderFrame can 61 // go away at any time. 62 virtual void OnDestruct() = 0; 63 64 // Called when a Pepper plugin is created. DidCreatePepperPlugin(RendererPpapiHost * host)65 virtual void DidCreatePepperPlugin(RendererPpapiHost* host) {} 66 67 // Called when a load is explicitly stopped by the user or browser. OnStop()68 virtual void OnStop() {} 69 70 // Called when the RenderFrame visiblity is changed. WasHidden()71 virtual void WasHidden() {} WasShown()72 virtual void WasShown() {} 73 74 // Navigation callbacks. 75 // 76 // Each navigation starts with a DidStartNavigation call. Then it may be 77 // followed by a ReadyToCommitNavigation (if the navigation has succeeded), 78 // and should always end with a DidFinishNavigation. 79 // TODO(dgozman): ReadyToCommitNavigation will be removed soon. 80 // 81 // Unfortunately, this is currently a mess. For example, some started 82 // navigations which did not commit won't receive any further notifications. 83 // DidCommitProvisionalLoad will be called for same-document navigations, 84 // without any other notifications. DidFailProvisionalLoad will be called 85 // when committing error pages, in addition to all the methods (start, ready, 86 // commit) for the error page load itself. 87 88 // Called when the RenderFrame has started a navigation. 89 // |url| is a url being navigated to. Note that final url might be different 90 // due to redirects. 91 // |navigation_type| is only present for renderer-initiated navigations, e.g. 92 // JavaScript call, link click, form submit. User-initiated navigations from 93 // the browser process (e.g. by typing a url) won't have a navigation type. DidStartNavigation(const GURL & url,base::Optional<blink::WebNavigationType> navigation_type)94 virtual void DidStartNavigation( 95 const GURL& url, 96 base::Optional<blink::WebNavigationType> navigation_type) {} 97 98 // Called when a navigation has just committed and |document_loader| 99 // will start loading a new document in the RenderFrame. 100 // TODO(dgozman): the name does not match functionality anymore, we should 101 // merge this with DidCommitProvisionalLoad, which will become 102 // DidFinishNavigation. ReadyToCommitNavigation(blink::WebDocumentLoader * document_loader)103 virtual void ReadyToCommitNavigation( 104 blink::WebDocumentLoader* document_loader) {} 105 106 // Called when a RenderFrame's page lifecycle state gets updated. DidSetPageLifecycleState()107 virtual void DidSetPageLifecycleState() {} 108 109 // These match the Blink API notifications DidCreateNewDocument()110 virtual void DidCreateNewDocument() {} DidCreateDocumentElement()111 virtual void DidCreateDocumentElement() {} 112 // TODO(dgozman): replace next two methods with DidFinishNavigation. 113 // DidCommitProvisionalLoad is only called for new-document navigations. 114 // Use DidFinishSameDocumentNavigation for same-document navigations. DidCommitProvisionalLoad(ui::PageTransition transition)115 virtual void DidCommitProvisionalLoad(ui::PageTransition transition) {} DidFailProvisionalLoad()116 virtual void DidFailProvisionalLoad() {} DidFinishLoad()117 virtual void DidFinishLoad() {} DidFinishDocumentLoad()118 virtual void DidFinishDocumentLoad() {} DidHandleOnloadEvents()119 virtual void DidHandleOnloadEvents() {} DidCreateScriptContext(v8::Local<v8::Context> context,int32_t world_id)120 virtual void DidCreateScriptContext(v8::Local<v8::Context> context, 121 int32_t world_id) {} WillReleaseScriptContext(v8::Local<v8::Context> context,int32_t world_id)122 virtual void WillReleaseScriptContext(v8::Local<v8::Context> context, 123 int32_t world_id) {} DidClearWindowObject()124 virtual void DidClearWindowObject() {} DidChangeScrollOffset()125 virtual void DidChangeScrollOffset() {} WillSendSubmitEvent(const blink::WebFormElement & form)126 virtual void WillSendSubmitEvent(const blink::WebFormElement& form) {} WillSubmitForm(const blink::WebFormElement & form)127 virtual void WillSubmitForm(const blink::WebFormElement& form) {} DidMatchCSS(const blink::WebVector<blink::WebString> & newly_matching_selectors,const blink::WebVector<blink::WebString> & stopped_matching_selectors)128 virtual void DidMatchCSS( 129 const blink::WebVector<blink::WebString>& newly_matching_selectors, 130 const blink::WebVector<blink::WebString>& stopped_matching_selectors) {} 131 132 // Called when same-document navigation finishes. 133 // This is the only callback for same-document navigations, 134 // DidStartNavigation and ReadyToCommitNavigation are not called. 135 // 136 // Same-document navigation is typically initiated by an anchor click 137 // (that usually results in the page scrolling to the anchor) or a 138 // history web API manipulation. 139 // 140 // However, it could be some rare case like user changing #hash in the url 141 // bar or history restore for subframe or anything else that was classified 142 // as same-document. DidFinishSameDocumentNavigation()143 virtual void DidFinishSameDocumentNavigation() {} 144 145 // Called when this frame has been detached from the view. This *will* be 146 // called for child frames when a parent frame is detached. Since the frame is 147 // already detached from the DOM at this time, it should not be inspected. WillDetach()148 virtual void WillDetach() {} 149 150 // Called when we receive a console message from Blink for which we requested 151 // extra details (like the stack trace). |message| is the error message, 152 // |source| is the Blink-reported source of the error (either external or 153 // internal), and |stack_trace| is the stack trace of the error in a 154 // human-readable format (each frame is formatted as 155 // "\n at function_name (source:line_number:column_number)"). DetailedConsoleMessageAdded(const base::string16 & message,const base::string16 & source,const base::string16 & stack_trace,uint32_t line_number,int32_t severity_level)156 virtual void DetailedConsoleMessageAdded(const base::string16& message, 157 const base::string16& source, 158 const base::string16& stack_trace, 159 uint32_t line_number, 160 int32_t severity_level) {} 161 162 // Called when an interesting (from document lifecycle perspective), 163 // compositor-driven layout had happened. This is a reasonable hook to use 164 // to inspect the document and layout information, since it is in a clean 165 // state and you won't accidentally force new layouts. 166 // The interestingness of layouts is explained in WebMeaningfulLayout.h. DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type)167 virtual void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) {} 168 169 // Notifications when |PerformanceTiming| data becomes available DidChangePerformanceTiming()170 virtual void DidChangePerformanceTiming() {} 171 172 // Notifications When an input delay data becomes available. DidObserveInputDelay(base::TimeDelta input_delay)173 virtual void DidObserveInputDelay(base::TimeDelta input_delay) {} 174 175 // Notification When the First Scroll Delay becomes available. DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay)176 virtual void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay) {} 177 178 // Notifications when a cpu timing update becomes available, when a frame 179 // has performed at least 100ms of tasks. DidChangeCpuTiming(base::TimeDelta time)180 virtual void DidChangeCpuTiming(base::TimeDelta time) {} 181 182 // Notification when the renderer uses a particular code path during a page 183 // load. This is used for metrics collection. DidObserveLoadingBehavior(blink::LoadingBehaviorFlag behavior)184 virtual void DidObserveLoadingBehavior(blink::LoadingBehaviorFlag behavior) {} 185 186 // Notification when the renderer observes a new use counter usage during a 187 // page load. This is used for UseCounter metrics. DidObserveNewFeatureUsage(blink::mojom::WebFeature feature)188 virtual void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) {} DidObserveNewCssPropertyUsage(blink::mojom::CSSSampleId css_property,bool is_animated)189 virtual void DidObserveNewCssPropertyUsage( 190 blink::mojom::CSSSampleId css_property, 191 bool is_animated) {} 192 193 // Reports that visible elements in the frame shifted (bit.ly/lsm-explainer). 194 // This is called once for each animation frame containing any layout shift, 195 // and receives the layout shift (LS) score for that frame. The cumulative 196 // layout shift (CLS) score can be inferred by summing the LS scores. 197 // |after_input_or_scroll| indicates whether the given |score| was observed 198 // after an input or scroll occurred in the associated document. DidObserveLayoutShift(double score,bool after_input_or_scroll)199 virtual void DidObserveLayoutShift(double score, bool after_input_or_scroll) { 200 } 201 202 // Reports the number of LayoutBlock creation, and LayoutObject::UpdateLayout 203 // calls. All values are deltas since the last calls of this function. DidObserveLayoutNg(uint32_t all_block_count,uint32_t ng_block_count,uint32_t all_call_count,uint32_t ng_call_count)204 virtual void DidObserveLayoutNg(uint32_t all_block_count, 205 uint32_t ng_block_count, 206 uint32_t all_call_count, 207 uint32_t ng_call_count) {} 208 209 // Reports lazy loaded behavior when the frame or image is fully deferred or 210 // if the frame or image is loaded after being deferred by lazy load. 211 // Called every time the behavior occurs. This does not apply to image 212 // requests for placeholder images. DidObserveLazyLoadBehavior(blink::WebLocalFrameClient::LazyLoadBehavior lazy_load_behavior)213 virtual void DidObserveLazyLoadBehavior( 214 blink::WebLocalFrameClient::LazyLoadBehavior lazy_load_behavior) {} 215 216 // Notification when the renderer a response started, completed or canceled. 217 // Complete or Cancel is guaranteed to be called for a response that started. 218 // |request_id| uniquely identifies the request within this render frame. 219 // |previews_state| is the PreviewsState if the request is a sub-resource. For 220 // Document resources, |previews_state| should be reported as PREVIEWS_OFF. DidStartResponse(const GURL & response_url,int request_id,const network::mojom::URLResponseHead & response_head,network::mojom::RequestDestination request_destination,blink::PreviewsState previews_state)221 virtual void DidStartResponse( 222 const GURL& response_url, 223 int request_id, 224 const network::mojom::URLResponseHead& response_head, 225 network::mojom::RequestDestination request_destination, 226 blink::PreviewsState previews_state) {} DidCompleteResponse(int request_id,const network::URLLoaderCompletionStatus & status)227 virtual void DidCompleteResponse( 228 int request_id, 229 const network::URLLoaderCompletionStatus& status) {} DidCancelResponse(int request_id)230 virtual void DidCancelResponse(int request_id) {} 231 232 // Reports that a resource was loaded from the blink memory cache. 233 // |request_id| uniquely identifies this resource within this render frame. 234 // |from_archive| indicates if the resource originated from a MHTML archive. DidLoadResourceFromMemoryCache(const GURL & response_url,int request_id,int64_t encoded_body_length,const std::string & mime_type,bool from_archive)235 virtual void DidLoadResourceFromMemoryCache(const GURL& response_url, 236 int request_id, 237 int64_t encoded_body_length, 238 const std::string& mime_type, 239 bool from_archive) {} 240 241 // Notification when the renderer observes data used during the page load. 242 // This is used for page load metrics. |received_data_length| is the received 243 // network bytes. |resource_id| uniquely identifies the resource within this 244 // render frame. DidReceiveTransferSizeUpdate(int resource_id,int received_data_length)245 virtual void DidReceiveTransferSizeUpdate(int resource_id, 246 int received_data_length) {} 247 248 // Called when the focused element has changed to |element|. FocusedElementChanged(const blink::WebElement & element)249 virtual void FocusedElementChanged(const blink::WebElement& element) {} 250 251 // Called when accessibility is enabled or disabled. AccessibilityModeChanged(const ui::AXMode & mode)252 virtual void AccessibilityModeChanged(const ui::AXMode& mode) {} 253 254 // Called when script in the page calls window.print(). ScriptedPrint(bool user_initiated)255 virtual void ScriptedPrint(bool user_initiated) {} 256 257 // Called when draggable regions change. DraggableRegionsChanged()258 virtual void DraggableRegionsChanged() {} 259 260 // Called when a worker fetch context will be created. WillCreateWorkerFetchContext(blink::WebWorkerFetchContext *)261 virtual void WillCreateWorkerFetchContext(blink::WebWorkerFetchContext*) {} 262 263 // Called when a frame's intersection with the main frame changes. OnMainFrameIntersectionChanged(const blink::WebRect & intersect_rect)264 virtual void OnMainFrameIntersectionChanged( 265 const blink::WebRect& intersect_rect) {} 266 267 // Called to give the embedder an opportunity to bind an interface request 268 // for a frame. If the request can be bound, |interface_pipe| will be taken. OnInterfaceRequestForFrame(const std::string & interface_name,mojo::ScopedMessagePipeHandle * interface_pipe)269 virtual void OnInterfaceRequestForFrame( 270 const std::string& interface_name, 271 mojo::ScopedMessagePipeHandle* interface_pipe) {} 272 273 // Similar to above but for handling Channel-associated interface requests. 274 // Returns |true| if the request is handled by the implementation (taking 275 // ownership of |*handle|) and |false| otherwise (leaving |*handle| 276 // unmodified). 277 virtual bool OnAssociatedInterfaceRequestForFrame( 278 const std::string& interface_name, 279 mojo::ScopedInterfaceEndpointHandle* handle); 280 281 // Called when a page's mobile friendliness changed. OnMobileFriendlinessChanged(const blink::MobileFriendliness &)282 virtual void OnMobileFriendlinessChanged(const blink::MobileFriendliness&) {} 283 284 // The smoothness metrics is shared over shared-memory. The interested 285 // observer should invalidate |shared_memory| (by std::move()'ing it), and 286 // return true. All other observers should return false (default). 287 virtual bool SetUpSmoothnessReporting( 288 base::ReadOnlySharedMemoryRegion& shared_memory); 289 290 // IPC::Listener implementation. 291 bool OnMessageReceived(const IPC::Message& message) override; 292 293 // IPC::Sender implementation. 294 bool Send(IPC::Message* message) override; 295 296 RenderFrame* render_frame() const; routing_id()297 int routing_id() const { return routing_id_; } 298 299 protected: 300 explicit RenderFrameObserver(RenderFrame* render_frame); 301 ~RenderFrameObserver() override; 302 303 private: 304 friend class RenderFrameImpl; 305 306 // This is called by the RenderFrame when it's going away so that this object 307 // can null out its pointer. 308 void RenderFrameGone(); 309 310 RenderFrame* render_frame_; 311 // The routing ID of the associated RenderFrame. 312 int routing_id_; 313 314 DISALLOW_COPY_AND_ASSIGN(RenderFrameObserver); 315 }; 316 317 } // namespace content 318 319 #endif // CONTENT_PUBLIC_RENDERER_RENDER_FRAME_OBSERVER_H_ 320