no_state_prefetch_contents.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. // Copyright (c) 2012 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. #ifndef COMPONENTS_NO_STATE_PREFETCH_BROWSER_NO_STATE_PREFETCH_CONTENTS_H_
  5. #define COMPONENTS_NO_STATE_PREFETCH_BROWSER_NO_STATE_PREFETCH_CONTENTS_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/observer_list.h"
  14. #include "base/time/time.h"
  15. #include "base/values.h"
  16. #include "components/no_state_prefetch/browser/no_state_prefetch_contents_delegate.h"
  17. #include "components/no_state_prefetch/common/no_state_prefetch_final_status.h"
  18. #include "components/no_state_prefetch/common/prerender_canceler.mojom.h"
  19. #include "components/no_state_prefetch/common/prerender_origin.h"
  20. #include "content/public/browser/web_contents_observer.h"
  21. #include "content/public/common/referrer.h"
  22. #include "mojo/public/cpp/bindings/receiver_set.h"
  23. #include "third_party/abseil-cpp/absl/types/optional.h"
  24. #include "ui/gfx/geometry/rect.h"
  25. #include "url/origin.h"
  26. namespace base {
  27. class ProcessMetrics;
  28. }
  29. namespace content {
  30. class BrowserContext;
  31. class RenderViewHost;
  32. class SessionStorageNamespace;
  33. class WebContents;
  34. } // namespace content
  35. namespace memory_instrumentation {
  36. class GlobalMemoryDump;
  37. }
  38. namespace prerender {
  39. class NoStatePrefetchManager;
  40. class NoStatePrefetchContents : public content::WebContentsObserver,
  41. public prerender::mojom::PrerenderCanceler {
  42. public:
  43. // NoStatePrefetchContents::Create uses the currently registered Factory to
  44. // create the NoStatePrefetchContents. Factory is intended for testing.
  45. class Factory {
  46. public:
  47. Factory() {}
  48. Factory(const Factory&) = delete;
  49. Factory& operator=(const Factory&) = delete;
  50. virtual ~Factory() {}
  51. // Ownership is not transferred through this interface as
  52. // no_state_prefetch_manager and browser_context are stored as weak
  53. // pointers.
  54. virtual NoStatePrefetchContents* CreateNoStatePrefetchContents(
  55. std::unique_ptr<NoStatePrefetchContentsDelegate> delegate,
  56. NoStatePrefetchManager* no_state_prefetch_manager,
  57. content::BrowserContext* browser_context,
  58. const GURL& url,
  59. const content::Referrer& referrer,
  60. const absl::optional<url::Origin>& initiator_origin,
  61. Origin origin) = 0;
  62. };
  63. class Observer {
  64. public:
  65. // Signals that the prefetch has started running.
  66. virtual void OnPrefetchStart(NoStatePrefetchContents* contents) {}
  67. // Signals that the prefetch has had its load event.
  68. virtual void OnPrefetchStopLoading(NoStatePrefetchContents* contents) {}
  69. // Signals that the prefetch has stopped running.
  70. // A NoStatePrefetchContents with an unset final status will always call
  71. // OnPrefetchStop before being destroyed.
  72. virtual void OnPrefetchStop(NoStatePrefetchContents* contents) {}
  73. // Signals that a resource finished loading and altered the running byte
  74. // count.
  75. virtual void OnPrefetchNetworkBytesChanged(
  76. NoStatePrefetchContents* contents) {}
  77. protected:
  78. Observer() {}
  79. virtual ~Observer() = 0;
  80. };
  81. NoStatePrefetchContents(const NoStatePrefetchContents&) = delete;
  82. NoStatePrefetchContents& operator=(const NoStatePrefetchContents&) = delete;
  83. ~NoStatePrefetchContents() override;
  84. // All observers of a NoStatePrefetchContents are removed after the
  85. // OnPrefetchStop event is sent, so there is no need to call RemoveObserver()
  86. // in the normal use case.
  87. void AddObserver(Observer* observer);
  88. void RemoveObserver(Observer* observer);
  89. bool Init();
  90. static Factory* CreateFactory();
  91. // Starts rendering the contents in the prerendered state.
  92. // |bounds| indicates the rectangle that the prerendered page should be in.
  93. // |session_storage_namespace| indicates the namespace that the prerendered
  94. // page should be part of.
  95. virtual void StartPrerendering(
  96. const gfx::Rect& bounds,
  97. content::SessionStorageNamespace* session_storage_namespace);
  98. // Verifies that the prerendering is not using too many resources, and kills
  99. // it if not.
  100. void DestroyWhenUsingTooManyResources();
  101. content::RenderFrameHost* GetPrimaryMainFrame();
  102. NoStatePrefetchManager* no_state_prefetch_manager() {
  103. return no_state_prefetch_manager_;
  104. }
  105. const GURL& prerender_url() const { return prerender_url_; }
  106. bool has_finished_loading() const { return has_finished_loading_; }
  107. bool prerendering_has_started() const { return prerendering_has_started_; }
  108. FinalStatus final_status() const { return final_status_; }
  109. Origin origin() const { return origin_; }
  110. base::TimeTicks load_start_time() const { return load_start_time_; }
  111. // Indicates whether this prerendered page can be used for the provided
  112. // |url| and |session_storage_namespace|.
  113. bool Matches(
  114. const GURL& url,
  115. content::SessionStorageNamespace* session_storage_namespace) const;
  116. // content::WebContentsObserver implementation.
  117. void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
  118. void DidStopLoading() override;
  119. void DidStartNavigation(
  120. content::NavigationHandle* navigation_handle) override;
  121. void DidRedirectNavigation(
  122. content::NavigationHandle* navigation_handle) override;
  123. void DidFinishLoad(content::RenderFrameHost* render_frame_host,
  124. const GURL& validated_url) override;
  125. void DidFinishNavigation(
  126. content::NavigationHandle* navigation_handle) override;
  127. void PrimaryMainFrameRenderProcessGone(
  128. base::TerminationStatus status) override;
  129. // Checks that a URL may be prerendered, for one of the many redirections. If
  130. // the URL can not be prerendered - for example, it's an ftp URL - |this| will
  131. // be destroyed and false is returned. Otherwise, true is returned.
  132. virtual bool CheckURL(const GURL& url);
  133. // Adds an alias URL. If the URL can not be prerendered, |this| will be
  134. // destroyed and false is returned.
  135. bool AddAliasURL(const GURL& url);
  136. // The WebContents for NoStatePrefetch (may be NULL).
  137. content::WebContents* no_state_prefetch_contents() const {
  138. return no_state_prefetch_contents_.get();
  139. }
  140. // Sets the final status, calls OnDestroy and adds |this| to the
  141. // NoStatePrefetchManager's pending deletes list.
  142. void Destroy(FinalStatus reason);
  143. std::unique_ptr<base::DictionaryValue> GetAsValue() const;
  144. // This function is not currently called in production since prerendered
  145. // contents are never used (only prefetch is supported), but it may be used in
  146. // the future: https://crbug.com/1126305
  147. void MarkAsUsedForTesting();
  148. // Increments the number of bytes fetched over the network for this prerender.
  149. void AddNetworkBytes(int64_t bytes);
  150. bool prerendering_has_been_cancelled() const {
  151. return prerendering_has_been_cancelled_;
  152. }
  153. // Running byte count. Increased when each resource completes loading.
  154. int64_t network_bytes() { return network_bytes_; }
  155. void AddPrerenderCancelerReceiver(
  156. mojo::PendingReceiver<prerender::mojom::PrerenderCanceler> receiver);
  157. protected:
  158. NoStatePrefetchContents(
  159. std::unique_ptr<NoStatePrefetchContentsDelegate> delegate,
  160. NoStatePrefetchManager* no_state_prefetch_manager,
  161. content::BrowserContext* browser_context,
  162. const GURL& url,
  163. const content::Referrer& referrer,
  164. const absl::optional<url::Origin>& initiator_origin,
  165. Origin origin);
  166. // Set the final status for how the NoStatePrefetchContents was used. This
  167. // should only be called once, and should be called before the prerender
  168. // contents are destroyed.
  169. void SetFinalStatus(FinalStatus final_status);
  170. // These call out to methods on our Observers, using our observer_list_. Note
  171. // that NotifyPrefetchStop() also clears the observer list.
  172. void NotifyPrefetchStart();
  173. void NotifyPrefetchStopLoading();
  174. void NotifyPrefetchStop();
  175. std::unique_ptr<content::WebContents> CreateWebContents(
  176. content::SessionStorageNamespace* session_storage_namespace);
  177. bool prerendering_has_started_;
  178. // Time at which we started to load the URL. This is used to compute
  179. // the time elapsed from initiating a prerender until the time the
  180. // (potentially only partially) prerendered page is shown to the user.
  181. base::TimeTicks load_start_time_;
  182. // The WebContents for NoStatePrefetch; may be null.
  183. std::unique_ptr<content::WebContents> no_state_prefetch_contents_;
  184. // The session storage namespace id for use in matching. We must save it
  185. // rather than get it from the RenderViewHost since in the control group
  186. // we won't have a RenderViewHost.
  187. std::string session_storage_namespace_id_;
  188. private:
  189. class WebContentsDelegateImpl;
  190. // Needs to be able to call the constructor.
  191. friend class NoStatePrefetchContentsFactoryImpl;
  192. // Returns the ProcessMetrics for the render process, if it exists.
  193. void DidGetMemoryUsage(
  194. bool success,
  195. std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
  196. // prerender::mojom::PrerenderCanceler:
  197. void CancelPrerenderForUnsupportedScheme() override;
  198. void CancelPrerenderForNoStatePrefetch() override;
  199. mojo::ReceiverSet<prerender::mojom::PrerenderCanceler>
  200. prerender_canceler_receiver_set_;
  201. base::ObserverList<Observer>::Unchecked observer_list_;
  202. // The prefetch manager owning this object.
  203. raw_ptr<NoStatePrefetchManager> no_state_prefetch_manager_;
  204. // The delegate that content embedders use to override this class's logic.
  205. std::unique_ptr<NoStatePrefetchContentsDelegate> delegate_;
  206. // The URL being prerendered.
  207. const GURL prerender_url_;
  208. // The referrer.
  209. const content::Referrer referrer_;
  210. // The origin of the page requesting the prerender. Empty when the prerender
  211. // is browser initiated.
  212. const absl::optional<url::Origin> initiator_origin_;
  213. // The browser context being used
  214. raw_ptr<content::BrowserContext> browser_context_;
  215. // A vector of URLs that this prerendered page matches against.
  216. // This array can contain more than element as a result of redirects,
  217. // such as HTTP redirects or javascript redirects.
  218. std::vector<GURL> alias_urls_;
  219. // True when the main frame has finished loading.
  220. bool has_finished_loading_;
  221. FinalStatus final_status_;
  222. // Tracks whether or not prerendering has been cancelled by calling Destroy.
  223. // Used solely to prevent double deletion.
  224. bool prerendering_has_been_cancelled_;
  225. // Pid of the render process associated with the RenderViewHost for this
  226. // object.
  227. base::ProcessId process_pid_;
  228. std::unique_ptr<WebContentsDelegateImpl> web_contents_delegate_;
  229. // Origin for this prerender.
  230. const Origin origin_;
  231. // The bounds of the WebView from the launching page.
  232. gfx::Rect bounds_;
  233. // A running tally of the number of bytes this prerender has caused to be
  234. // transferred over the network for resources. Updated with AddNetworkBytes.
  235. int64_t network_bytes_;
  236. base::WeakPtrFactory<NoStatePrefetchContents> weak_factory_{this};
  237. };
  238. } // namespace prerender
  239. #endif // COMPONENTS_NO_STATE_PREFETCH_BROWSER_NO_STATE_PREFETCH_CONTENTS_H_