navigation_entry_impl.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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#include "content/browser/frame_host/navigation_entry_impl.h"
6
7#include "base/metrics/histogram.h"
8#include "base/strings/string_util.h"
9#include "base/strings/utf_string_conversions.h"
10#include "content/public/common/content_constants.h"
11#include "content/public/common/url_constants.h"
12#include "net/base/net_util.h"
13#include "ui/gfx/text_elider.h"
14
15// Use this to get a new unique ID for a NavigationEntry during construction.
16// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
17static int GetUniqueIDInConstructor() {
18  static int unique_id_counter = 0;
19  return ++unique_id_counter;
20}
21
22namespace content {
23
24int NavigationEntryImpl::kInvalidBindings = -1;
25
26NavigationEntry* NavigationEntry::Create() {
27  return new NavigationEntryImpl();
28}
29
30NavigationEntry* NavigationEntry::Create(const NavigationEntry& copy) {
31  return new NavigationEntryImpl(static_cast<const NavigationEntryImpl&>(copy));
32}
33
34NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry(
35    NavigationEntry* entry) {
36  return static_cast<NavigationEntryImpl*>(entry);
37}
38
39NavigationEntryImpl::NavigationEntryImpl()
40    : unique_id_(GetUniqueIDInConstructor()),
41      site_instance_(NULL),
42      bindings_(kInvalidBindings),
43      page_type_(PAGE_TYPE_NORMAL),
44      update_virtual_url_with_url_(false),
45      page_id_(-1),
46      transition_type_(PAGE_TRANSITION_LINK),
47      has_post_data_(false),
48      post_id_(-1),
49      restore_type_(RESTORE_NONE),
50      is_overriding_user_agent_(false),
51      http_status_code_(0),
52      is_renderer_initiated_(false),
53      should_replace_entry_(false),
54      should_clear_history_list_(false),
55      can_load_local_resources_(false),
56      xss_detected_(false),
57      frame_tree_node_id_(-1) {
58}
59
60NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance,
61                                         int page_id,
62                                         const GURL& url,
63                                         const Referrer& referrer,
64                                         const base::string16& title,
65                                         PageTransition transition_type,
66                                         bool is_renderer_initiated)
67    : unique_id_(GetUniqueIDInConstructor()),
68      site_instance_(instance),
69      bindings_(kInvalidBindings),
70      page_type_(PAGE_TYPE_NORMAL),
71      url_(url),
72      referrer_(referrer),
73      update_virtual_url_with_url_(false),
74      title_(title),
75      page_id_(page_id),
76      transition_type_(transition_type),
77      has_post_data_(false),
78      post_id_(-1),
79      restore_type_(RESTORE_NONE),
80      is_overriding_user_agent_(false),
81      http_status_code_(0),
82      is_renderer_initiated_(is_renderer_initiated),
83      should_replace_entry_(false),
84      should_clear_history_list_(false),
85      can_load_local_resources_(false),
86      xss_detected_(false),
87      frame_tree_node_id_(-1) {
88}
89
90NavigationEntryImpl::~NavigationEntryImpl() {
91}
92
93int NavigationEntryImpl::GetUniqueID() const {
94  return unique_id_;
95}
96
97PageType NavigationEntryImpl::GetPageType() const {
98  return page_type_;
99}
100
101void NavigationEntryImpl::SetURL(const GURL& url) {
102  url_ = url;
103  cached_display_title_.clear();
104}
105
106const GURL& NavigationEntryImpl::GetURL() const {
107  return url_;
108}
109
110void NavigationEntryImpl::SetBaseURLForDataURL(const GURL& url) {
111  base_url_for_data_url_ = url;
112}
113
114const GURL& NavigationEntryImpl::GetBaseURLForDataURL() const {
115  return base_url_for_data_url_;
116}
117
118void NavigationEntryImpl::SetReferrer(const Referrer& referrer) {
119  referrer_ = referrer;
120}
121
122const Referrer& NavigationEntryImpl::GetReferrer() const {
123  return referrer_;
124}
125
126void NavigationEntryImpl::SetVirtualURL(const GURL& url) {
127  virtual_url_ = (url == url_) ? GURL() : url;
128  cached_display_title_.clear();
129}
130
131const GURL& NavigationEntryImpl::GetVirtualURL() const {
132  return virtual_url_.is_empty() ? url_ : virtual_url_;
133}
134
135void NavigationEntryImpl::SetTitle(const base::string16& title) {
136  title_ = title;
137  cached_display_title_.clear();
138}
139
140const base::string16& NavigationEntryImpl::GetTitle() const {
141  return title_;
142}
143
144void NavigationEntryImpl::SetPageState(const PageState& state) {
145  page_state_ = state;
146}
147
148const PageState& NavigationEntryImpl::GetPageState() const {
149  return page_state_;
150}
151
152void NavigationEntryImpl::SetPageID(int page_id) {
153  page_id_ = page_id;
154}
155
156int32 NavigationEntryImpl::GetPageID() const {
157  return page_id_;
158}
159
160void NavigationEntryImpl::set_site_instance(SiteInstanceImpl* site_instance) {
161  site_instance_ = site_instance;
162}
163
164void NavigationEntryImpl::SetBindings(int bindings) {
165  // Ensure this is set to a valid value, and that it stays the same once set.
166  CHECK_NE(bindings, kInvalidBindings);
167  CHECK(bindings_ == kInvalidBindings || bindings_ == bindings);
168  bindings_ = bindings;
169}
170
171const base::string16& NavigationEntryImpl::GetTitleForDisplay(
172    const std::string& languages) const {
173  // Most pages have real titles. Don't even bother caching anything if this is
174  // the case.
175  if (!title_.empty())
176    return title_;
177
178  // More complicated cases will use the URLs as the title. This result we will
179  // cache since it's more complicated to compute.
180  if (!cached_display_title_.empty())
181    return cached_display_title_;
182
183  // Use the virtual URL first if any, and fall back on using the real URL.
184  base::string16 title;
185  if (!virtual_url_.is_empty()) {
186    title = net::FormatUrl(virtual_url_, languages);
187  } else if (!url_.is_empty()) {
188    title = net::FormatUrl(url_, languages);
189  }
190
191  // For file:// URLs use the filename as the title, not the full path.
192  if (url_.SchemeIsFile()) {
193    base::string16::size_type slashpos = title.rfind('/');
194    if (slashpos != base::string16::npos)
195      title = title.substr(slashpos + 1);
196  }
197
198  gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
199  return cached_display_title_;
200}
201
202bool NavigationEntryImpl::IsViewSourceMode() const {
203  return virtual_url_.SchemeIs(kViewSourceScheme);
204}
205
206void NavigationEntryImpl::SetTransitionType(
207    PageTransition transition_type) {
208  transition_type_ = transition_type;
209}
210
211PageTransition NavigationEntryImpl::GetTransitionType() const {
212  return transition_type_;
213}
214
215const GURL& NavigationEntryImpl::GetUserTypedURL() const {
216  return user_typed_url_;
217}
218
219void NavigationEntryImpl::SetHasPostData(bool has_post_data) {
220  has_post_data_ = has_post_data;
221}
222
223bool NavigationEntryImpl::GetHasPostData() const {
224  return has_post_data_;
225}
226
227void NavigationEntryImpl::SetPostID(int64 post_id) {
228  post_id_ = post_id;
229}
230
231int64 NavigationEntryImpl::GetPostID() const {
232  return post_id_;
233}
234
235void NavigationEntryImpl::SetBrowserInitiatedPostData(
236    const base::RefCountedMemory* data) {
237  browser_initiated_post_data_ = data;
238}
239
240const base::RefCountedMemory*
241NavigationEntryImpl::GetBrowserInitiatedPostData() const {
242  return browser_initiated_post_data_.get();
243}
244
245
246const FaviconStatus& NavigationEntryImpl::GetFavicon() const {
247  return favicon_;
248}
249
250FaviconStatus& NavigationEntryImpl::GetFavicon() {
251  return favicon_;
252}
253
254const SSLStatus& NavigationEntryImpl::GetSSL() const {
255  return ssl_;
256}
257
258SSLStatus& NavigationEntryImpl::GetSSL() {
259  return ssl_;
260}
261
262void NavigationEntryImpl::SetOriginalRequestURL(const GURL& original_url) {
263  original_request_url_ = original_url;
264}
265
266const GURL& NavigationEntryImpl::GetOriginalRequestURL() const {
267  return original_request_url_;
268}
269
270void NavigationEntryImpl::SetIsOverridingUserAgent(bool override) {
271  is_overriding_user_agent_ = override;
272}
273
274bool NavigationEntryImpl::GetIsOverridingUserAgent() const {
275  return is_overriding_user_agent_;
276}
277
278void NavigationEntryImpl::SetTimestamp(base::Time timestamp) {
279  timestamp_ = timestamp;
280}
281
282base::Time NavigationEntryImpl::GetTimestamp() const {
283  return timestamp_;
284}
285
286void NavigationEntryImpl::SetHttpStatusCode(int http_status_code) {
287  http_status_code_ = http_status_code;
288}
289
290int NavigationEntryImpl::GetHttpStatusCode() const {
291  return http_status_code_;
292}
293
294void NavigationEntryImpl::SetRedirectChain(
295    const std::vector<GURL>& redirect_chain) {
296  redirect_chain_ = redirect_chain;
297}
298
299const std::vector<GURL>& NavigationEntryImpl::GetRedirectChain() const {
300  return redirect_chain_;
301}
302
303bool NavigationEntryImpl::IsRestored() const {
304  return restore_type_ != RESTORE_NONE;
305}
306
307void NavigationEntryImpl::SetCanLoadLocalResources(bool allow) {
308  can_load_local_resources_ = allow;
309}
310
311bool NavigationEntryImpl::GetCanLoadLocalResources() const {
312  return can_load_local_resources_;
313}
314
315bool NavigationEntryImpl::GetXssDetected() const {
316  return xss_detected_;
317}
318
319void NavigationEntryImpl::SetFrameToNavigate(const std::string& frame_name) {
320  frame_to_navigate_ = frame_name;
321}
322
323const std::string& NavigationEntryImpl::GetFrameToNavigate() const {
324  return frame_to_navigate_;
325}
326
327void NavigationEntryImpl::SetExtraData(const std::string& key,
328                                       const base::string16& data) {
329  extra_data_[key] = data;
330}
331
332bool NavigationEntryImpl::GetExtraData(const std::string& key,
333                                       base::string16* data) const {
334  std::map<std::string, base::string16>::const_iterator iter =
335      extra_data_.find(key);
336  if (iter == extra_data_.end())
337    return false;
338  *data = iter->second;
339  return true;
340}
341
342void NavigationEntryImpl::ClearExtraData(const std::string& key) {
343  extra_data_.erase(key);
344}
345
346void NavigationEntryImpl::ResetForCommit() {
347  // Any state that only matters when a navigation entry is pending should be
348  // cleared here.
349  SetBrowserInitiatedPostData(NULL);
350  set_is_renderer_initiated(false);
351  set_transferred_global_request_id(GlobalRequestID());
352  set_should_replace_entry(false);
353
354  set_should_clear_history_list(false);
355  set_frame_tree_node_id(-1);
356}
357
358void NavigationEntryImpl::SetScreenshotPNGData(
359    scoped_refptr<base::RefCountedBytes> png_data) {
360  screenshot_ = png_data;
361  if (screenshot_.get())
362    UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size());
363}
364
365}  // namespace content
366