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