| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sessions/session_types.h" | 5 #include "components/sessions/serialized_navigation_entry.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/pickle.h" | 7 #include "base/pickle.h" |
| 9 #include "base/stl_util.h" | |
| 10 #include "base/string_util.h" | |
| 11 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/search/search.h" | |
| 13 #include "chrome/browser/sessions/session_command.h" | |
| 14 #include "chrome/browser/ui/browser.h" | |
| 15 #include "content/public/browser/favicon_status.h" | 9 #include "content/public/browser/favicon_status.h" |
| 16 #include "content/public/browser/navigation_controller.h" | 10 #include "content/public/browser/navigation_controller.h" |
| 17 #include "content/public/browser/navigation_entry.h" | 11 #include "content/public/browser/navigation_entry.h" |
| 18 #include "sync/util/time.h" | 12 #include "sync/util/time.h" |
| 19 #include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h
" | 13 #include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h
" |
| 20 #include "webkit/glue/glue_serialize.h" | 14 #include "webkit/glue/glue_serialize.h" |
| 21 | 15 |
| 22 using content::NavigationEntry; | 16 using content::NavigationEntry; |
| 23 | 17 |
| 24 // TabNavigation -------------------------------------------------------------- | 18 namespace sessions { |
| 25 | 19 |
| 26 TabNavigation::TabNavigation() | 20 const char kSearchTermsKey[] = "search_terms"; |
| 21 |
| 22 SerializedNavigationEntry::SerializedNavigationEntry() |
| 27 : index_(-1), | 23 : index_(-1), |
| 28 unique_id_(0), | 24 unique_id_(0), |
| 29 transition_type_(content::PAGE_TRANSITION_TYPED), | 25 transition_type_(content::PAGE_TRANSITION_TYPED), |
| 30 has_post_data_(false), | 26 has_post_data_(false), |
| 31 post_id_(-1), | 27 post_id_(-1), |
| 32 is_overriding_user_agent_(false) {} | 28 is_overriding_user_agent_(false) {} |
| 33 | 29 |
| 34 TabNavigation::~TabNavigation() {} | 30 SerializedNavigationEntry::~SerializedNavigationEntry() {} |
| 35 | 31 |
| 36 // static | 32 // static |
| 37 TabNavigation TabNavigation::FromNavigationEntry( | 33 SerializedNavigationEntry SerializedNavigationEntry::FromNavigationEntry( |
| 38 int index, | 34 int index, |
| 39 const NavigationEntry& entry) { | 35 const NavigationEntry& entry) { |
| 40 TabNavigation navigation; | 36 SerializedNavigationEntry navigation; |
| 41 navigation.index_ = index; | 37 navigation.index_ = index; |
| 42 navigation.unique_id_ = entry.GetUniqueID(); | 38 navigation.unique_id_ = entry.GetUniqueID(); |
| 43 navigation.referrer_ = entry.GetReferrer(); | 39 navigation.referrer_ = entry.GetReferrer(); |
| 44 navigation.virtual_url_ = entry.GetVirtualURL(); | 40 navigation.virtual_url_ = entry.GetVirtualURL(); |
| 45 navigation.title_ = entry.GetTitle(); | 41 navigation.title_ = entry.GetTitle(); |
| 46 navigation.content_state_ = entry.GetContentState(); | 42 navigation.content_state_ = entry.GetContentState(); |
| 47 navigation.transition_type_ = entry.GetTransitionType(); | 43 navigation.transition_type_ = entry.GetTransitionType(); |
| 48 navigation.has_post_data_ = entry.GetHasPostData(); | 44 navigation.has_post_data_ = entry.GetHasPostData(); |
| 49 navigation.post_id_ = entry.GetPostID(); | 45 navigation.post_id_ = entry.GetPostID(); |
| 50 navigation.original_request_url_ = entry.GetOriginalRequestURL(); | 46 navigation.original_request_url_ = entry.GetOriginalRequestURL(); |
| 51 navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); | 47 navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); |
| 52 navigation.timestamp_ = entry.GetTimestamp(); | 48 navigation.timestamp_ = entry.GetTimestamp(); |
| 53 // If you want to navigate a named frame in Chrome, you will first need to | 49 // If you want to navigate a named frame in Chrome, you will first need to |
| 54 // add support for persisting it. It is currently only used for layout tests. | 50 // add support for persisting it. It is currently only used for layout tests. |
| 55 CHECK(entry.GetFrameToNavigate().empty()); | 51 CHECK(entry.GetFrameToNavigate().empty()); |
| 56 navigation.search_terms_ = | 52 entry.GetExtraData(kSearchTermsKey, &navigation.search_terms_); |
| 57 chrome::GetSearchTermsFromNavigationEntry(&entry); | |
| 58 if (entry.GetFavicon().valid) | 53 if (entry.GetFavicon().valid) |
| 59 navigation.favicon_url_ = entry.GetFavicon().url; | 54 navigation.favicon_url_ = entry.GetFavicon().url; |
| 60 | 55 |
| 61 return navigation; | 56 return navigation; |
| 62 } | 57 } |
| 63 | 58 |
| 64 TabNavigation TabNavigation::FromSyncData( | 59 SerializedNavigationEntry SerializedNavigationEntry::FromSyncData( |
| 65 int index, | 60 int index, |
| 66 const sync_pb::TabNavigation& sync_data) { | 61 const sync_pb::TabNavigation& sync_data) { |
| 67 TabNavigation navigation; | 62 SerializedNavigationEntry navigation; |
| 68 navigation.index_ = index; | 63 navigation.index_ = index; |
| 69 navigation.unique_id_ = sync_data.unique_id(); | 64 navigation.unique_id_ = sync_data.unique_id(); |
| 70 navigation.referrer_ = | 65 navigation.referrer_ = |
| 71 content::Referrer(GURL(sync_data.referrer()), | 66 content::Referrer(GURL(sync_data.referrer()), |
| 72 WebKit::WebReferrerPolicyDefault); | 67 WebKit::WebReferrerPolicyDefault); |
| 73 navigation.virtual_url_ = GURL(sync_data.virtual_url()); | 68 navigation.virtual_url_ = GURL(sync_data.virtual_url()); |
| 74 navigation.title_ = UTF8ToUTF16(sync_data.title()); | 69 navigation.title_ = UTF8ToUTF16(sync_data.title()); |
| 75 navigation.content_state_ = sync_data.state(); | 70 navigation.content_state_ = sync_data.state(); |
| 76 | 71 |
| 77 uint32 transition = 0; | 72 uint32 transition = 0; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 navigation.timestamp_ = base::Time(); | 139 navigation.timestamp_ = base::Time(); |
| 145 navigation.search_terms_ = UTF8ToUTF16(sync_data.search_terms()); | 140 navigation.search_terms_ = UTF8ToUTF16(sync_data.search_terms()); |
| 146 if (sync_data.has_favicon_url()) | 141 if (sync_data.has_favicon_url()) |
| 147 navigation.favicon_url_ = GURL(sync_data.favicon_url()); | 142 navigation.favicon_url_ = GURL(sync_data.favicon_url()); |
| 148 | 143 |
| 149 return navigation; | 144 return navigation; |
| 150 } | 145 } |
| 151 | 146 |
| 152 namespace { | 147 namespace { |
| 153 | 148 |
| 154 // Helper used by TabNavigation::WriteToPickle(). It writes |str| to | 149 // Helper used by SerializedNavigationEntry::WriteToPickle(). It writes |str| to |
| 155 // |pickle|, if and only if |str| fits within (|max_bytes| - | 150 // |pickle|, if and only if |str| fits within (|max_bytes| - |
| 156 // |*bytes_written|). |bytes_written| is incremented to reflect the | 151 // |*bytes_written|). |bytes_written| is incremented to reflect the |
| 157 // data written. | 152 // data written. |
| 158 // | 153 // |
| 159 // TODO(akalin): Unify this with the same function in | 154 // TODO(akalin): Unify this with the same function in |
| 160 // base_session_service.cc. | 155 // base_session_service.cc. |
| 161 void WriteStringToPickle(Pickle* pickle, | 156 void WriteStringToPickle(Pickle* pickle, |
| 162 int* bytes_written, | 157 int* bytes_written, |
| 163 int max_bytes, | 158 int max_bytes, |
| 164 const std::string& str) { | 159 const std::string& str) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 // | 204 // |
| 210 // Added on later: | 205 // Added on later: |
| 211 // | 206 // |
| 212 // type_mask (has_post_data_) | 207 // type_mask (has_post_data_) |
| 213 // referrer_ | 208 // referrer_ |
| 214 // original_request_url_ | 209 // original_request_url_ |
| 215 // is_overriding_user_agent_ | 210 // is_overriding_user_agent_ |
| 216 // timestamp_ | 211 // timestamp_ |
| 217 // search_terms_ | 212 // search_terms_ |
| 218 | 213 |
| 219 void TabNavigation::WriteToPickle(Pickle* pickle) const { | 214 void SerializedNavigationEntry::WriteToPickle(int max_size, |
| 215 Pickle* pickle) const { |
| 220 pickle->WriteInt(index_); | 216 pickle->WriteInt(index_); |
| 221 | 217 |
| 222 // We only allow navigations up to 63k (which should be completely | |
| 223 // reasonable). On the off chance we get one that is too big, try to | |
| 224 // keep the url. | |
| 225 | |
| 226 // Bound the string data (which is variable length) to | |
| 227 // |max_state_size bytes| bytes. | |
| 228 static const size_t max_state_size = | |
| 229 std::numeric_limits<SessionCommand::size_type>::max() - 1024; | |
| 230 int bytes_written = 0; | 218 int bytes_written = 0; |
| 231 | 219 |
| 232 WriteStringToPickle(pickle, &bytes_written, max_state_size, | 220 WriteStringToPickle(pickle, &bytes_written, max_size, |
| 233 virtual_url_.spec()); | 221 virtual_url_.spec()); |
| 234 | 222 |
| 235 WriteString16ToPickle(pickle, &bytes_written, max_state_size, title_); | 223 WriteString16ToPickle(pickle, &bytes_written, max_size, title_); |
| 236 | 224 |
| 237 std::string content_state = content_state_; | 225 std::string content_state = content_state_; |
| 238 if (has_post_data_) { | 226 if (has_post_data_) { |
| 239 content_state = | 227 content_state = |
| 240 webkit_glue::RemovePasswordDataFromHistoryState(content_state); | 228 webkit_glue::RemovePasswordDataFromHistoryState(content_state); |
| 241 } | 229 } |
| 242 WriteStringToPickle(pickle, &bytes_written, max_state_size, content_state); | 230 WriteStringToPickle(pickle, &bytes_written, max_size, content_state); |
| 243 | 231 |
| 244 pickle->WriteInt(transition_type_); | 232 pickle->WriteInt(transition_type_); |
| 245 | 233 |
| 246 const int type_mask = has_post_data_ ? HAS_POST_DATA : 0; | 234 const int type_mask = has_post_data_ ? HAS_POST_DATA : 0; |
| 247 pickle->WriteInt(type_mask); | 235 pickle->WriteInt(type_mask); |
| 248 | 236 |
| 249 WriteStringToPickle( | 237 WriteStringToPickle( |
| 250 pickle, &bytes_written, max_state_size, | 238 pickle, &bytes_written, max_size, |
| 251 referrer_.url.is_valid() ? referrer_.url.spec() : std::string()); | 239 referrer_.url.is_valid() ? referrer_.url.spec() : std::string()); |
| 252 | 240 |
| 253 pickle->WriteInt(referrer_.policy); | 241 pickle->WriteInt(referrer_.policy); |
| 254 | 242 |
| 255 // Save info required to override the user agent. | 243 // Save info required to override the user agent. |
| 256 WriteStringToPickle( | 244 WriteStringToPickle( |
| 257 pickle, &bytes_written, max_state_size, | 245 pickle, &bytes_written, max_size, |
| 258 original_request_url_.is_valid() ? | 246 original_request_url_.is_valid() ? |
| 259 original_request_url_.spec() : std::string()); | 247 original_request_url_.spec() : std::string()); |
| 260 pickle->WriteBool(is_overriding_user_agent_); | 248 pickle->WriteBool(is_overriding_user_agent_); |
| 261 pickle->WriteInt64(timestamp_.ToInternalValue()); | 249 pickle->WriteInt64(timestamp_.ToInternalValue()); |
| 262 | 250 |
| 263 WriteString16ToPickle(pickle, &bytes_written, max_state_size, search_terms_); | 251 WriteString16ToPickle(pickle, &bytes_written, max_size, search_terms_); |
| 264 } | 252 } |
| 265 | 253 |
| 266 bool TabNavigation::ReadFromPickle(PickleIterator* iterator) { | 254 bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) { |
| 267 *this = TabNavigation(); | 255 *this = SerializedNavigationEntry(); |
| 268 std::string virtual_url_spec; | 256 std::string virtual_url_spec; |
| 269 int transition_type_int = 0; | 257 int transition_type_int = 0; |
| 270 if (!iterator->ReadInt(&index_) || | 258 if (!iterator->ReadInt(&index_) || |
| 271 !iterator->ReadString(&virtual_url_spec) || | 259 !iterator->ReadString(&virtual_url_spec) || |
| 272 !iterator->ReadString16(&title_) || | 260 !iterator->ReadString16(&title_) || |
| 273 !iterator->ReadString(&content_state_) || | 261 !iterator->ReadString(&content_state_) || |
| 274 !iterator->ReadInt(&transition_type_int)) | 262 !iterator->ReadInt(&transition_type_int)) |
| 275 return false; | 263 return false; |
| 276 virtual_url_ = GURL(virtual_url_spec); | 264 virtual_url_ = GURL(virtual_url_spec); |
| 277 transition_type_ = static_cast<content::PageTransition>(transition_type_int); | 265 transition_type_ = static_cast<content::PageTransition>(transition_type_int); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 } | 304 } |
| 317 | 305 |
| 318 // If the search terms field can't be found, leave it empty. | 306 // If the search terms field can't be found, leave it empty. |
| 319 if (!iterator->ReadString16(&search_terms_)) | 307 if (!iterator->ReadString16(&search_terms_)) |
| 320 search_terms_.clear(); | 308 search_terms_.clear(); |
| 321 } | 309 } |
| 322 | 310 |
| 323 return true; | 311 return true; |
| 324 } | 312 } |
| 325 | 313 |
| 326 scoped_ptr<NavigationEntry> TabNavigation::ToNavigationEntry( | 314 scoped_ptr<NavigationEntry> SerializedNavigationEntry::ToNavigationEntry( |
| 327 int page_id, | 315 int page_id, |
| 328 content::BrowserContext* browser_context) const { | 316 content::BrowserContext* browser_context) const { |
| 329 scoped_ptr<NavigationEntry> entry( | 317 scoped_ptr<NavigationEntry> entry( |
| 330 content::NavigationController::CreateNavigationEntry( | 318 content::NavigationController::CreateNavigationEntry( |
| 331 virtual_url_, | 319 virtual_url_, |
| 332 referrer_, | 320 referrer_, |
| 333 // Use a transition type of reload so that we don't incorrectly | 321 // Use a transition type of reload so that we don't incorrectly |
| 334 // increase the typed count. | 322 // increase the typed count. |
| 335 content::PAGE_TRANSITION_RELOAD, | 323 content::PAGE_TRANSITION_RELOAD, |
| 336 false, | 324 false, |
| 337 // The extra headers are not sync'ed across sessions. | 325 // The extra headers are not sync'ed across sessions. |
| 338 std::string(), | 326 std::string(), |
| 339 browser_context)); | 327 browser_context)); |
| 340 | 328 |
| 341 entry->SetTitle(title_); | 329 entry->SetTitle(title_); |
| 342 entry->SetContentState(content_state_); | 330 entry->SetContentState(content_state_); |
| 343 entry->SetPageID(page_id); | 331 entry->SetPageID(page_id); |
| 344 entry->SetHasPostData(has_post_data_); | 332 entry->SetHasPostData(has_post_data_); |
| 345 entry->SetPostID(post_id_); | 333 entry->SetPostID(post_id_); |
| 346 entry->SetOriginalRequestURL(original_request_url_); | 334 entry->SetOriginalRequestURL(original_request_url_); |
| 347 entry->SetIsOverridingUserAgent(is_overriding_user_agent_); | 335 entry->SetIsOverridingUserAgent(is_overriding_user_agent_); |
| 348 entry->SetTimestamp(timestamp_); | 336 entry->SetTimestamp(timestamp_); |
| 349 entry->SetExtraData(chrome::kInstantExtendedSearchTermsKey, search_terms_); | 337 entry->SetExtraData(kSearchTermsKey, search_terms_); |
| 350 | 338 |
| 351 return entry.Pass(); | 339 return entry.Pass(); |
| 352 } | 340 } |
| 353 | 341 |
| 354 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? | 342 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? |
| 355 // See http://crbug.com/67068. | 343 // See http://crbug.com/67068. |
| 356 sync_pb::TabNavigation TabNavigation::ToSyncData() const { | 344 sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const { |
| 357 sync_pb::TabNavigation sync_data; | 345 sync_pb::TabNavigation sync_data; |
| 358 sync_data.set_virtual_url(virtual_url_.spec()); | 346 sync_data.set_virtual_url(virtual_url_.spec()); |
| 359 // FIXME(zea): Support referrer policy? | 347 // FIXME(zea): Support referrer policy? |
| 360 sync_data.set_referrer(referrer_.url.spec()); | 348 sync_data.set_referrer(referrer_.url.spec()); |
| 361 sync_data.set_title(UTF16ToUTF8(title_)); | 349 sync_data.set_title(UTF16ToUTF8(title_)); |
| 362 | 350 |
| 363 // Page transition core. | 351 // Page transition core. |
| 364 COMPILE_ASSERT(content::PAGE_TRANSITION_LAST_CORE == | 352 COMPILE_ASSERT(content::PAGE_TRANSITION_LAST_CORE == |
| 365 content::PAGE_TRANSITION_KEYWORD_GENERATED, | 353 content::PAGE_TRANSITION_KEYWORD_GENERATED, |
| 366 PageTransitionCoreBounds); | 354 PageTransitionCoreBounds); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 | 429 |
| 442 sync_data.set_search_terms(UTF16ToUTF8(search_terms_)); | 430 sync_data.set_search_terms(UTF16ToUTF8(search_terms_)); |
| 443 | 431 |
| 444 if (favicon_url_.is_valid()) | 432 if (favicon_url_.is_valid()) |
| 445 sync_data.set_favicon_url(favicon_url_.spec()); | 433 sync_data.set_favicon_url(favicon_url_.spec()); |
| 446 | 434 |
| 447 return sync_data; | 435 return sync_data; |
| 448 } | 436 } |
| 449 | 437 |
| 450 // static | 438 // static |
| 451 std::vector<NavigationEntry*> | 439 std::vector<NavigationEntry*> SerializedNavigationEntry::ToNavigationEntries( |
| 452 TabNavigation::CreateNavigationEntriesFromTabNavigations( | 440 const std::vector<SerializedNavigationEntry>& navigations, |
| 453 const std::vector<TabNavigation>& navigations, | |
| 454 content::BrowserContext* browser_context) { | 441 content::BrowserContext* browser_context) { |
| 455 int page_id = 0; | 442 int page_id = 0; |
| 456 std::vector<NavigationEntry*> entries; | 443 std::vector<NavigationEntry*> entries; |
| 457 for (std::vector<TabNavigation>::const_iterator it = navigations.begin(); | 444 for (std::vector<SerializedNavigationEntry>::const_iterator |
| 458 it != navigations.end(); ++it) { | 445 it = navigations.begin(); it != navigations.end(); ++it) { |
| 459 entries.push_back( | 446 entries.push_back( |
| 460 it->ToNavigationEntry(page_id, browser_context).release()); | 447 it->ToNavigationEntry(page_id, browser_context).release()); |
| 461 ++page_id; | 448 ++page_id; |
| 462 } | 449 } |
| 463 return entries; | 450 return entries; |
| 464 } | 451 } |
| 465 | 452 |
| 466 // SessionTab ----------------------------------------------------------------- | 453 } // namespace sessions |
| 467 | |
| 468 SessionTab::SessionTab() | |
| 469 : tab_visual_index(-1), | |
| 470 current_navigation_index(-1), | |
| 471 pinned(false) { | |
| 472 } | |
| 473 | |
| 474 SessionTab::~SessionTab() { | |
| 475 } | |
| 476 | |
| 477 void SessionTab::SetFromSyncData(const sync_pb::SessionTab& sync_data, | |
| 478 base::Time timestamp) { | |
| 479 window_id.set_id(sync_data.window_id()); | |
| 480 tab_id.set_id(sync_data.tab_id()); | |
| 481 tab_visual_index = sync_data.tab_visual_index(); | |
| 482 current_navigation_index = sync_data.current_navigation_index(); | |
| 483 pinned = sync_data.pinned(); | |
| 484 extension_app_id = sync_data.extension_app_id(); | |
| 485 user_agent_override.clear(); | |
| 486 this->timestamp = timestamp; | |
| 487 navigations.clear(); | |
| 488 for (int i = 0; i < sync_data.navigation_size(); ++i) { | |
| 489 navigations.push_back( | |
| 490 TabNavigation::FromSyncData(i, sync_data.navigation(i))); | |
| 491 } | |
| 492 session_storage_persistent_id.clear(); | |
| 493 } | |
| 494 | |
| 495 sync_pb::SessionTab SessionTab::ToSyncData() const { | |
| 496 sync_pb::SessionTab sync_data; | |
| 497 sync_data.set_tab_id(tab_id.id()); | |
| 498 sync_data.set_window_id(window_id.id()); | |
| 499 sync_data.set_tab_visual_index(tab_visual_index); | |
| 500 sync_data.set_current_navigation_index(current_navigation_index); | |
| 501 sync_data.set_pinned(pinned); | |
| 502 sync_data.set_extension_app_id(extension_app_id); | |
| 503 for (std::vector<TabNavigation>::const_iterator it = navigations.begin(); | |
| 504 it != navigations.end(); ++it) { | |
| 505 *sync_data.add_navigation() = it->ToSyncData(); | |
| 506 } | |
| 507 return sync_data; | |
| 508 } | |
| 509 | |
| 510 // SessionWindow --------------------------------------------------------------- | |
| 511 | |
| 512 SessionWindow::SessionWindow() | |
| 513 : selected_tab_index(-1), | |
| 514 type(Browser::TYPE_TABBED), | |
| 515 is_constrained(true), | |
| 516 show_state(ui::SHOW_STATE_DEFAULT) { | |
| 517 } | |
| 518 | |
| 519 SessionWindow::~SessionWindow() { | |
| 520 STLDeleteElements(&tabs); | |
| 521 } | |
| OLD | NEW |