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.
5 #ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_IMPL_H_
6 #define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_IMPL_H_
8 #include "base/basictypes.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/time/time.h"
12 #include "content/browser/frame_host/frame_navigation_entry.h"
13 #include "content/browser/frame_host/frame_tree_node.h"
14 #include "content/browser/site_instance_impl.h"
15 #include "content/common/frame_message_enums.h"
16 #include "content/public/browser/favicon_status.h"
17 #include "content/public/browser/global_request_id.h"
18 #include "content/public/browser/navigation_entry.h"
19 #include "content/public/common/page_state.h"
20 #include "content/public/common/ssl_status.h"
23 struct CommonNavigationParams
;
24 struct RequestNavigationParams
;
25 struct StartNavigationParams
;
27 class CONTENT_EXPORT NavigationEntryImpl
28 : public NON_EXPORTED_BASE(NavigationEntry
) {
30 // Represents a tree of FrameNavigationEntries that make up this joint session
31 // history item. The tree currently only tracks the main frame by default,
32 // and is populated with subframe nodes in --site-per-process mode.
34 TreeNode(FrameNavigationEntry
* frame_entry
);
37 // Returns whether this TreeNode corresponds to |frame_tree_node|.
38 bool MatchesFrame(FrameTreeNode
* frame_tree_node
) const;
40 // Recursively makes a deep copy of TreeNode with copies of each of the
41 // FrameNavigationEntries in the subtree. Replaces the TreeNode
42 // corresponding to |frame_tree_node| (and all of its children) with a new
43 // TreeNode for |frame_navigation_entry|. Pass nullptr for both parameters
44 // to make a complete clone.
45 // TODO(creis): For --site-per-process, share FrameNavigationEntries between
46 // NavigationEntries of the same tab.
47 scoped_ptr
<TreeNode
> CloneAndReplace(
48 FrameTreeNode
* frame_tree_node
,
49 FrameNavigationEntry
* frame_navigation_entry
) const;
51 // Ref counted pointer that keeps the FrameNavigationEntry alive as long as
52 // it is needed by this node's NavigationEntry.
53 scoped_refptr
<FrameNavigationEntry
> frame_entry
;
55 // List of child TreeNodes, which will be deleted when this node is.
56 ScopedVector
<TreeNode
> children
;
59 static NavigationEntryImpl
* FromNavigationEntry(NavigationEntry
* entry
);
60 static const NavigationEntryImpl
* FromNavigationEntry(
61 const NavigationEntry
* entry
);
62 static scoped_ptr
<NavigationEntryImpl
> FromNavigationEntry(
63 scoped_ptr
<NavigationEntry
> entry
);
65 // The value of bindings() before it is set during commit.
66 static int kInvalidBindings
;
68 NavigationEntryImpl();
69 NavigationEntryImpl(SiteInstanceImpl
* instance
,
72 const Referrer
& referrer
,
73 const base::string16
& title
,
74 ui::PageTransition transition_type
,
75 bool is_renderer_initiated
);
76 ~NavigationEntryImpl() override
;
78 // NavigationEntry implementation:
79 int GetUniqueID() const override
;
80 PageType
GetPageType() const override
;
81 void SetURL(const GURL
& url
) override
;
82 const GURL
& GetURL() const override
;
83 void SetBaseURLForDataURL(const GURL
& url
) override
;
84 const GURL
& GetBaseURLForDataURL() const override
;
85 void SetReferrer(const Referrer
& referrer
) override
;
86 const Referrer
& GetReferrer() const override
;
87 void SetVirtualURL(const GURL
& url
) override
;
88 const GURL
& GetVirtualURL() const override
;
89 void SetTitle(const base::string16
& title
) override
;
90 const base::string16
& GetTitle() const override
;
91 void SetPageState(const PageState
& state
) override
;
92 const PageState
& GetPageState() const override
;
93 void SetPageID(int page_id
) override
;
94 int32
GetPageID() const override
;
95 const base::string16
& GetTitleForDisplay(
96 const std::string
& languages
) const override
;
97 bool IsViewSourceMode() const override
;
98 void SetTransitionType(ui::PageTransition transition_type
) override
;
99 ui::PageTransition
GetTransitionType() const override
;
100 const GURL
& GetUserTypedURL() const override
;
101 void SetHasPostData(bool has_post_data
) override
;
102 bool GetHasPostData() const override
;
103 void SetPostID(int64 post_id
) override
;
104 int64
GetPostID() const override
;
105 void SetBrowserInitiatedPostData(const base::RefCountedMemory
* data
) override
;
106 const base::RefCountedMemory
* GetBrowserInitiatedPostData() const override
;
107 const FaviconStatus
& GetFavicon() const override
;
108 FaviconStatus
& GetFavicon() override
;
109 const SSLStatus
& GetSSL() const override
;
110 SSLStatus
& GetSSL() override
;
111 void SetOriginalRequestURL(const GURL
& original_url
) override
;
112 const GURL
& GetOriginalRequestURL() const override
;
113 void SetIsOverridingUserAgent(bool override
) override
;
114 bool GetIsOverridingUserAgent() const override
;
115 void SetTimestamp(base::Time timestamp
) override
;
116 base::Time
GetTimestamp() const override
;
117 void SetCanLoadLocalResources(bool allow
) override
;
118 bool GetCanLoadLocalResources() const override
;
119 void SetExtraData(const std::string
& key
,
120 const base::string16
& data
) override
;
121 bool GetExtraData(const std::string
& key
,
122 base::string16
* data
) const override
;
123 void ClearExtraData(const std::string
& key
) override
;
124 void SetHttpStatusCode(int http_status_code
) override
;
125 int GetHttpStatusCode() const override
;
126 void SetRedirectChain(const std::vector
<GURL
>& redirects
) override
;
127 const std::vector
<GURL
>& GetRedirectChain() const override
;
128 bool IsRestored() const override
;
130 // Creates a copy of this NavigationEntryImpl that can be modified
131 // independently from the original. Does not copy any value that would be
132 // cleared in ResetForCommit.
133 scoped_ptr
<NavigationEntryImpl
> Clone() const;
135 // Like |Clone|, but replaces the FrameNavigationEntry corresponding to
136 // |frame_tree_node| (and all its children) with |frame_entry|.
137 // TODO(creis): Once we start sharing FrameNavigationEntries between
138 // NavigationEntryImpls, we will need to support two versions of Clone: one
139 // that shares the existing FrameNavigationEntries (for use within the same
140 // tab) and one that draws them from a different pool (for use in a new tab).
141 scoped_ptr
<NavigationEntryImpl
> CloneAndReplace(
142 FrameTreeNode
* frame_tree_node
, FrameNavigationEntry
* frame_entry
) const;
144 // Helper functions to construct NavigationParameters for a navigation to this
146 CommonNavigationParams
ConstructCommonNavigationParams(
147 const GURL
& dest_url
,
148 const Referrer
& dest_referrer
,
149 const FrameNavigationEntry
& frame_entry
,
150 FrameMsg_Navigate_Type::Value navigation_type
) const;
151 StartNavigationParams
ConstructStartNavigationParams() const;
152 RequestNavigationParams
ConstructRequestNavigationParams(
153 const FrameNavigationEntry
& frame_entry
,
154 base::TimeTicks navigation_start
,
155 bool is_same_document_history_load
,
156 bool has_committed_real_load
,
157 bool intended_as_new_entry
,
158 int pending_offset_to_send
,
159 int current_offset_to_send
,
160 int current_length_to_send
) const;
162 // Once a navigation entry is committed, we should no longer track several
163 // pieces of non-persisted state, as documented on the members below.
164 void ResetForCommit();
166 // Exposes the tree of FrameNavigationEntries that make up this joint session
168 // In default Chrome, this tree only has a root node with an unshared
169 // FrameNavigationEntry. Subframes are only added to the tree if the
170 // --site-per-process flag is passed.
171 TreeNode
* root_node() const {
172 return frame_tree_
.get();
175 // Finds the TreeNode associated with |frame_tree_node_id| to add or update
176 // its FrameNavigationEntry. A new FrameNavigationEntry is added if none
177 // exists, or else the existing one (which might be shared with other
178 // NavigationEntries) is updated with the given parameters.
179 // Does nothing if there is no entry already and |url| is about:blank, since
180 // that does not count as a real commit.
181 void AddOrUpdateFrameEntry(FrameTreeNode
* frame_tree_node
,
182 int64 item_sequence_number
,
183 int64 document_sequence_number
,
184 SiteInstanceImpl
* site_instance
,
186 const Referrer
& referrer
,
187 const PageState
& page_state
);
189 // Returns the FrameNavigationEntry corresponding to |frame_tree_node|, if
190 // there is one in this NavigationEntry.
191 FrameNavigationEntry
* GetFrameEntry(FrameTreeNode
* frame_tree_node
) const;
193 void set_unique_id(int unique_id
) {
194 unique_id_
= unique_id
;
197 // The SiteInstance represents which pages must share processes. This is a
198 // reference counted pointer to a shared SiteInstance.
200 // Note that the SiteInstance should usually not be changed after it is set,
201 // but this may happen if the NavigationEntry was cloned and needs to use a
202 // different SiteInstance.
203 void set_site_instance(SiteInstanceImpl
* site_instance
);
204 SiteInstanceImpl
* site_instance() const {
205 return frame_tree_
->frame_entry
->site_instance();
208 // The |source_site_instance| is used to identify the SiteInstance of the
209 // frame that initiated the navigation.
210 void set_source_site_instance(SiteInstanceImpl
* source_site_instance
);
211 SiteInstanceImpl
* source_site_instance() const {
212 return source_site_instance_
.get();
215 // Remember the set of bindings granted to this NavigationEntry at the time
216 // of commit, to ensure that we do not grant it additional bindings if we
217 // navigate back to it in the future. This can only be changed once.
218 void SetBindings(int bindings
);
219 int bindings() const {
223 void set_page_type(PageType page_type
) {
224 page_type_
= page_type
;
227 bool has_virtual_url() const {
228 return !virtual_url_
.is_empty();
231 bool update_virtual_url_with_url() const {
232 return update_virtual_url_with_url_
;
234 void set_update_virtual_url_with_url(bool update
) {
235 update_virtual_url_with_url_
= update
;
238 // Extra headers (separated by \n) to send during the request.
239 void set_extra_headers(const std::string
& extra_headers
) {
240 extra_headers_
= extra_headers
;
242 const std::string
& extra_headers() const {
243 return extra_headers_
;
246 // Whether this (pending) navigation is renderer-initiated. Resets to false
247 // for all types of navigations after commit.
248 void set_is_renderer_initiated(bool is_renderer_initiated
) {
249 is_renderer_initiated_
= is_renderer_initiated
;
251 bool is_renderer_initiated() const {
252 return is_renderer_initiated_
;
255 void set_user_typed_url(const GURL
& user_typed_url
) {
256 user_typed_url_
= user_typed_url
;
259 // Enumerations of the possible restore types.
261 // Restore from the previous session.
262 RESTORE_LAST_SESSION_EXITED_CLEANLY
,
263 RESTORE_LAST_SESSION_CRASHED
,
265 // The entry has been restored from the current session. This is used when
266 // the user issues 'reopen closed tab'.
267 RESTORE_CURRENT_SESSION
,
269 // The entry was not restored.
273 // The RestoreType for this entry. This is set if the entry was retored. This
274 // is set to RESTORE_NONE once the entry is loaded.
275 void set_restore_type(RestoreType type
) {
276 restore_type_
= type
;
278 RestoreType
restore_type() const {
279 return restore_type_
;
282 void set_transferred_global_request_id(
283 const GlobalRequestID
& transferred_global_request_id
) {
284 transferred_global_request_id_
= transferred_global_request_id
;
287 GlobalRequestID
transferred_global_request_id() const {
288 return transferred_global_request_id_
;
291 // Whether this (pending) navigation needs to replace current entry.
292 // Resets to false after commit.
293 bool should_replace_entry() const {
294 return should_replace_entry_
;
297 void set_should_replace_entry(bool should_replace_entry
) {
298 should_replace_entry_
= should_replace_entry
;
301 void SetScreenshotPNGData(scoped_refptr
<base::RefCountedBytes
> png_data
);
302 const scoped_refptr
<base::RefCountedBytes
> screenshot() const {
306 // Whether this (pending) navigation should clear the session history. Resets
307 // to false after commit.
308 bool should_clear_history_list() const {
309 return should_clear_history_list_
;
311 void set_should_clear_history_list(bool should_clear_history_list
) {
312 should_clear_history_list_
= should_clear_history_list
;
315 // Indicates which FrameTreeNode to navigate. Currently only used if the
316 // --site-per-process flag is passed.
317 int frame_tree_node_id() const {
318 return frame_tree_node_id_
;
320 void set_frame_tree_node_id(int frame_tree_node_id
) {
321 frame_tree_node_id_
= frame_tree_node_id
;
324 // Returns the history URL for a data URL to use in Blink.
325 GURL
GetHistoryURLForDataURL() const;
327 #if defined(OS_ANDROID)
328 base::TimeTicks
intent_received_timestamp() const {
329 return intent_received_timestamp_
;
332 void set_intent_received_timestamp(
333 const base::TimeTicks intent_received_timestamp
) {
334 intent_received_timestamp_
= intent_received_timestamp
;
337 bool has_user_gesture() const {
338 return has_user_gesture_
;
341 void set_has_user_gesture (bool has_user_gesture
) {
342 has_user_gesture_
= has_user_gesture
;
347 // Finds the TreeNode associated with |frame_tree_node|, if any.
348 NavigationEntryImpl::TreeNode
* FindFrameEntry(
349 FrameTreeNode
* frame_tree_node
) const;
351 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
352 // Session/Tab restore save portions of this class so that it can be recreated
353 // later. If you add a new field that needs to be persisted you'll have to
354 // update SessionService/TabRestoreService and Android WebView
355 // state_serializer.cc appropriately.
356 // For all new fields, update |Clone| and possibly |ResetForCommit|.
357 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
359 // Tree of FrameNavigationEntries, one for each frame on the page.
360 // TODO(creis): Once FrameNavigationEntries can be shared across multiple
361 // NavigationEntries, we will need to update Session/Tab restore. For now,
362 // each NavigationEntry's tree has its own unshared FrameNavigationEntries.
363 scoped_ptr
<TreeNode
> frame_tree_
;
365 // See the accessors above for descriptions.
367 // TODO(creis): Persist bindings_. http://crbug.com/173672.
371 bool update_virtual_url_with_url_
;
372 base::string16 title_
;
373 FaviconStatus favicon_
;
376 ui::PageTransition transition_type_
;
377 GURL user_typed_url_
;
380 RestoreType restore_type_
;
381 GURL original_request_url_
;
382 bool is_overriding_user_agent_
;
383 base::Time timestamp_
;
384 int http_status_code_
;
386 // This member is not persisted with session restore because it is transient.
387 // If the post request succeeds, this field is cleared since the same
388 // information is stored in |content_state_| above. It is also only shallow
389 // copied with compiler provided copy constructor.
390 // Cleared in |ResetForCommit|.
391 scoped_refptr
<const base::RefCountedMemory
> browser_initiated_post_data_
;
393 // This is also a transient member (i.e. is not persisted with session
394 // restore). The screenshot of a page is taken when navigating away from the
395 // page. This screenshot is displayed during an overscroll-navigation
396 // gesture. |screenshot_| will be NULL when the screenshot is not available
397 // (e.g. after a session restore, or if taking the screenshot of a page
398 // failed). The UI is responsible for dealing with missing screenshots
399 // appropriately (e.g. display a placeholder image instead).
400 scoped_refptr
<base::RefCountedBytes
> screenshot_
;
402 // This member is not persisted with session restore.
403 std::string extra_headers_
;
405 // This member is cleared in |ResetForCommit| and not persisted.
406 scoped_refptr
<SiteInstanceImpl
> source_site_instance_
;
408 // Used for specifying base URL for pages loaded via data URLs. Only used and
409 // persisted by Android WebView.
410 GURL base_url_for_data_url_
;
412 // Whether the entry, while loading, was created for a renderer-initiated
413 // navigation. This dictates whether the URL should be displayed before the
414 // navigation commits. It is cleared in |ResetForCommit| and not persisted.
415 bool is_renderer_initiated_
;
417 // This is a cached version of the result of GetTitleForDisplay. It prevents
418 // us from having to do URL formatting on the URL every time the title is
419 // displayed. When the URL, virtual URL, or title is set, this should be
420 // cleared to force a refresh.
421 mutable base::string16 cached_display_title_
;
423 // In case a navigation is transferred to a new RVH but the request has
424 // been generated in the renderer already, this identifies the old request so
425 // that it can be resumed. The old request is stored until the
426 // ResourceDispatcher receives the navigation from the renderer which
427 // carries this |transferred_global_request_id_| annotation. Once the request
428 // is transferred to the new process, this is cleared and the request
429 // continues as normal.
430 // Cleared in |ResetForCommit|.
431 GlobalRequestID transferred_global_request_id_
;
433 // This is set to true when this entry is being reloaded and due to changes in
434 // the state of the URL, it has to be reloaded in a different site instance.
435 // In such case, we must treat it as an existing navigation in the new site
436 // instance, instead of a new navigation. This value should not be persisted
437 // and is cleared in |ResetForCommit|.
439 // We also use this flag for cross-process redirect navigations, so that the
440 // browser will replace the current navigation entry (which is the page
441 // doing the redirect).
442 bool should_replace_entry_
;
444 // This is used when transferring a pending entry from one process to another.
445 // We also send this data through session sync for offline analysis.
446 // It is preserved after commit but should not be persisted.
447 std::vector
<GURL
> redirect_chain_
;
449 // This is set to true when this entry's navigation should clear the session
450 // history both on the renderer and browser side. The browser side history
451 // won't be cleared until the renderer has committed this navigation. This
452 // entry is not persisted by the session restore system, as it is always
453 // cleared in |ResetForCommit|.
454 bool should_clear_history_list_
;
456 // Set when this entry should be able to access local file:// resources. This
457 // value is not needed after the entry commits and is not persisted.
458 bool can_load_local_resources_
;
460 // If not -1, this indicates which FrameTreeNode to navigate. This field is
461 // not persisted because it is experimental and only used when the
462 // --site-per-process flag is passed. It is cleared in |ResetForCommit|
463 // because we only use it while the navigation is pending.
464 // TODO(creis): Move this to FrameNavigationEntry.
465 int frame_tree_node_id_
;
467 #if defined(OS_ANDROID)
468 // The time at which Chrome received the Android Intent that triggered this
469 // URL load operation. Reset at commit and not persisted.
470 base::TimeTicks intent_received_timestamp_
;
472 // Whether the URL load carries a user gesture.
473 bool has_user_gesture_
;
476 // Used to store extra data to support browser features. This member is not
477 // persisted, unless specific data is taken out/put back in at save/restore
478 // time (see TabNavigation for an example of this).
479 std::map
<std::string
, base::string16
> extra_data_
;
481 DISALLOW_COPY_AND_ASSIGN(NavigationEntryImpl
);
484 } // namespace content
486 #endif // CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_IMPL_H_