BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / prerender / prerender_manager.h
blob2ba76b43db5d61ce82ae230110a411f2b6277d89
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/threading/non_thread_safe.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
20 #include "chrome/browser/prerender/prerender_config.h"
21 #include "chrome/browser/prerender/prerender_contents.h"
22 #include "chrome/browser/prerender/prerender_final_status.h"
23 #include "chrome/browser/prerender/prerender_histograms.h"
24 #include "chrome/browser/prerender/prerender_origin.h"
25 #include "components/keyed_service/core/keyed_service.h"
26 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/render_process_host_observer.h"
29 #include "net/cookies/cookie_monster.h"
30 #include "url/gurl.h"
32 class Profile;
33 class InstantSearchPrerendererTest;
34 struct ChromeCookieDetails;
36 namespace base {
37 class DictionaryValue;
40 namespace chrome {
41 struct NavigateParams;
44 namespace content {
45 class WebContents;
48 namespace gfx {
49 class Size;
52 namespace prerender {
54 class PrerenderHandle;
55 class PrerenderHistory;
56 class PrerenderLocalPredictor;
58 // PrerenderManager is responsible for initiating and keeping prerendered
59 // views of web pages. All methods must be called on the UI thread unless
60 // indicated otherwise.
61 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
62 public base::NonThreadSafe,
63 public content::NotificationObserver,
64 public content::RenderProcessHostObserver,
65 public KeyedService,
66 public MediaCaptureDevicesDispatcher::Observer {
67 public:
68 // NOTE: New values need to be appended, since they are used in histograms.
69 enum PrerenderManagerMode {
70 PRERENDER_MODE_DISABLED = 0,
71 PRERENDER_MODE_ENABLED = 1,
72 PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2,
73 PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3,
74 // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4,
75 PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5,
76 PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6,
77 PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7,
78 PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP = 8,
79 PRERENDER_MODE_MAX
82 // One or more of these flags must be passed to ClearData() to specify just
83 // what data to clear. See function declaration for more information.
84 enum ClearFlags {
85 CLEAR_PRERENDER_CONTENTS = 0x1 << 0,
86 CLEAR_PRERENDER_HISTORY = 0x1 << 1,
87 CLEAR_MAX = 0x1 << 2
90 // Owned by a Profile object for the lifetime of the profile.
91 explicit PrerenderManager(Profile* profile);
93 ~PrerenderManager() override;
95 // From KeyedService:
96 void Shutdown() override;
98 // Entry points for adding prerenders.
100 // Adds a prerender for |url| if valid. |process_id| and |route_id| identify
101 // the RenderView that the prerender request came from. If |size| is empty, a
102 // default from the PrerenderConfig is used. Returns a caller-owned
103 // PrerenderHandle* if the URL was added, NULL if it was not. If the launching
104 // RenderView is itself prerendering, the prerender is added as a pending
105 // prerender.
106 PrerenderHandle* AddPrerenderFromLinkRelPrerender(
107 int process_id,
108 int route_id,
109 const GURL& url,
110 uint32 rel_types,
111 const content::Referrer& referrer,
112 const gfx::Size& size);
114 // Adds a prerender for |url| if valid. As the prerender request is coming
115 // from a source without a RenderFrameHost (i.e., the omnibox) we don't have a
116 // child or route id, or a referrer. This method uses sensible values for
117 // those. The |session_storage_namespace| matches the namespace of the active
118 // tab at the time the prerender is generated from the omnibox. Returns a
119 // caller-owned PrerenderHandle*, or NULL.
120 PrerenderHandle* AddPrerenderFromOmnibox(
121 const GURL& url,
122 content::SessionStorageNamespace* session_storage_namespace,
123 const gfx::Size& size);
125 PrerenderHandle* AddPrerenderFromExternalRequest(
126 const GURL& url,
127 const content::Referrer& referrer,
128 content::SessionStorageNamespace* session_storage_namespace,
129 const gfx::Size& size);
131 // Adds a prerender for Instant Search |url| if valid. The
132 // |session_storage_namespace| matches the namespace of the active tab at the
133 // time the prerender is generated. Returns a caller-owned PrerenderHandle* or
134 // NULL.
135 PrerenderHandle* AddPrerenderForInstant(
136 const GURL& url,
137 content::SessionStorageNamespace* session_storage_namespace,
138 const gfx::Size& size);
140 // Cancels all active prerenders.
141 void CancelAllPrerenders();
143 // If |url| matches a valid prerendered page and |params| are compatible, try
144 // to swap it and merge browsing histories. Returns |true| and updates
145 // |params->target_contents| if a prerendered page is swapped in, |false|
146 // otherwise.
147 bool MaybeUsePrerenderedPage(const GURL& url,
148 chrome::NavigateParams* params);
150 // Moves a PrerenderContents to the pending delete list from the list of
151 // active prerenders when prerendering should be cancelled.
152 virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
153 FinalStatus final_status);
155 // Records the page load time for a prerender that wasn't swapped in.
156 void RecordPageLoadTimeNotSwappedIn(Origin origin,
157 base::TimeDelta page_load_time,
158 const GURL& url);
160 // Records the perceived page load time for a page - effectively the time from
161 // when the user navigates to a page to when it finishes loading. The actual
162 // load may have started prior to navigation due to prerender hints.
163 // This must be called on the UI thread.
164 // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value
165 // outside that range indicating that it doesn't apply.
166 void RecordPerceivedPageLoadTime(
167 Origin origin,
168 NavigationType navigation_type,
169 base::TimeDelta perceived_page_load_time,
170 double fraction_plt_elapsed_at_swap_in,
171 const GURL& url);
173 static PrerenderManagerMode GetMode();
174 static void SetMode(PrerenderManagerMode mode);
175 static const char* GetModeString();
176 static bool IsPrerenderingPossible();
177 static bool ActuallyPrerendering();
178 static bool IsControlGroup();
179 static bool IsNoUseGroup();
181 // Query the list of current prerender pages to see if the given web contents
182 // is prerendering a page. The optional parameter |origin| is an output
183 // parameter which, if a prerender is found, is set to the Origin of the
184 // prerender |web_contents|.
185 bool IsWebContentsPrerendering(const content::WebContents* web_contents,
186 Origin* origin) const;
188 // Whether the PrerenderManager has an active prerender with the given url and
189 // SessionStorageNamespace associated with the given WebContens.
190 bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const;
192 // Returns the PrerenderContents object for the given web_contents, otherwise
193 // returns NULL. Note that the PrerenderContents may have been Destroy()ed,
194 // but not yet deleted.
195 PrerenderContents* GetPrerenderContents(
196 const content::WebContents* web_contents) const;
198 // Returns the PrerenderContents object for a given child_id, route_id pair,
199 // otherwise returns NULL. Note that the PrerenderContents may have been
200 // Destroy()ed, but not yet deleted.
201 virtual PrerenderContents* GetPrerenderContentsForRoute(
202 int child_id, int route_id) const;
204 // Returns a list of all WebContents being prerendered.
205 const std::vector<content::WebContents*> GetAllPrerenderingContents() const;
207 // Checks whether |url| has been recently navigated to.
208 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url);
210 // Returns true iff the method given is valid for prerendering.
211 static bool IsValidHttpMethod(const std::string& method);
213 // Returns true iff the scheme of the URL given is valid for prerendering.
214 static bool DoesURLHaveValidScheme(const GURL& url);
216 // Returns true iff the scheme of the subresource URL given is valid for
217 // prerendering.
218 static bool DoesSubresourceURLHaveValidScheme(const GURL& url);
220 // Returns a Value object containing the active pages being prerendered, and
221 // a history of pages which were prerendered. The caller is responsible for
222 // deleting the return value.
223 base::DictionaryValue* GetAsValue() const;
225 // Clears the data indicated by which bits of clear_flags are set.
227 // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are
228 // cancelled and then deleted, and any WebContents queued for destruction are
229 // destroyed as well.
231 // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is
232 // cleared, including any entries newly created by destroying them in
233 // response to the CLEAR_PRERENDER_CONTENTS flag.
235 // Intended to be used when clearing the cache or history.
236 void ClearData(int clear_flags);
238 // Record a final status of a prerendered page in a histogram.
239 // This variation allows specifying whether prerendering had been started
240 // (necessary to flag MatchComplete dummies).
241 void RecordFinalStatusWithMatchCompleteStatus(
242 Origin origin,
243 PrerenderContents::MatchCompleteStatus mc_status,
244 FinalStatus final_status) const;
246 // content::NotificationObserver
247 void Observe(int type,
248 const content::NotificationSource& source,
249 const content::NotificationDetails& details) override;
251 // MediaCaptureDevicesDispatcher::Observer
252 void OnCreatingAudioStream(int render_process_id,
253 int render_frame_id) override;
255 const Config& config() const { return config_; }
256 Config& mutable_config() { return config_; }
258 // Records that some visible tab navigated (or was redirected) to the
259 // provided URL.
260 void RecordNavigation(const GURL& url);
262 Profile* profile() const { return profile_; }
264 // Classes which will be tested in prerender unit browser tests should use
265 // these methods to get times for comparison, so that the test framework can
266 // mock advancing/retarding time.
267 virtual base::Time GetCurrentTime() const;
268 virtual base::TimeTicks GetCurrentTimeTicks() const;
270 // Notification that a prerender has completed and its bytes should be
271 // recorded.
272 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes);
274 // Returns whether prerendering is currently enabled for this manager.
275 bool IsEnabled() const;
277 // Add to the running tally of bytes transferred over the network for this
278 // profile if prerendering is currently enabled.
279 void AddProfileNetworkBytesIfEnabled(int64 bytes);
281 // Registers a new ProcessHost performing a prerender. Called by
282 // PrerenderContents.
283 void AddPrerenderProcessHost(content::RenderProcessHost* process_host);
285 // Returns whether or not |process_host| may be reused for new navigations
286 // from a prerendering perspective. Currently, if Prerender Cookie Stores are
287 // enabled, prerenders must be in their own processes that may not be shared.
288 bool MayReuseProcessHost(content::RenderProcessHost* process_host);
290 // content::RenderProcessHostObserver implementation.
291 void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
293 protected:
294 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> {
295 public:
296 struct OrderByExpiryTime;
298 PrerenderData(PrerenderManager* manager,
299 PrerenderContents* contents,
300 base::TimeTicks expiry_time);
302 ~PrerenderData();
304 // Turn this PrerenderData into a Match Complete replacement for itself,
305 // placing the current prerender contents into |to_delete_prerenders_|.
306 void MakeIntoMatchCompleteReplacement();
308 // A new PrerenderHandle has been created for this PrerenderData.
309 void OnHandleCreated(PrerenderHandle* prerender_handle);
311 // The launcher associated with a handle is navigating away from the context
312 // that launched this prerender. If the prerender is active, it may stay
313 // alive briefly though, in case we we going through a redirect chain that
314 // will eventually land at it.
315 void OnHandleNavigatedAway(PrerenderHandle* prerender_handle);
317 // The launcher associated with a handle has taken explicit action to cancel
318 // this prerender. We may well destroy the prerender in this case if no
319 // other handles continue to track it.
320 void OnHandleCanceled(PrerenderHandle* prerender_handle);
322 PrerenderContents* contents() { return contents_.get(); }
324 PrerenderContents* ReleaseContents();
326 int handle_count() const { return handle_count_; }
328 base::TimeTicks abandon_time() const { return abandon_time_; }
330 base::TimeTicks expiry_time() const { return expiry_time_; }
331 void set_expiry_time(base::TimeTicks expiry_time) {
332 expiry_time_ = expiry_time;
335 private:
336 PrerenderManager* manager_;
337 scoped_ptr<PrerenderContents> contents_;
339 // The number of distinct PrerenderHandles created for |this|, including
340 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not
341 // counting the ones that have called PrerenderData::OnHandleCanceled(). For
342 // pending prerenders, this will always be 1, since the PrerenderManager
343 // only merges handles of running prerenders.
344 int handle_count_;
346 // The time when OnHandleNavigatedAway was called.
347 base::TimeTicks abandon_time_;
349 // After this time, this prerender is no longer fresh, and should be
350 // removed.
351 base::TimeTicks expiry_time_;
353 DISALLOW_COPY_AND_ASSIGN(PrerenderData);
356 void SetPrerenderContentsFactory(
357 PrerenderContents::Factory* prerender_contents_factory);
359 // Called by a PrerenderData to signal that the launcher has navigated away
360 // from the context that launched the prerender. A user may have clicked
361 // a link in a page containing a <link rel=prerender> element, or the user
362 // might have committed an omnibox navigation. This is used to possibly
363 // shorten the TTL of the prerendered page.
364 void SourceNavigatedAway(PrerenderData* prerender_data);
366 private:
367 friend class ::InstantSearchPrerendererTest;
368 friend class PrerenderBrowserTest;
369 friend class PrerenderContents;
370 friend class PrerenderHandle;
371 friend class UnitTestPrerenderManager;
373 class OnCloseWebContentsDeleter;
374 struct NavigationRecord;
376 // Time interval before a new prerender is allowed.
377 static const int kMinTimeBetweenPrerendersMs = 500;
379 // Time window for which we record old navigations, in milliseconds.
380 static const int kNavigationRecordWindowMs = 5000;
382 void OnCancelPrerenderHandle(PrerenderData* prerender_data);
384 // Adds a prerender for |url| from |referrer|. The |origin| specifies how the
385 // prerender was added. If |size| is empty, then
386 // PrerenderContents::StartPrerendering will instead use a default from
387 // PrerenderConfig. Returns a PrerenderHandle*, owned by the caller, or NULL.
388 PrerenderHandle* AddPrerender(
389 Origin origin,
390 const GURL& url,
391 const content::Referrer& referrer,
392 const gfx::Size& size,
393 content::SessionStorageNamespace* session_storage_namespace);
395 void StartSchedulingPeriodicCleanups();
396 void StopSchedulingPeriodicCleanups();
398 void EvictOldestPrerendersIfNecessary();
400 // Deletes stale and cancelled prerendered PrerenderContents, as well as
401 // WebContents that have been replaced by prerendered WebContents.
402 // Also identifies and kills PrerenderContents that use too much
403 // resources.
404 void PeriodicCleanup();
406 // Posts a task to call PeriodicCleanup. Results in quicker destruction of
407 // objects. If |this| is deleted before the task is run, the task will
408 // automatically be cancelled.
409 void PostCleanupTask();
411 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const;
412 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const;
414 void DeleteOldEntries();
415 virtual PrerenderContents* CreatePrerenderContents(
416 const GURL& url,
417 const content::Referrer& referrer,
418 Origin origin);
420 // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
421 // after every mutation of active_prerenders_ that can possibly make it
422 // unsorted (e.g. an insert, or changing an expiry time).
423 void SortActivePrerenders();
425 // Finds the active PrerenderData object for a running prerender matching
426 // |url| and |session_storage_namespace|.
427 PrerenderData* FindPrerenderData(
428 const GURL& url,
429 const content::SessionStorageNamespace* session_storage_namespace);
431 // Given the |prerender_contents|, find the iterator in active_prerenders_
432 // correponding to the given prerender.
433 ScopedVector<PrerenderData>::iterator
434 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents);
436 bool DoesRateLimitAllowPrerender(Origin origin) const;
438 // Deletes old WebContents that have been replaced by prerendered ones. This
439 // is needed because they're replaced in a callback from the old WebContents,
440 // so cannot immediately be deleted.
441 void DeleteOldWebContents();
443 // Cleans up old NavigationRecord's.
444 void CleanUpOldNavigations();
446 // Arrange for the given WebContents to be deleted asap. If deleter is not
447 // NULL, deletes that as well.
448 void ScheduleDeleteOldWebContents(content::WebContents* tab,
449 OnCloseWebContentsDeleter* deleter);
451 // Adds to the history list.
452 void AddToHistory(PrerenderContents* contents);
454 // Returns a new Value representing the pages currently being prerendered. The
455 // caller is responsible for delete'ing the return value.
456 base::Value* GetActivePrerendersAsValue() const;
458 // Destroys all pending prerenders using FinalStatus. Also deletes them as
459 // well as any swapped out WebContents queued for destruction.
460 // Used both on destruction, and when clearing the browsing history.
461 void DestroyAllContents(FinalStatus final_status);
463 // Helper function to destroy a PrerenderContents with the specified
464 // final_status, while at the same time recording that for the MatchComplete
465 // case, that this prerender would have been used.
466 void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents,
467 FinalStatus final_status);
469 // Records the final status a prerender in the case that a PrerenderContents
470 // was never created, and also adds a PrerenderHistory entry.
471 // This is a helper function which will ultimately call
472 // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT.
473 void RecordFinalStatusWithoutCreatingPrerenderContents(
474 const GURL& url, Origin origin, FinalStatus final_status) const;
477 // Swaps a prerender |prerender_data| for |url| into the tab, replacing
478 // |web_contents|. Returns the new WebContents that was swapped in, or NULL
479 // if a swap-in was not possible. If |should_replace_current_entry| is true,
480 // the current history entry in |web_contents| is replaced.
481 content::WebContents* SwapInternal(const GURL& url,
482 content::WebContents* web_contents,
483 PrerenderData* prerender_data,
484 bool should_replace_current_entry);
486 // The configuration.
487 Config config_;
489 // The profile that owns this PrerenderManager.
490 Profile* profile_;
492 // All running prerenders. Sorted by expiry time, in ascending order.
493 ScopedVector<PrerenderData> active_prerenders_;
495 // Prerenders awaiting deletion.
496 ScopedVector<PrerenderData> to_delete_prerenders_;
498 // List of recent navigations in this profile, sorted by ascending
499 // navigate_time_.
500 std::list<NavigationRecord> navigations_;
502 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_;
504 static PrerenderManagerMode mode_;
506 // A count of how many prerenders we do per session. Initialized to 0 then
507 // incremented and emitted to a histogram on each successful prerender.
508 static int prerenders_per_session_count_;
510 // RepeatingTimer to perform periodic cleanups of pending prerendered
511 // pages.
512 base::RepeatingTimer<PrerenderManager> repeating_timer_;
514 // Track time of last prerender to limit prerender spam.
515 base::TimeTicks last_prerender_start_time_;
517 std::list<content::WebContents*> old_web_contents_list_;
519 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_;
521 scoped_ptr<PrerenderHistory> prerender_history_;
523 scoped_ptr<PrerenderHistograms> histograms_;
525 content::NotificationRegistrar notification_registrar_;
527 // The number of bytes transferred over the network for the profile this
528 // PrerenderManager is attached to.
529 int64 profile_network_bytes_;
531 // The value of profile_network_bytes_ that was last recorded.
532 int64 last_recorded_profile_network_bytes_;
534 // Set of process hosts being prerendered.
535 typedef std::set<content::RenderProcessHost*> PrerenderProcessSet;
536 PrerenderProcessSet prerender_process_hosts_;
538 DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
541 } // namespace prerender
543 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_