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 |