[Cronet] Delay StartNetLog and StopNetLog until native request context is initialized
[chromium-blink-merge.git] / chrome / browser / prerender / prerender_manager.h
blobf1a0c7ed46019f341c9f6c0529f1e0b535120dff
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.
5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_
8 #include <list>
9 #include <string>
10 #include <vector>
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/task/cancelable_task_tracker.h"
17 #include "base/threading/non_thread_safe.h"
18 #include "base/time/time.h"
19 #include "base/timer/timer.h"
20 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
21 #include "chrome/browser/predictors/logged_in_predictor_table.h"
22 #include "chrome/browser/prerender/prerender_config.h"
23 #include "chrome/browser/prerender/prerender_contents.h"
24 #include "chrome/browser/prerender/prerender_final_status.h"
25 #include "chrome/browser/prerender/prerender_histograms.h"
26 #include "chrome/browser/prerender/prerender_origin.h"
27 #include "components/history/core/browser/history_service.h"
28 #include "components/keyed_service/core/keyed_service.h"
29 #include "content/public/browser/notification_observer.h"
30 #include "content/public/browser/notification_registrar.h"
31 #include "content/public/browser/render_process_host_observer.h"
32 #include "net/cookies/cookie_monster.h"
33 #include "url/gurl.h"
35 class Profile;
36 class InstantSearchPrerendererTest;
37 struct ChromeCookieDetails;
39 namespace base {
40 class DictionaryValue;
43 namespace chrome {
44 struct NavigateParams;
47 namespace content {
48 class WebContents;
51 namespace gfx {
52 class Size;
55 namespace prerender {
57 class PrerenderHandle;
58 class PrerenderHistory;
59 class PrerenderLocalPredictor;
61 // PrerenderManager is responsible for initiating and keeping prerendered
62 // views of web pages. All methods must be called on the UI thread unless
63 // indicated otherwise.
64 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
65 public base::NonThreadSafe,
66 public content::NotificationObserver,
67 public content::RenderProcessHostObserver,
68 public KeyedService,
69 public MediaCaptureDevicesDispatcher::Observer {
70 public:
71 // NOTE: New values need to be appended, since they are used in histograms.
72 enum PrerenderManagerMode {
73 PRERENDER_MODE_DISABLED = 0,
74 PRERENDER_MODE_ENABLED = 1,
75 PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2,
76 PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3,
77 // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4,
78 PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5,
79 PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6,
80 PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7,
81 PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP = 8,
82 PRERENDER_MODE_MAX
85 // One or more of these flags must be passed to ClearData() to specify just
86 // what data to clear. See function declaration for more information.
87 enum ClearFlags {
88 CLEAR_PRERENDER_CONTENTS = 0x1 << 0,
89 CLEAR_PRERENDER_HISTORY = 0x1 << 1,
90 CLEAR_MAX = 0x1 << 2
93 typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap;
95 // ID indicating that no experiment is active.
96 static const uint8 kNoExperiment = 0;
98 // Owned by a Profile object for the lifetime of the profile.
99 explicit PrerenderManager(Profile* profile);
101 ~PrerenderManager() override;
103 // From KeyedService:
104 void Shutdown() override;
106 // Entry points for adding prerenders.
108 // Adds a prerender for |url| if valid. |process_id| and |route_id| identify
109 // the RenderView that the prerender request came from. If |size| is empty, a
110 // default from the PrerenderConfig is used. Returns a caller-owned
111 // PrerenderHandle* if the URL was added, NULL if it was not. If the launching
112 // RenderView is itself prerendering, the prerender is added as a pending
113 // prerender.
114 PrerenderHandle* AddPrerenderFromLinkRelPrerender(
115 int process_id,
116 int route_id,
117 const GURL& url,
118 uint32 rel_types,
119 const content::Referrer& referrer,
120 const gfx::Size& size);
122 // Adds a prerender for |url| if valid. As the prerender request is coming
123 // from a source without a RenderFrameHost (i.e., the omnibox) we don't have a
124 // child or route id, or a referrer. This method uses sensible values for
125 // those. The |session_storage_namespace| matches the namespace of the active
126 // tab at the time the prerender is generated from the omnibox. Returns a
127 // caller-owned PrerenderHandle*, or NULL.
128 PrerenderHandle* AddPrerenderFromOmnibox(
129 const GURL& url,
130 content::SessionStorageNamespace* session_storage_namespace,
131 const gfx::Size& size);
133 PrerenderHandle* AddPrerenderFromLocalPredictor(
134 const GURL& url,
135 content::SessionStorageNamespace* session_storage_namespace,
136 const gfx::Size& size);
138 PrerenderHandle* AddPrerenderFromExternalRequest(
139 const GURL& url,
140 const content::Referrer& referrer,
141 content::SessionStorageNamespace* session_storage_namespace,
142 const gfx::Size& size);
144 // Adds a prerender for Instant Search |url| if valid. The
145 // |session_storage_namespace| matches the namespace of the active tab at the
146 // time the prerender is generated. Returns a caller-owned PrerenderHandle* or
147 // NULL.
148 PrerenderHandle* AddPrerenderForInstant(
149 const GURL& url,
150 content::SessionStorageNamespace* session_storage_namespace,
151 const gfx::Size& size);
153 // Cancels all active prerenders.
154 void CancelAllPrerenders();
156 // If |url| matches a valid prerendered page and |params| are compatible, try
157 // to swap it and merge browsing histories. Returns |true| and updates
158 // |params->target_contents| if a prerendered page is swapped in, |false|
159 // otherwise.
160 bool MaybeUsePrerenderedPage(const GURL& url,
161 chrome::NavigateParams* params);
163 // Moves a PrerenderContents to the pending delete list from the list of
164 // active prerenders when prerendering should be cancelled.
165 virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
166 FinalStatus final_status);
168 // Records the page load time for a prerender that wasn't swapped in.
169 void RecordPageLoadTimeNotSwappedIn(Origin origin,
170 base::TimeDelta page_load_time,
171 const GURL& url);
173 // Records the perceived page load time for a page - effectively the time from
174 // when the user navigates to a page to when it finishes loading. The actual
175 // load may have started prior to navigation due to prerender hints.
176 // This must be called on the UI thread.
177 // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value
178 // outside that range indicating that it doesn't apply.
179 void RecordPerceivedPageLoadTime(
180 Origin origin,
181 NavigationType navigation_type,
182 base::TimeDelta perceived_page_load_time,
183 double fraction_plt_elapsed_at_swap_in,
184 const GURL& url);
186 static PrerenderManagerMode GetMode();
187 static void SetMode(PrerenderManagerMode mode);
188 static const char* GetModeString();
189 static bool IsPrerenderingPossible();
190 static bool ActuallyPrerendering();
191 static bool IsControlGroup(uint8 experiment_id);
192 static bool IsNoUseGroup();
194 // Query the list of current prerender pages to see if the given web contents
195 // is prerendering a page. The optional parameter |origin| is an output
196 // parameter which, if a prerender is found, is set to the Origin of the
197 // prerender |web_contents|.
198 bool IsWebContentsPrerendering(const content::WebContents* web_contents,
199 Origin* origin) const;
201 // Whether the PrerenderManager has an active prerender with the given url and
202 // SessionStorageNamespace associated with the given WebContens.
203 bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const;
205 // Returns the PrerenderContents object for the given web_contents, otherwise
206 // returns NULL. Note that the PrerenderContents may have been Destroy()ed,
207 // but not yet deleted.
208 PrerenderContents* GetPrerenderContents(
209 const content::WebContents* web_contents) const;
211 // Returns the PrerenderContents object for a given child_id, route_id pair,
212 // otherwise returns NULL. Note that the PrerenderContents may have been
213 // Destroy()ed, but not yet deleted.
214 virtual PrerenderContents* GetPrerenderContentsForRoute(
215 int child_id, int route_id) const;
217 // Returns a list of all WebContents being prerendered.
218 const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
220 // Checks whether |url| has been recently navigated to.
221 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
223 // Returns true iff the method given is valid for prerendering.
224 static bool IsValidHttpMethod(const std::string& method);
226 // Returns true iff the scheme of the URL given is valid for prerendering.
227 static bool DoesURLHaveValidScheme(const GURL& url);
229 // Returns true iff the scheme of the subresource URL given is valid for
230 // prerendering.
231 static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
233 // Returns a Value object containing the active pages being prerendered, and
234 // a history of pages which were prerendered. The caller is responsible for
235 // deleting the return value.
236 base::DictionaryValue* GetAsValue() const;
238 // Clears the data indicated by which bits of clear_flags are set.
240 // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are
241 // cancelled and then deleted, and any WebContents queued for destruction are
242 // destroyed as well.
244 // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is
245 // cleared, including any entries newly created by destroying them in
246 // response to the CLEAR_PRERENDER_CONTENTS flag.
248 // Intended to be used when clearing the cache or history.
249 void ClearData(int clear_flags);
251 // Record a final status of a prerendered page in a histogram.
252 // This variation allows specifying whether prerendering had been started
253 // (necessary to flag MatchComplete dummies).
254 void RecordFinalStatusWithMatchCompleteStatus(
255 Origin origin,
256 uint8 experiment_id,
257 PrerenderContents::MatchCompleteStatus mc_status,
258 FinalStatus final_status) const;
260 // content::NotificationObserver
261 void Observe(int type,
262 const content::NotificationSource& source,
263 const content::NotificationDetails& details) override;
265 // MediaCaptureDevicesDispatcher::Observer
266 void OnCreatingAudioStream(int render_process_id,
267 int render_frame_id) override;
269 const Config& config() const { return config_; }
270 Config& mutable_config() { return config_; }
272 // Records that some visible tab navigated (or was redirected) to the
273 // provided URL.
274 void RecordNavigation(const GURL& url);
276 // Updates the LoggedInPredictor state to reflect that a login has likely
277 // on the URL provided.
278 void RecordLikelyLoginOnURL(const GURL& url);
280 // Checks if the LoggedInPredictor shows that the user is likely logged on
281 // to the site for the URL provided.
282 void CheckIfLikelyLoggedInOnURL(const GURL& url,
283 bool* lookup_result,
284 bool* database_was_present,
285 const base::Closure& result_cb);
287 void OnHistoryServiceDidQueryURL(Origin origin,
288 uint8 experiment_id,
289 bool success,
290 const history::URLRow& url_row,
291 const history::VisitVector& visits);
293 Profile* profile() const { return profile_; }
295 // Classes which will be tested in prerender unit browser tests should use
296 // these methods to get times for comparison, so that the test framework can
297 // mock advancing/retarding time.
298 virtual base::Time GetCurrentTime() const;
299 virtual base::TimeTicks GetCurrentTimeTicks() const;
301 scoped_refptr<predictors::LoggedInPredictorTable>
302 logged_in_predictor_table() {
303 return logged_in_predictor_table_;
306 PrerenderLocalPredictor* local_predictor() {
307 return local_predictor_.get();
310 // Notification that a prerender has completed and its bytes should be
311 // recorded.
312 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes);
314 // Returns whether prerendering is currently enabled for this manager.
315 bool IsEnabled() const;
317 // Add to the running tally of bytes transferred over the network for this
318 // profile if prerendering is currently enabled.
319 void AddProfileNetworkBytesIfEnabled(int64 bytes);
321 // Registers a new ProcessHost performing a prerender. Called by
322 // PrerenderContents.
323 void AddPrerenderProcessHost(content::RenderProcessHost* process_host);
325 // Returns whether or not |process_host| may be reused for new navigations
326 // from a prerendering perspective. Currently, if Prerender Cookie Stores are
327 // enabled, prerenders must be in their own processes that may not be shared.
328 bool MayReuseProcessHost(content::RenderProcessHost* process_host);
330 // content::RenderProcessHostObserver implementation.
331 void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
333 protected:
334 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
335 public:
336 struct OrderByExpiryTime;
338 PrerenderData(PrerenderManager* manager,
339 PrerenderContents* contents,
340 base::TimeTicks expiry_time);
342 ~PrerenderData();
344 // Turn this PrerenderData into a Match Complete replacement for itself,
345 // placing the current prerender contents into |to_delete_prerenders_|.
346 void MakeIntoMatchCompleteReplacement();
348 // A new PrerenderHandle has been created for this PrerenderData.
349 void OnHandleCreated(PrerenderHandle* prerender_handle);
351 // The launcher associated with a handle is navigating away from the context
352 // that launched this prerender. If the prerender is active, it may stay
353 // alive briefly though, in case we we going through a redirect chain that
354 // will eventually land at it.
355 void OnHandleNavigatedAway(PrerenderHandle* prerender_handle);
357 // The launcher associated with a handle has taken explicit action to cancel
358 // this prerender. We may well destroy the prerender in this case if no
359 // other handles continue to track it.
360 void OnHandleCanceled(PrerenderHandle* prerender_handle);
362 PrerenderContents* contents() { return contents_.get(); }
364 PrerenderContents* ReleaseContents();
366 int handle_count() const { return handle_count_; }
368 base::TimeTicks abandon_time() const { return abandon_time_; }
370 base::TimeTicks expiry_time() const { return expiry_time_; }
371 void set_expiry_time(base::TimeTicks expiry_time) {
372 expiry_time_ = expiry_time;
375 private:
376 PrerenderManager* manager_;
377 scoped_ptr<PrerenderContents> contents_;
379 // The number of distinct PrerenderHandles created for |this|, including
380 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not
381 // counting the ones that have called PrerenderData::OnHandleCanceled(). For
382 // pending prerenders, this will always be 1, since the PrerenderManager
383 // only merges handles of running prerenders.
384 int handle_count_;
386 // The time when OnHandleNavigatedAway was called.
387 base::TimeTicks abandon_time_;
389 // After this time, this prerender is no longer fresh, and should be
390 // removed.
391 base::TimeTicks expiry_time_;
393 DISALLOW_COPY_AND_ASSIGN(PrerenderData);
396 void SetPrerenderContentsFactory(
397 PrerenderContents::Factory* prerender_contents_factory);
399 // Called by a PrerenderData to signal that the launcher has navigated away
400 // from the context that launched the prerender. A user may have clicked
401 // a link in a page containing a <link rel=prerender> element, or the user
402 // might have committed an omnibox navigation. This is used to possibly
403 // shorten the TTL of the prerendered page.
404 void SourceNavigatedAway(PrerenderData* prerender_data);
406 private:
407 friend class ::InstantSearchPrerendererTest;
408 friend class PrerenderBrowserTest;
409 friend class PrerenderContents;
410 friend class PrerenderHandle;
411 friend class UnitTestPrerenderManager;
413 class OnCloseWebContentsDeleter;
414 struct NavigationRecord;
416 // Time interval before a new prerender is allowed.
417 static const int kMinTimeBetweenPrerendersMs = 500;
419 // Time window for which we record old navigations, in milliseconds.
420 static const int kNavigationRecordWindowMs = 5000;
422 void OnCancelPrerenderHandle(PrerenderData* prerender_data);
424 // Adds a prerender for |url| from |referrer|. The |origin| specifies how the
425 // prerender was added. If |size| is empty, then
426 // PrerenderContents::StartPrerendering will instead use a default from
427 // PrerenderConfig. Returns a PrerenderHandle*, owned by the caller, or NULL.
428 PrerenderHandle* AddPrerender(
429 Origin origin,
430 const GURL& url,
431 const content::Referrer& referrer,
432 const gfx::Size& size,
433 content::SessionStorageNamespace* session_storage_namespace);
435 void StartSchedulingPeriodicCleanups();
436 void StopSchedulingPeriodicCleanups();
438 void EvictOldestPrerendersIfNecessary();
440 // Deletes stale and cancelled prerendered PrerenderContents, as well as
441 // WebContents that have been replaced by prerendered WebContents.
442 // Also identifies and kills PrerenderContents that use too much
443 // resources.
444 void PeriodicCleanup();
446 // Posts a task to call PeriodicCleanup. Results in quicker destruction of
447 // objects. If |this| is deleted before the task is run, the task will
448 // automatically be cancelled.
449 void PostCleanupTask();
451 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
452 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
454 void DeleteOldEntries();
455 virtual PrerenderContents* CreatePrerenderContents(
456 const GURL& url,
457 const content::Referrer& referrer,
458 Origin origin,
459 uint8 experiment_id);
461 // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
462 // after every mutation of active_prerenders_ that can possibly make it
463 // unsorted (e.g. an insert, or changing an expiry time).
464 void SortActivePrerenders();
466 // Finds the active PrerenderData object for a running prerender matching
467 // |url| and |session_storage_namespace|.
468 PrerenderData* FindPrerenderData(
469 const GURL& url,
470 const content::SessionStorageNamespace* session_storage_namespace);
472 // Given the |prerender_contents|, find the iterator in active_prerenders_
473 // correponding to the given prerender.
474 ScopedVector<PrerenderData>::iterator
475 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
477 bool DoesRateLimitAllowPrerender(Origin origin) const;
479 // Deletes old WebContents that have been replaced by prerendered ones. This
480 // is needed because they're replaced in a callback from the old WebContents,
481 // so cannot immediately be deleted.
482 void DeleteOldWebContents();
484 // Cleans up old NavigationRecord's.
485 void CleanUpOldNavigations();
487 // Arrange for the given WebContents to be deleted asap. If deleter is not
488 // NULL, deletes that as well.
489 void ScheduleDeleteOldWebContents(content::WebContents* tab,
490 OnCloseWebContentsDeleter* deleter);
492 // Adds to the history list.
493 void AddToHistory(PrerenderContents* contents);
495 // Returns a new Value representing the pages currently being prerendered. The
496 // caller is responsible for delete'ing the return value.
497 base::Value* GetActivePrerendersAsValue() const;
499 // Destroys all pending prerenders using FinalStatus. Also deletes them as
500 // well as any swapped out WebContents queued for destruction.
501 // Used both on destruction, and when clearing the browsing history.
502 void DestroyAllContents(FinalStatus final_status);
504 // Helper function to destroy a PrerenderContents with the specified
505 // final_status, while at the same time recording that for the MatchComplete
506 // case, that this prerender would have been used.
507 void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents,
508 FinalStatus final_status);
510 // Records the final status a prerender in the case that a PrerenderContents
511 // was never created, and also adds a PrerenderHistory entry.
512 // This is a helper function which will ultimately call
513 // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
514 void RecordFinalStatusWithoutCreatingPrerenderContents(
515 const GURL& url, Origin origin, uint8 experiment_id,
516 FinalStatus final_status) const;
519 void CookieChanged(ChromeCookieDetails* details);
520 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key,
521 bool cookies_exist);
522 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map);
524 // Swaps a prerender |prerender_data| for |url| into the tab, replacing
525 // |web_contents|. Returns the new WebContents that was swapped in, or NULL
526 // if a swap-in was not possible. If |should_replace_current_entry| is true,
527 // the current history entry in |web_contents| is replaced.
528 content::WebContents* SwapInternal(const GURL& url,
529 content::WebContents* web_contents,
530 PrerenderData* prerender_data,
531 bool should_replace_current_entry);
533 // The configuration.
534 Config config_;
536 // The profile that owns this PrerenderManager.
537 Profile* profile_;
539 // All running prerenders. Sorted by expiry time, in ascending order.
540 ScopedVector<PrerenderData> active_prerenders_;
542 // Prerenders awaiting deletion.
543 ScopedVector<PrerenderData> to_delete_prerenders_;
545 // List of recent navigations in this profile, sorted by ascending
546 // navigate_time_.
547 std::list<NavigationRecord> navigations_;
549 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
551 static PrerenderManagerMode mode_;
553 // A count of how many prerenders we do per session. Initialized to 0 then
554 // incremented and emitted to a histogram on each successful prerender.
555 static int prerenders_per_session_count_;
557 // RepeatingTimer to perform periodic cleanups of pending prerendered
558 // pages.
559 base::RepeatingTimer<PrerenderManager> repeating_timer_;
561 // Track time of last prerender to limit prerender spam.
562 base::TimeTicks last_prerender_start_time_;
564 std::list<content::WebContents*> old_web_contents_list_;
566 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
568 scoped_ptr<PrerenderHistory> prerender_history_;
570 scoped_ptr<PrerenderHistograms> histograms_;
572 scoped_ptr<PrerenderLocalPredictor> local_predictor_;
574 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_;
576 // Here, we keep the logged in predictor state, but potentially a superset
577 // of its actual (database-backed) state, since we do not incorporate
578 // browser data deletion. We do not use this for actual lookups, but only
579 // to query cookie data for domains we know there was a login before.
580 // This is required to avoid a large number of cookie lookups on bulk
581 // deletion of cookies.
582 scoped_ptr<LoggedInStateMap> logged_in_state_;
584 content::NotificationRegistrar notification_registrar_;
586 base::CancelableTaskTracker query_url_tracker_;
588 // The number of bytes transferred over the network for the profile this
589 // PrerenderManager is attached to.
590 int64 profile_network_bytes_;
592 // The value of profile_network_bytes_ that was last recorded.
593 int64 last_recorded_profile_network_bytes_;
595 // Set of process hosts being prerendered.
596 typedef std::set<content::RenderProcessHost*> PrerenderProcessSet;
597 PrerenderProcessSet prerender_process_hosts_;
599 DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
602 } // namespace prerender
604 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_