Fix broken path in extensions/common/PRESUBMIT.py
[chromium-blink-merge.git] / content / browser / frame_host / navigation_entry_impl.cc
blob5a93b0fe1c69f8dacd84519344c2dd47529ea369
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 #include "content/browser/frame_host/navigation_entry_impl.h"
7 #include "base/metrics/histogram.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/common/navigation_params.h"
11 #include "content/public/common/content_constants.h"
12 #include "content/public/common/url_constants.h"
13 #include "net/base/net_util.h"
14 #include "ui/gfx/text_elider.h"
16 // Use this to get a new unique ID for a NavigationEntry during construction.
17 // The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
18 static int GetUniqueIDInConstructor() {
19 static int unique_id_counter = 0;
20 return ++unique_id_counter;
23 namespace content {
25 int NavigationEntryImpl::kInvalidBindings = -1;
27 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry)
28 : frame_entry(frame_entry) {
31 NavigationEntryImpl::TreeNode::~TreeNode() {
34 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const {
35 // Clone the tree using a copy of the FrameNavigationEntry, without sharing.
36 NavigationEntryImpl::TreeNode* copy =
37 new NavigationEntryImpl::TreeNode(frame_entry->Clone());
39 // TODO(creis): Clone children once we add them.
40 return copy;
43 NavigationEntry* NavigationEntry::Create() {
44 return new NavigationEntryImpl();
47 NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry(
48 NavigationEntry* entry) {
49 return static_cast<NavigationEntryImpl*>(entry);
52 NavigationEntryImpl::NavigationEntryImpl()
53 : NavigationEntryImpl(nullptr, -1, GURL(), Referrer(), base::string16(),
54 ui::PAGE_TRANSITION_LINK, false) {
57 NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance,
58 int page_id,
59 const GURL& url,
60 const Referrer& referrer,
61 const base::string16& title,
62 ui::PageTransition transition_type,
63 bool is_renderer_initiated)
64 : frame_tree_(
65 new TreeNode(new FrameNavigationEntry(instance, url, referrer))),
66 unique_id_(GetUniqueIDInConstructor()),
67 bindings_(kInvalidBindings),
68 page_type_(PAGE_TYPE_NORMAL),
69 update_virtual_url_with_url_(false),
70 title_(title),
71 page_id_(page_id),
72 transition_type_(transition_type),
73 has_post_data_(false),
74 post_id_(-1),
75 restore_type_(RESTORE_NONE),
76 is_overriding_user_agent_(false),
77 http_status_code_(0),
78 is_renderer_initiated_(is_renderer_initiated),
79 should_replace_entry_(false),
80 should_clear_history_list_(false),
81 can_load_local_resources_(false),
82 frame_tree_node_id_(-1) {
85 NavigationEntryImpl::~NavigationEntryImpl() {
88 int NavigationEntryImpl::GetUniqueID() const {
89 return unique_id_;
92 PageType NavigationEntryImpl::GetPageType() const {
93 return page_type_;
96 void NavigationEntryImpl::SetURL(const GURL& url) {
97 frame_tree_->frame_entry->set_url(url);
98 cached_display_title_.clear();
101 const GURL& NavigationEntryImpl::GetURL() const {
102 return frame_tree_->frame_entry->url();
105 void NavigationEntryImpl::SetBaseURLForDataURL(const GURL& url) {
106 base_url_for_data_url_ = url;
109 const GURL& NavigationEntryImpl::GetBaseURLForDataURL() const {
110 return base_url_for_data_url_;
113 void NavigationEntryImpl::SetReferrer(const Referrer& referrer) {
114 frame_tree_->frame_entry->set_referrer(referrer);
117 const Referrer& NavigationEntryImpl::GetReferrer() const {
118 return frame_tree_->frame_entry->referrer();
121 void NavigationEntryImpl::SetVirtualURL(const GURL& url) {
122 virtual_url_ = (url == GetURL()) ? GURL() : url;
123 cached_display_title_.clear();
126 const GURL& NavigationEntryImpl::GetVirtualURL() const {
127 return virtual_url_.is_empty() ? GetURL() : virtual_url_;
130 void NavigationEntryImpl::SetTitle(const base::string16& title) {
131 title_ = title;
132 cached_display_title_.clear();
135 const base::string16& NavigationEntryImpl::GetTitle() const {
136 return title_;
139 void NavigationEntryImpl::SetPageState(const PageState& state) {
140 page_state_ = state;
143 const PageState& NavigationEntryImpl::GetPageState() const {
144 return page_state_;
147 void NavigationEntryImpl::SetPageID(int page_id) {
148 page_id_ = page_id;
151 int32 NavigationEntryImpl::GetPageID() const {
152 return page_id_;
155 void NavigationEntryImpl::set_site_instance(SiteInstanceImpl* site_instance) {
156 // TODO(creis): Update all callers and remove this method.
157 frame_tree_->frame_entry->set_site_instance(site_instance);
160 void NavigationEntryImpl::set_source_site_instance(
161 SiteInstanceImpl* source_site_instance) {
162 source_site_instance_ = source_site_instance;
165 void NavigationEntryImpl::SetBindings(int bindings) {
166 // Ensure this is set to a valid value, and that it stays the same once set.
167 CHECK_NE(bindings, kInvalidBindings);
168 CHECK(bindings_ == kInvalidBindings || bindings_ == bindings);
169 bindings_ = bindings;
172 const base::string16& NavigationEntryImpl::GetTitleForDisplay(
173 const std::string& languages) const {
174 // Most pages have real titles. Don't even bother caching anything if this is
175 // the case.
176 if (!title_.empty())
177 return title_;
179 // More complicated cases will use the URLs as the title. This result we will
180 // cache since it's more complicated to compute.
181 if (!cached_display_title_.empty())
182 return cached_display_title_;
184 // Use the virtual URL first if any, and fall back on using the real URL.
185 base::string16 title;
186 if (!virtual_url_.is_empty()) {
187 title = net::FormatUrl(virtual_url_, languages);
188 } else if (!GetURL().is_empty()) {
189 title = net::FormatUrl(GetURL(), languages);
192 // For file:// URLs use the filename as the title, not the full path.
193 if (GetURL().SchemeIsFile()) {
194 base::string16::size_type slashpos = title.rfind('/');
195 if (slashpos != base::string16::npos)
196 title = title.substr(slashpos + 1);
199 gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
200 return cached_display_title_;
203 bool NavigationEntryImpl::IsViewSourceMode() const {
204 return virtual_url_.SchemeIs(kViewSourceScheme);
207 void NavigationEntryImpl::SetTransitionType(
208 ui::PageTransition transition_type) {
209 transition_type_ = transition_type;
212 ui::PageTransition NavigationEntryImpl::GetTransitionType() const {
213 return transition_type_;
216 const GURL& NavigationEntryImpl::GetUserTypedURL() const {
217 return user_typed_url_;
220 void NavigationEntryImpl::SetHasPostData(bool has_post_data) {
221 has_post_data_ = has_post_data;
224 bool NavigationEntryImpl::GetHasPostData() const {
225 return has_post_data_;
228 void NavigationEntryImpl::SetPostID(int64 post_id) {
229 post_id_ = post_id;
232 int64 NavigationEntryImpl::GetPostID() const {
233 return post_id_;
236 void NavigationEntryImpl::SetBrowserInitiatedPostData(
237 const base::RefCountedMemory* data) {
238 browser_initiated_post_data_ = data;
241 const base::RefCountedMemory*
242 NavigationEntryImpl::GetBrowserInitiatedPostData() const {
243 return browser_initiated_post_data_.get();
247 const FaviconStatus& NavigationEntryImpl::GetFavicon() const {
248 return favicon_;
251 FaviconStatus& NavigationEntryImpl::GetFavicon() {
252 return favicon_;
255 const SSLStatus& NavigationEntryImpl::GetSSL() const {
256 return ssl_;
259 SSLStatus& NavigationEntryImpl::GetSSL() {
260 return ssl_;
263 void NavigationEntryImpl::SetOriginalRequestURL(const GURL& original_url) {
264 original_request_url_ = original_url;
267 const GURL& NavigationEntryImpl::GetOriginalRequestURL() const {
268 return original_request_url_;
271 void NavigationEntryImpl::SetIsOverridingUserAgent(bool override) {
272 is_overriding_user_agent_ = override;
275 bool NavigationEntryImpl::GetIsOverridingUserAgent() const {
276 return is_overriding_user_agent_;
279 void NavigationEntryImpl::SetTimestamp(base::Time timestamp) {
280 timestamp_ = timestamp;
283 base::Time NavigationEntryImpl::GetTimestamp() const {
284 return timestamp_;
287 void NavigationEntryImpl::SetHttpStatusCode(int http_status_code) {
288 http_status_code_ = http_status_code;
291 int NavigationEntryImpl::GetHttpStatusCode() const {
292 return http_status_code_;
295 void NavigationEntryImpl::SetRedirectChain(
296 const std::vector<GURL>& redirect_chain) {
297 redirect_chain_ = redirect_chain;
300 const std::vector<GURL>& NavigationEntryImpl::GetRedirectChain() const {
301 return redirect_chain_;
304 bool NavigationEntryImpl::IsRestored() const {
305 return restore_type_ != RESTORE_NONE;
308 void NavigationEntryImpl::SetCanLoadLocalResources(bool allow) {
309 can_load_local_resources_ = allow;
312 bool NavigationEntryImpl::GetCanLoadLocalResources() const {
313 return can_load_local_resources_;
316 void NavigationEntryImpl::SetExtraData(const std::string& key,
317 const base::string16& data) {
318 extra_data_[key] = data;
321 bool NavigationEntryImpl::GetExtraData(const std::string& key,
322 base::string16* data) const {
323 std::map<std::string, base::string16>::const_iterator iter =
324 extra_data_.find(key);
325 if (iter == extra_data_.end())
326 return false;
327 *data = iter->second;
328 return true;
331 void NavigationEntryImpl::ClearExtraData(const std::string& key) {
332 extra_data_.erase(key);
335 NavigationEntryImpl* NavigationEntryImpl::Clone() const {
336 NavigationEntryImpl* copy = new NavigationEntryImpl();
338 // TODO(creis): Only share the same FrameNavigationEntries if cloning within
339 // the same tab.
340 copy->frame_tree_.reset(frame_tree_->Clone());
342 // Copy all state over, unless cleared in ResetForCommit.
343 copy->unique_id_ = unique_id_;
344 copy->bindings_ = bindings_;
345 copy->page_type_ = page_type_;
346 copy->virtual_url_ = virtual_url_;
347 copy->update_virtual_url_with_url_ = update_virtual_url_with_url_;
348 copy->title_ = title_;
349 copy->favicon_ = favicon_;
350 copy->page_state_ = page_state_;
351 copy->page_id_ = page_id_;
352 copy->ssl_ = ssl_;
353 copy->transition_type_ = transition_type_;
354 copy->user_typed_url_ = user_typed_url_;
355 copy->has_post_data_ = has_post_data_;
356 copy->post_id_ = post_id_;
357 copy->restore_type_ = restore_type_;
358 copy->original_request_url_ = original_request_url_;
359 copy->is_overriding_user_agent_ = is_overriding_user_agent_;
360 copy->timestamp_ = timestamp_;
361 copy->http_status_code_ = http_status_code_;
362 // ResetForCommit: browser_initiated_post_data_
363 copy->screenshot_ = screenshot_;
364 copy->extra_headers_ = extra_headers_;
365 // ResetForCommit: source_site_instance_
366 copy->base_url_for_data_url_ = base_url_for_data_url_;
367 // ResetForCommit: is_renderer_initiated_
368 copy->cached_display_title_ = cached_display_title_;
369 // ResetForCommit: transferred_global_request_id_
370 // ResetForCommit: should_replace_entry_
371 copy->redirect_chain_ = redirect_chain_;
372 // ResetForCommit: should_clear_history_list_
373 // ResetForCommit: frame_tree_node_id_
374 // ResetForCommit: intent_received_timestamp_
375 copy->extra_data_ = extra_data_;
377 return copy;
380 CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
381 FrameMsg_Navigate_Type::Value navigation_type) const {
382 FrameMsg_UILoadMetricsReportType::Value report_type =
383 FrameMsg_UILoadMetricsReportType::NO_REPORT;
384 base::TimeTicks ui_timestamp = base::TimeTicks();
385 #if defined(OS_ANDROID)
386 if (!intent_received_timestamp().is_null())
387 report_type = FrameMsg_UILoadMetricsReportType::REPORT_INTENT;
388 ui_timestamp = intent_received_timestamp();
389 #endif
391 return CommonNavigationParams(
392 GetURL(), GetReferrer(), GetTransitionType(), navigation_type,
393 !IsViewSourceMode(), ui_timestamp, report_type, GetBaseURLForDataURL(),
394 GetHistoryURLForDataURL());
397 StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
398 const {
399 std::vector<unsigned char> browser_initiated_post_data;
400 if (GetBrowserInitiatedPostData()) {
401 browser_initiated_post_data.assign(
402 GetBrowserInitiatedPostData()->front(),
403 GetBrowserInitiatedPostData()->front() +
404 GetBrowserInitiatedPostData()->size());
407 return StartNavigationParams(
408 GetHasPostData(), extra_headers(), browser_initiated_post_data,
409 should_replace_entry(), transferred_global_request_id().child_id,
410 transferred_global_request_id().request_id);
413 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
414 base::TimeTicks navigation_start,
415 bool intended_as_new_entry,
416 int pending_history_list_offset,
417 int current_history_list_offset,
418 int current_history_list_length) const {
419 // Set the redirect chain to the navigation's redirects, unless returning to a
420 // completed navigation (whose previous redirects don't apply).
421 std::vector<GURL> redirects;
422 if (ui::PageTransitionIsNewNavigation(GetTransitionType())) {
423 redirects = GetRedirectChain();
426 int pending_offset_to_send = pending_history_list_offset;
427 int current_offset_to_send = current_history_list_offset;
428 int current_length_to_send = current_history_list_length;
429 if (should_clear_history_list()) {
430 // Set the history list related parameters to the same values a
431 // NavigationController would return before its first navigation. This will
432 // fully clear the RenderView's view of the session history.
433 pending_offset_to_send = -1;
434 current_offset_to_send = -1;
435 current_length_to_send = 0;
437 return RequestNavigationParams(
438 GetIsOverridingUserAgent(), navigation_start, redirects,
439 GetCanLoadLocalResources(), base::Time::Now(), GetPageState(),
440 GetPageID(), GetUniqueID(), intended_as_new_entry, pending_offset_to_send,
441 current_offset_to_send, current_length_to_send,
442 should_clear_history_list());
445 void NavigationEntryImpl::ResetForCommit() {
446 // Any state that only matters when a navigation entry is pending should be
447 // cleared here.
448 // TODO(creis): This state should be moved to NavigationRequest once
449 // PlzNavigate is enabled.
450 SetBrowserInitiatedPostData(nullptr);
451 set_source_site_instance(nullptr);
452 set_is_renderer_initiated(false);
453 set_transferred_global_request_id(GlobalRequestID());
454 set_should_replace_entry(false);
456 set_should_clear_history_list(false);
457 set_frame_tree_node_id(-1);
459 #if defined(OS_ANDROID)
460 // Reset the time stamp so that the metrics are not reported if this entry is
461 // loaded again in the future.
462 set_intent_received_timestamp(base::TimeTicks());
463 #endif
466 void NavigationEntryImpl::AddOrUpdateFrameEntry(int frame_tree_node_id,
467 SiteInstanceImpl* site_instance,
468 const GURL& url,
469 const Referrer& referrer) {
470 // TODO(creis): Walk tree to find the node to update.
471 // TODO(creis): Only create a new entry if one doesn't exist yet.
472 FrameNavigationEntry* frame_entry =
473 new FrameNavigationEntry(site_instance, url, referrer);
474 root_node()->children.push_back(
475 new NavigationEntryImpl::TreeNode(frame_entry));
478 void NavigationEntryImpl::SetScreenshotPNGData(
479 scoped_refptr<base::RefCountedBytes> png_data) {
480 screenshot_ = png_data;
481 if (screenshot_.get())
482 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size());
485 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const {
486 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL();
489 } // namespace content