diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 04:04:16 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 04:04:16 +0000 |
commit | 9dd1d5809c8420f1e636154424826bf575804cdc (patch) | |
tree | 2a9709d108d300c8ee303332674e3468befcaac2 /chrome/browser | |
parent | a26e6666e814600a133dae854ab6fa0762b0b51f (diff) | |
download | chromium_src-9dd1d5809c8420f1e636154424826bf575804cdc.zip chromium_src-9dd1d5809c8420f1e636154424826bf575804cdc.tar.gz chromium_src-9dd1d5809c8420f1e636154424826bf575804cdc.tar.bz2 |
Move all TabNavigation logic to session_types.{h,cc}
In particular, move the conversion to/from NavigationEntry,
to/from sync_pb::TabNavigation, and pickling/unpickling logic
to member functions of TabNavigation.
Merge TabNavigation and SyncedTabNavigation (i.e., add unique_id and timestamp to TabNavigation).
Mark most TabNavigation accessors ForTest().
Make CreateUpdateTabNavigationCommand() and UpdateTabNavigation() take a TabNavigation instead of an index + NavigationEntry.
Make TabNavigation use default copy constructor and assignment operator. Also do some other misc. cleanups.
Also remove unused field 'unique_id' from sync_pb::TabNavigation.
Use correct indices in session model associator.
Add some unit tests for TabNavigation.
BUG=128449
Review URL: https://chromiumcodereview.appspot.com/10917231
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157491 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
29 files changed, 1171 insertions, 865 deletions
diff --git a/chrome/browser/sessions/DEPS b/chrome/browser/sessions/DEPS index 5a55055..41ea134 100644 --- a/chrome/browser/sessions/DEPS +++ b/chrome/browser/sessions/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+sync/util/time.h", # For compressing data stored in SessionStorage. "+third_party/bzip2", ] diff --git a/chrome/browser/sessions/base_session_service.cc b/chrome/browser/sessions/base_session_service.cc index fe88ae0..b89c6a3 100644 --- a/chrome/browser/sessions/base_session_service.cc +++ b/chrome/browser/sessions/base_session_service.cc @@ -20,7 +20,6 @@ #include "content/public/common/referrer.h" #include "webkit/glue/webkit_glue.h" -using WebKit::WebReferrerPolicy; using content::BrowserThread; using content::NavigationEntry; @@ -150,52 +149,11 @@ void BaseSessionService::Save() { SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( SessionID::id_type command_id, SessionID::id_type tab_id, - int index, - const NavigationEntry& entry) { + const TabNavigation& navigation) { // Use pickle to handle marshalling. Pickle pickle; pickle.WriteInt(tab_id); - pickle.WriteInt(index); - - // We only allow navigations up to 63k (which should be completely - // reasonable). On the off chance we get one that is too big, try to - // keep the url. - - // Bound the string data (which is variable length) to - // |max_state_size bytes| bytes. - static const SessionCommand::size_type max_state_size = - std::numeric_limits<SessionCommand::size_type>::max() - 1024; - - int bytes_written = 0; - - WriteStringToPickle(pickle, &bytes_written, max_state_size, - entry.GetVirtualURL().spec()); - - WriteString16ToPickle(pickle, &bytes_written, max_state_size, - entry.GetTitle()); - - std::string content_state = entry.GetContentState(); - if (entry.GetHasPostData()) { - content_state = - webkit_glue::RemovePasswordDataFromHistoryState(content_state); - } - WriteStringToPickle(pickle, &bytes_written, max_state_size, content_state); - - pickle.WriteInt(entry.GetTransitionType()); - int type_mask = entry.GetHasPostData() ? TabNavigation::HAS_POST_DATA : 0; - pickle.WriteInt(type_mask); - - WriteStringToPickle(pickle, &bytes_written, max_state_size, - entry.GetReferrer().url.is_valid() ? - entry.GetReferrer().url.spec() : std::string()); - pickle.WriteInt(entry.GetReferrer().policy); - - // Save info required to override the user agent. - WriteStringToPickle(pickle, &bytes_written, max_state_size, - entry.GetOriginalRequestURL().is_valid() ? - entry.GetOriginalRequestURL().spec() : std::string()); - pickle.WriteBool(entry.GetIsOverridingUserAgent()); - + navigation.WriteToPickle(&pickle); return new SessionCommand(command_id, pickle); } @@ -266,51 +224,9 @@ bool BaseSessionService::RestoreUpdateTabNavigationCommand( if (!pickle.get()) return false; PickleIterator iterator(*pickle); - std::string url_spec; - if (!pickle->ReadInt(&iterator, tab_id) || - !pickle->ReadInt(&iterator, &(navigation->index_)) || - !pickle->ReadString(&iterator, &url_spec) || - !pickle->ReadString16(&iterator, &(navigation->title_)) || - !pickle->ReadString(&iterator, &(navigation->state_)) || - !pickle->ReadInt(&iterator, - reinterpret_cast<int*>(&(navigation->transition_)))) - return false; - // type_mask did not always exist in the written stream. As such, we - // don't fail if it can't be read. - bool has_type_mask = pickle->ReadInt(&iterator, &(navigation->type_mask_)); - - if (has_type_mask) { - // the "referrer" property was added after type_mask to the written - // stream. As such, we don't fail if it can't be read. - std::string referrer_spec; - pickle->ReadString(&iterator, &referrer_spec); - // The "referrer policy" property was added even later, so we fall back to - // the default policy if the property is not present. - int policy_int; - WebReferrerPolicy policy; - if (pickle->ReadInt(&iterator, &policy_int)) - policy = static_cast<WebReferrerPolicy>(policy_int); - else - policy = WebKit::WebReferrerPolicyDefault; - navigation->referrer_ = content::Referrer( - referrer_spec.empty() ? GURL() : GURL(referrer_spec), - policy); - - // If the original URL can't be found, leave it empty. - std::string url_spec; - if (!pickle->ReadString(&iterator, &url_spec)) - url_spec = std::string(); - navigation->set_original_request_url(GURL(url_spec)); - - // Default to not overriding the user agent if we don't have info. - bool override_user_agent; - if (!pickle->ReadBool(&iterator, &override_user_agent)) - override_user_agent = false; - navigation->set_is_overriding_user_agent(override_user_agent); - } - - navigation->virtual_url_ = GURL(url_spec); - return true; + return + pickle->ReadInt(&iterator, tab_id) && + navigation->ReadFromPickle(&iterator); } bool BaseSessionService::RestoreSetTabExtensionAppIDCommand( diff --git a/chrome/browser/sessions/base_session_service.h b/chrome/browser/sessions/base_session_service.h index 2fd043a..ce0253d 100644 --- a/chrome/browser/sessions/base_session_service.h +++ b/chrome/browser/sessions/base_session_service.h @@ -22,10 +22,6 @@ class SessionBackend; class SessionCommand; class TabNavigation; -namespace content { -class NavigationEntry; -} - // BaseSessionService is the super class of both tab restore service and // session service. It contains commonality needed by both, in particular // it manages a set of SessionCommands that are periodically sent to a @@ -113,8 +109,7 @@ class BaseSessionService : public CancelableRequestProvider, SessionCommand* CreateUpdateTabNavigationCommand( SessionID::id_type command_id, SessionID::id_type tab_id, - int index, - const content::NavigationEntry& entry); + const TabNavigation& navigation); // Creates a SessionCommand that represents marking a tab as an application. SessionCommand* CreateSetTabExtensionAppIDCommand( diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index adab427..c9145ba 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc @@ -947,7 +947,7 @@ class SessionRestoreImpl : public content::NotificationObserver { base::PLATFORM_FILE_EXCLUSIVE_READ | base::PLATFORM_FILE_ASYNC; const std::string& state = - tab.navigations.at(selected_index).state(); + tab.navigations.at(selected_index).content_state(); const std::vector<FilePath>& file_paths = webkit_glue::FilePathsFromHistoryState(state); for (std::vector<FilePath>::const_iterator file = file_paths.begin(); diff --git a/chrome/browser/sessions/session_restore_android.cc b/chrome/browser/sessions/session_restore_android.cc index 41b3c06..836ff0c 100644 --- a/chrome/browser/sessions/session_restore_android.cc +++ b/chrome/browser/sessions/session_restore_android.cc @@ -26,9 +26,9 @@ void SessionRestore::RestoreForeignSessionTab( Profile* profile = Profile::FromBrowserContext(context); TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile); DCHECK(tab_model); - std::vector<content::NavigationEntry*> entries; - TabNavigation::CreateNavigationEntriesFromTabNavigations( - profile, session_tab.navigations, &entries); + std::vector<content::NavigationEntry*> entries = + TabNavigation::CreateNavigationEntriesFromTabNavigations( + session_tab.navigations, profile); content::WebContents* new_web_contents = content::WebContents::Create( context, NULL, MSG_ROUTING_NONE, NULL); int selected_index = session_tab.normalized_navigation_index(); diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 76620e2..7c75e1d 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc @@ -14,6 +14,8 @@ #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/session_service_test_helper.h" +#include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/ui/browser.h" @@ -387,10 +389,11 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) { IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) { GURL url1("http://google.com"); GURL url2("http://google2.com"); - TabNavigation nav1(0, url1, content::Referrer(), ASCIIToUTF16("one"), - std::string(), content::PAGE_TRANSITION_TYPED); - TabNavigation nav2(0, url2, content::Referrer(), ASCIIToUTF16("two"), - std::string(), content::PAGE_TRANSITION_TYPED); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation(url1.spec(), "one"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation(url2.spec(), "two"); + SessionTypesTestHelper::SetIsOverridingUserAgent(&nav2, true); // Set up the restore data. SessionTab tab; @@ -450,12 +453,10 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) { GURL url1("http://google.com"); GURL url2("http://google2.com"); - TabNavigation nav1(0, url1, content::Referrer(), ASCIIToUTF16("one"), - std::string(), content::PAGE_TRANSITION_TYPED); - TabNavigation nav2(0, url2, content::Referrer(), ASCIIToUTF16("two"), - std::string(), content::PAGE_TRANSITION_TYPED); - nav1.set_is_overriding_user_agent(false); - nav2.set_is_overriding_user_agent(true); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation(url1.spec(), "one"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation(url2.spec(), "two"); // Set up the restore data -- one window with two tabs. std::vector<const SessionWindow*> session; @@ -499,11 +500,13 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) { content::NavigationEntry* entry = web_contents_1->GetController().GetActiveEntry(); ASSERT_TRUE(entry); - ASSERT_EQ(nav1.is_overriding_user_agent(), entry->GetIsOverridingUserAgent()); + ASSERT_EQ(SessionTypesTestHelper::GetIsOverridingUserAgent(nav1), + entry->GetIsOverridingUserAgent()); entry = web_contents_2->GetController().GetActiveEntry(); ASSERT_TRUE(entry); - ASSERT_EQ(nav2.is_overriding_user_agent(), entry->GetIsOverridingUserAgent()); + ASSERT_EQ(SessionTypesTestHelper::GetIsOverridingUserAgent(nav2), + entry->GetIsOverridingUserAgent()); // The SessionWindow destructor deletes the tabs, so we have to clear them // here to avoid a crash. diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc index 3e4961d..eb406fc 100644 --- a/chrome/browser/sessions/session_service.cc +++ b/chrome/browser/sessions/session_service.cc @@ -430,9 +430,8 @@ void SessionService::TabNavigationPathPrunedFromFront( void SessionService::UpdateTabNavigation( const SessionID& window_id, const SessionID& tab_id, - int index, - const NavigationEntry& entry) { - if (!ShouldTrackEntry(entry.GetVirtualURL()) || + const TabNavigation& navigation) { + if (!ShouldTrackEntry(navigation.virtual_url()) || !ShouldTrackChangesToWindow(window_id)) { return; } @@ -440,11 +439,11 @@ void SessionService::UpdateTabNavigation( if (tab_to_available_range_.find(tab_id.id()) != tab_to_available_range_.end()) { std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; - range.first = std::min(index, range.first); - range.second = std::max(index, range.second); + range.first = std::min(navigation.index(), range.first); + range.second = std::max(navigation.index(), range.second); } ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, - tab_id.id(), index, entry)); + tab_id.id(), navigation)); } void SessionService::TabRestored(TabContents* tab, bool pinned) { @@ -689,9 +688,13 @@ void SessionService::Observe(int type, if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) return; content::Details<content::EntryChangedDetails> changed(details); + const TabNavigation navigation = + TabNavigation::FromNavigationEntry( + changed->index, *changed->changed_entry, + base::Time::Now()); UpdateTabNavigation(session_tab_helper->window_id(), session_tab_helper->session_id(), - changed->index, *changed->changed_entry); + navigation); break; } @@ -709,11 +712,16 @@ void SessionService::Observe(int type, session_tab_helper->window_id(), session_tab_helper->session_id(), current_entry_index); + const TabNavigation navigation = + TabNavigation::FromNavigationEntry( + current_entry_index, + *web_contents->GetController().GetEntryAtIndex( + current_entry_index), + base::Time::Now()); UpdateTabNavigation( session_tab_helper->window_id(), session_tab_helper->session_id(), - current_entry_index, - *web_contents->GetController().GetEntryAtIndex(current_entry_index)); + navigation); content::Details<content::LoadCommittedDetails> changed(details); if (changed->type == content::NAVIGATION_TYPE_NEW_PAGE || changed->type == content::NAVIGATION_TYPE_EXISTING_PAGE) { @@ -1352,9 +1360,11 @@ void SessionService::BuildCommandsForTab( tab->web_contents()->GetController().GetEntryAtIndex(i); DCHECK(entry); if (ShouldTrackEntry(entry->GetVirtualURL())) { + const TabNavigation navigation = + TabNavigation::FromNavigationEntry(i, *entry, base::Time::Now()); commands->push_back( CreateUpdateTabNavigationCommand( - kCommandUpdateTabNavigation, session_id.id(), i, *entry)); + kCommandUpdateTabNavigation, session_id.id(), navigation)); } } commands->push_back( diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h index 74512c4..b106640 100644 --- a/chrome/browser/sessions/session_service.h +++ b/chrome/browser/sessions/session_service.h @@ -149,8 +149,7 @@ class SessionService : public BaseSessionService, // Updates the navigation entry for the specified tab. void UpdateTabNavigation(const SessionID& window_id, const SessionID& tab_id, - int index, - const content::NavigationEntry& entry); + const TabNavigation& navigation); // Notification that a tab has restored its entries or a closed tab is being // reused. diff --git a/chrome/browser/sessions/session_service_test_helper.cc b/chrome/browser/sessions/session_service_test_helper.cc index 3f02a4c..62aac7c 100644 --- a/chrome/browser/sessions/session_service_test_helper.cc +++ b/chrome/browser/sessions/session_service_test_helper.cc @@ -9,6 +9,7 @@ #include "chrome/browser/sessions/session_id.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; @@ -89,16 +90,7 @@ void SessionServiceTestHelper::AssertTabEquals( void SessionServiceTestHelper::AssertNavigationEquals( const TabNavigation& expected, const TabNavigation& actual) { - EXPECT_TRUE(expected.virtual_url() == actual.virtual_url()); - EXPECT_EQ(expected.referrer().url, actual.referrer().url); - EXPECT_EQ(expected.referrer().policy, actual.referrer().policy); - EXPECT_EQ(expected.title(), actual.title()); - EXPECT_EQ(expected.state(), actual.state()); - EXPECT_EQ(expected.transition(), actual.transition()); - EXPECT_EQ(expected.type_mask(), actual.type_mask()); - EXPECT_TRUE(expected.original_request_url() == actual.original_request_url()); - EXPECT_EQ(expected.is_overriding_user_agent(), - actual.is_overriding_user_agent()); + SessionTypesTestHelper::ExpectNavigationEquals(expected, actual); } void SessionServiceTestHelper::AssertSingleWindowWithSingleTab( diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc index 748ee7a..3152b3b 100644 --- a/chrome/browser/sessions/session_service_unittest.cc +++ b/chrome/browser/sessions/session_service_unittest.cc @@ -18,6 +18,7 @@ #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_test_helper.h" #include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/browser_with_test_window_test.h" @@ -75,21 +76,12 @@ class SessionServiceTest : public BrowserWithTestWindowTest, void UpdateNavigation(const SessionID& window_id, const SessionID& tab_id, const TabNavigation& navigation, - int index, bool select) { - scoped_ptr<NavigationEntry> entry(NavigationEntry::Create()); - entry->SetURL(navigation.virtual_url()); - entry->SetReferrer(navigation.referrer()); - entry->SetTitle(navigation.title()); - entry->SetContentState(navigation.state()); - entry->SetTransitionType(navigation.transition()); - entry->SetHasPostData( - navigation.type_mask() & TabNavigation::HAS_POST_DATA); - entry->SetOriginalRequestURL(navigation.original_request_url()); - entry->SetIsOverridingUserAgent(navigation.is_overriding_user_agent()); - service()->UpdateTabNavigation(window_id, tab_id, index, *entry.get()); - if (select) - service()->SetSelectedNavigationIndex(window_id, tab_id, index); + service()->UpdateTabNavigation(window_id, tab_id, navigation); + if (select) { + service()->SetSelectedNavigationIndex( + window_id, tab_id, navigation.index()); + } } void ReadWindows(std::vector<SessionWindow*>* windows) { @@ -107,14 +99,11 @@ class SessionServiceTest : public BrowserWithTestWindowTest, // and the pinned state of the read back tab is returned. bool CreateAndWriteSessionWithOneTab(bool pinned_state, bool write_always) { SessionID tab_id; - TabNavigation nav1(0, GURL("http://google.com"), - content::Referrer(GURL("http://www.referrer.com"), - WebKit::WebReferrerPolicyDefault), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); if (pinned_state || write_always) helper_.service()->SetPinnedState(window_id, tab_id, pinned_state); @@ -156,15 +145,13 @@ TEST_F(SessionServiceTest, Basic) { SessionID tab_id; ASSERT_NE(window_id.id(), tab_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), - content::Referrer(GURL("http://www.referrer.com"), - WebKit::WebReferrerPolicyDefault), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - nav1.set_original_request_url(GURL("http://original.request.com")); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + SessionTypesTestHelper::SetOriginalRequestURL( + &nav1, GURL("http://original.request.com")); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -187,13 +174,12 @@ TEST_F(SessionServiceTest, PersistPostData) { SessionID tab_id; ASSERT_NE(window_id.id(), tab_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), std::string(), - content::PAGE_TRANSITION_QUALIFIER_MASK); - nav1.set_type_mask(TabNavigation::HAS_POST_DATA); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + SessionTypesTestHelper::SetHasPostData(&nav1, true); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -206,18 +192,16 @@ TEST_F(SessionServiceTest, ClosingTabStaysClosed) { SessionID tab2_id; ASSERT_NE(tab_id.id(), tab2_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window_id, tab2_id, 1, false); - UpdateNavigation(window_id, tab2_id, nav2, 0, true); + UpdateNavigation(window_id, tab2_id, nav2, true); service()->TabClosed(window_id, tab2_id, false); ScopedVector<SessionWindow> windows; @@ -237,17 +221,16 @@ TEST_F(SessionServiceTest, ClosingTabStaysClosed) { TEST_F(SessionServiceTest, Pruning) { SessionID tab_id; - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); for (int i = 0; i < 6; ++i) { - TabNavigation& nav = (i % 2) == 0 ? nav1 : nav2; - UpdateNavigation(window_id, tab_id, nav, i, true); + TabNavigation* nav = (i % 2) == 0 ? &nav1 : &nav2; + nav->set_index(i); + UpdateNavigation(window_id, tab_id, *nav, true); } service()->TabNavigationPathPrunedFromBack(window_id, tab_id, 3); @@ -263,6 +246,7 @@ TEST_F(SessionServiceTest, Pruning) { // index should get reset to last valid navigation, which is 2. helper_.AssertTabEquals(window_id, tab_id, 0, 2, 3, *tab); + ASSERT_EQ(3u, tab->navigations.size()); helper_.AssertNavigationEquals(nav1, tab->navigations[0]); helper_.AssertNavigationEquals(nav2, tab->navigations[1]); helper_.AssertNavigationEquals(nav1, tab->navigations[2]); @@ -273,15 +257,13 @@ TEST_F(SessionServiceTest, TwoWindows) { SessionID tab1_id; SessionID tab2_id; - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab1_id, 0, true); - UpdateNavigation(window_id, tab1_id, nav1, 0, true); + UpdateNavigation(window_id, tab1_id, nav1, true); const gfx::Rect window2_bounds(3, 4, 5, 6); service()->SetWindowType( @@ -290,7 +272,7 @@ TEST_F(SessionServiceTest, TwoWindows) { window2_bounds, ui::SHOW_STATE_MAXIMIZED); helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true); - UpdateNavigation(window2_id, tab2_id, nav2, 0, true); + UpdateNavigation(window2_id, tab2_id, nav2, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -331,12 +313,11 @@ TEST_F(SessionServiceTest, WindowWithNoTabsGetsPruned) { SessionID tab1_id; SessionID tab2_id; - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); helper_.PrepareTabInWindow(window_id, tab1_id, 0, true); - UpdateNavigation(window_id, tab1_id, nav1, 0, true); + UpdateNavigation(window_id, tab1_id, nav1, true); const gfx::Rect window2_bounds(3, 4, 5, 6); service()->SetWindowType( @@ -364,18 +345,16 @@ TEST_F(SessionServiceTest, ClosingWindowDoesntCloseTabs) { SessionID tab2_id; ASSERT_NE(tab_id.id(), tab2_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window_id, tab2_id, 1, false); - UpdateNavigation(window_id, tab2_id, nav2, 0, true); + UpdateNavigation(window_id, tab2_id, nav2, true); service()->WindowClosing(window_id); @@ -408,18 +387,16 @@ TEST_F(SessionServiceTest, WindowCloseCommittedAfterNavigate) { window_bounds, ui::SHOW_STATE_NORMAL); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); - UpdateNavigation(window2_id, tab2_id, nav2, 0, true); + UpdateNavigation(window2_id, tab2_id, nav2, true); service()->WindowClosing(window2_id); service()->TabClosed(window2_id, tab2_id, false); @@ -454,18 +431,16 @@ TEST_F(SessionServiceTest, IgnorePopups) { window_bounds, ui::SHOW_STATE_NORMAL); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); - UpdateNavigation(window2_id, tab2_id, nav2, 0, true); + UpdateNavigation(window2_id, tab2_id, nav2, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -496,18 +471,16 @@ TEST_F(SessionServiceTest, RestorePopup) { window_bounds, ui::SHOW_STATE_NORMAL); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); - UpdateNavigation(window2_id, tab2_id, nav2, 0, true); + UpdateNavigation(window2_id, tab2_id, nav2, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -548,18 +521,16 @@ TEST_F(SessionServiceTest, RestoreApp) { ui::SHOW_STATE_NORMAL); service()->SetWindowAppName(window2_id, "TestApp"); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); - TabNavigation nav2(0, GURL("http://google2.com"), content::Referrer(), - ASCIIToUTF16("abcd"), "defg", - content::PAGE_TRANSITION_AUTO_BOOKMARK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("http://google2.com", "abcd"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false); - UpdateNavigation(window2_id, tab2_id, nav2, 0, true); + UpdateNavigation(window2_id, tab2_id, nav2, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -597,11 +568,11 @@ TEST_F(SessionServiceTest, PruneFromFront) { // Add 5 navigations, with the 4th selected. for (int i = 0; i < 5; ++i) { - TabNavigation nav(0, GURL(base_url + base::IntToString(i)), - content::Referrer(), - ASCIIToUTF16("a"), "b", - content::PAGE_TRANSITION_QUALIFIER_MASK); - UpdateNavigation(window_id, tab_id, nav, i, (i == 3)); + TabNavigation nav = + SessionTypesTestHelper::CreateNavigation( + base_url + base::IntToString(i), "a"); + nav.set_index(i); + UpdateNavigation(window_id, tab_id, nav, (i == 3)); } // Prune the first two navigations from the front. @@ -640,11 +611,11 @@ TEST_F(SessionServiceTest, PruneToEmpty) { // Add 5 navigations, with the 4th selected. for (int i = 0; i < 5; ++i) { - TabNavigation nav(0, GURL(base_url + base::IntToString(i)), - content::Referrer(), - ASCIIToUTF16("a"), "b", - content::PAGE_TRANSITION_QUALIFIER_MASK); - UpdateNavigation(window_id, tab_id, nav, i, (i == 3)); + TabNavigation nav = + SessionTypesTestHelper::CreateNavigation( + base_url + base::IntToString(i), "a"); + nav.set_index(i); + UpdateNavigation(window_id, tab_id, nav, (i == 3)); } // Prune the first two navigations from the front. @@ -678,12 +649,11 @@ TEST_F(SessionServiceTest, PersistApplicationExtensionID) { ASSERT_NE(window_id.id(), tab_id.id()); std::string app_id("foo"); - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), std::string(), - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.SetTabExtensionAppID(window_id, tab_id, app_id); ScopedVector<SessionWindow> windows; @@ -701,13 +671,12 @@ TEST_F(SessionServiceTest, PersistUserAgentOverrides) { "AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.45 " "Safari/535.19"; - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("abc"), std::string(), - content::PAGE_TRANSITION_QUALIFIER_MASK); - nav1.set_is_overriding_user_agent(true); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); + SessionTypesTestHelper::SetIsOverridingUserAgent(&nav1, true); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); helper_.SetTabUserAgentOverride(window_id, tab_id, user_agent_override); ScopedVector<SessionWindow> windows; @@ -734,14 +703,11 @@ TEST_F(SessionServiceTest, CloseTabUserGesture) { SessionID tab_id; ASSERT_NE(window_id.id(), tab_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), - content::Referrer(GURL("http://www.referrer.com"), - WebKit::WebReferrerPolicyDefault), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); service()->TabClosed(window_id, tab_id, true); ScopedVector<SessionWindow> windows; @@ -754,13 +720,10 @@ TEST_F(SessionServiceTest, CloseTabUserGesture) { TEST_F(SessionServiceTest, DontPersistDefault) { SessionID tab_id; ASSERT_NE(window_id.id(), tab_id.id()); - TabNavigation nav1(0, GURL("http://google.com"), - content::Referrer(GURL("http://www.referrer.com"), - WebKit::WebReferrerPolicyDefault), - ASCIIToUTF16("abc"), "def", - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "abc"); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); service()->SetWindowBounds(window_id, window_bounds, ui::SHOW_STATE_DEFAULT); @@ -787,20 +750,22 @@ TEST_F(SessionServiceTest, KeepPostDataWithoutPasswords) { // Create a TabNavigation containing content_state and representing a POST // request. - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("title"), content_state, - content::PAGE_TRANSITION_QUALIFIER_MASK); - nav1.set_type_mask(TabNavigation::HAS_POST_DATA); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "title"); + SessionTypesTestHelper::SetContentState(&nav1, content_state); + SessionTypesTestHelper::SetHasPostData(&nav1, true); // Create a TabNavigation containing content_state and representing a normal // request. - TabNavigation nav2(0, GURL("http://google.com/nopost"), content::Referrer(), - ASCIIToUTF16("title"), content_state, - content::PAGE_TRANSITION_QUALIFIER_MASK); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation( + "http://google.com/nopost", "title"); + SessionTypesTestHelper::SetContentState(&nav2, content_state); + nav2.set_index(1); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); - UpdateNavigation(window_id, tab_id, nav2, 1, true); + UpdateNavigation(window_id, tab_id, nav1, true); + UpdateNavigation(window_id, tab_id, nav2, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -808,6 +773,7 @@ TEST_F(SessionServiceTest, KeepPostDataWithoutPasswords) { helper_.AssertSingleWindowWithSingleTab(windows.get(), 2); // Expected: the content state of both navigations was saved and restored. + ASSERT_EQ(2u, windows[0]->tabs[0]->navigations.size()); helper_.AssertNavigationEquals(nav1, windows[0]->tabs[0]->navigations[0]); helper_.AssertNavigationEquals(nav2, windows[0]->tabs[0]->navigations[1]); } @@ -829,12 +795,12 @@ TEST_F(SessionServiceTest, RemovePostDataWithPasswords) { // Create a TabNavigation containing content_state and representing a POST // request with passwords. - TabNavigation nav1(0, GURL("http://google.com"), content::Referrer(), - ASCIIToUTF16("title"), content_state, - content::PAGE_TRANSITION_QUALIFIER_MASK); - nav1.set_type_mask(TabNavigation::HAS_POST_DATA); + TabNavigation nav1 = + SessionTypesTestHelper::CreateNavigation("http://google.com", "title"); + SessionTypesTestHelper::SetContentState(&nav1, content_state); + SessionTypesTestHelper::SetHasPostData(&nav1, true); helper_.PrepareTabInWindow(window_id, tab_id, 0, true); - UpdateNavigation(window_id, tab_id, nav1, 0, true); + UpdateNavigation(window_id, tab_id, nav1, true); ScopedVector<SessionWindow> windows; ReadWindows(&(windows.get())); @@ -843,7 +809,7 @@ TEST_F(SessionServiceTest, RemovePostDataWithPasswords) { // Expected: the HTTP body was removed from the content state of the POST // navigation with passwords. - EXPECT_NE(content_state, windows[0]->tabs[0]->navigations[0].state()); + EXPECT_NE(content_state, windows[0]->tabs[0]->navigations[0].content_state()); } // This test is only applicable to chromeos. diff --git a/chrome/browser/sessions/session_types.cc b/chrome/browser/sessions/session_types.cc index 5691f8d..c31ddf5 100644 --- a/chrome/browser/sessions/session_types.cc +++ b/chrome/browser/sessions/session_types.cc @@ -4,118 +4,420 @@ #include "chrome/browser/sessions/session_types.h" +#include "base/basictypes.h" +#include "base/pickle.h" +#include "base/stl_util.h" #include "base/string_util.h" -#include "chrome/browser/profiles/profile.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/sessions/session_command.h" #include "chrome/browser/ui/browser.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" +#include "sync/util/time.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h" +#include "webkit/glue/webkit_glue.h" using content::NavigationEntry; // TabNavigation -------------------------------------------------------------- TabNavigation::TabNavigation() - : transition_(content::PAGE_TRANSITION_TYPED), - type_mask_(0), + : index_(-1), + unique_id_(0), + transition_type_(content::PAGE_TRANSITION_TYPED), + has_post_data_(false), post_id_(-1), - index_(-1), - is_overriding_user_agent_(false) { + is_overriding_user_agent_(false) {} + +TabNavigation::~TabNavigation() {} + +// static +TabNavigation TabNavigation::FromNavigationEntry( + int index, + const NavigationEntry& entry, + base::Time timestamp) { + TabNavigation navigation; + navigation.index_ = index; + navigation.unique_id_ = entry.GetUniqueID(); + navigation.referrer_ = entry.GetReferrer(); + navigation.virtual_url_ = entry.GetVirtualURL(); + navigation.title_ = entry.GetTitle(); + navigation.content_state_ = entry.GetContentState(); + navigation.transition_type_ = entry.GetTransitionType(); + navigation.has_post_data_ = entry.GetHasPostData(); + navigation.post_id_ = entry.GetPostID(); + navigation.original_request_url_ = entry.GetOriginalRequestURL(); + navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); + navigation.timestamp_ = timestamp; + return navigation; } -TabNavigation::TabNavigation(int index, - const GURL& virtual_url, - const content::Referrer& referrer, - const string16& title, - const std::string& state, - content::PageTransition transition) - : virtual_url_(virtual_url), - referrer_(referrer), - title_(title), - state_(state), - transition_(transition), - type_mask_(0), - post_id_(-1), - index_(index), - is_overriding_user_agent_(false) { +TabNavigation TabNavigation::FromSyncData( + int index, + const sync_pb::TabNavigation& specifics) { + TabNavigation navigation; + navigation.index_ = index; + if (specifics.has_unique_id()) { + navigation.unique_id_ = specifics.unique_id(); + } + if (specifics.has_referrer()) { + navigation.referrer_ = + content::Referrer(GURL(specifics.referrer()), + WebKit::WebReferrerPolicyDefault); + } + if (specifics.has_virtual_url()) + navigation.virtual_url_ = GURL(specifics.virtual_url()); + if (specifics.has_title()) + navigation.title_ = UTF8ToUTF16(specifics.title()); + if (specifics.has_state()) + navigation.content_state_ = specifics.state(); + navigation.transition_type_ = content::PAGE_TRANSITION_LINK; + if (specifics.has_page_transition() || + specifics.has_navigation_qualifier()) { + switch (specifics.page_transition()) { + case sync_pb::SyncEnums_PageTransition_LINK: + navigation.transition_type_ = content::PAGE_TRANSITION_LINK; + break; + case sync_pb::SyncEnums_PageTransition_TYPED: + navigation.transition_type_ = content::PAGE_TRANSITION_TYPED; + break; + case sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK: + navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_BOOKMARK; + break; + case sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME: + navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_SUBFRAME; + break; + case sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME: + navigation.transition_type_ = content::PAGE_TRANSITION_MANUAL_SUBFRAME; + break; + case sync_pb::SyncEnums_PageTransition_GENERATED: + navigation.transition_type_ = content::PAGE_TRANSITION_GENERATED; + break; + case sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL: + navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_TOPLEVEL; + break; + case sync_pb::SyncEnums_PageTransition_FORM_SUBMIT: + navigation.transition_type_ = content::PAGE_TRANSITION_FORM_SUBMIT; + break; + case sync_pb::SyncEnums_PageTransition_RELOAD: + navigation.transition_type_ = content::PAGE_TRANSITION_RELOAD; + break; + case sync_pb::SyncEnums_PageTransition_KEYWORD: + navigation.transition_type_ = content::PAGE_TRANSITION_KEYWORD; + break; + case sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED: + navigation.transition_type_ = + content::PAGE_TRANSITION_KEYWORD_GENERATED; + break; + case sync_pb::SyncEnums_PageTransition_CHAIN_START: + navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_START; + break; + case sync_pb::SyncEnums_PageTransition_CHAIN_END: + navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_END; + break; + default: + switch (specifics.navigation_qualifier()) { + case sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT: + navigation.transition_type_ = + content::PAGE_TRANSITION_CLIENT_REDIRECT; + break; + case sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT: + navigation.transition_type_ = + content::PAGE_TRANSITION_SERVER_REDIRECT; + break; + default: + navigation.transition_type_ = content::PAGE_TRANSITION_TYPED; + } + } + } + if (specifics.has_timestamp()) { + navigation.timestamp_ = syncer::ProtoTimeToTime(specifics.timestamp()); + } + return navigation; } -TabNavigation::TabNavigation(const TabNavigation& tab) - : virtual_url_(tab.virtual_url_), - referrer_(tab.referrer_), - title_(tab.title_), - state_(tab.state_), - transition_(tab.transition_), - type_mask_(tab.type_mask_), - post_id_(-1), - index_(tab.index_), - original_request_url_(tab.original_request_url_), - is_overriding_user_agent_(tab.is_overriding_user_agent_) { +namespace { + +// Helper used by TabNavigation::WriteToPickle(). It writes |str| to +// |pickle|, if and only if |str| fits within (|max_bytes| - +// |*bytes_written|). |bytes_written| is incremented to reflect the +// data written. +// +// TODO(akalin): Unify this with the same function in +// base_session_service.cc. +void WriteStringToPickle(Pickle* pickle, + int* bytes_written, + int max_bytes, + const std::string& str) { + int num_bytes = str.size() * sizeof(char); + if (*bytes_written + num_bytes < max_bytes) { + *bytes_written += num_bytes; + pickle->WriteString(str); + } else { + pickle->WriteString(std::string()); + } } -TabNavigation::~TabNavigation() { +// string16 version of WriteStringToPickle. +// +// TODO(akalin): Unify this, too. +void WriteString16ToPickle(Pickle* pickle, + int* bytes_written, + int max_bytes, + const string16& str) { + int num_bytes = str.size() * sizeof(char16); + if (*bytes_written + num_bytes < max_bytes) { + *bytes_written += num_bytes; + pickle->WriteString16(str); + } else { + pickle->WriteString16(string16()); + } +} + +// A mask used for arbitrary boolean values needed to represent a +// NavigationEntry. Currently only contains HAS_POST_DATA. +// +// NOTE(akalin): We may want to just serialize |has_post_data_| +// directly. Other bools (|is_overriding_user_agent_|) haven't been +// added to this mask. +enum TypeMask { + HAS_POST_DATA = 1 +}; + +} // namespace + +// Pickle order: +// +// index_ +// virtual_url_ +// title_ +// content_state_ +// transition_type_ +// +// Added on later: +// +// type_mask (has_post_data_) +// referrer_ +// original_request_url_ +// is_overriding_user_agent_ + +void TabNavigation::WriteToPickle(Pickle* pickle) const { + pickle->WriteInt(index_); + + // We only allow navigations up to 63k (which should be completely + // reasonable). On the off chance we get one that is too big, try to + // keep the url. + + // Bound the string data (which is variable length) to + // |max_state_size bytes| bytes. + static const size_t max_state_size = + std::numeric_limits<SessionCommand::size_type>::max() - 1024; + int bytes_written = 0; + + WriteStringToPickle(pickle, &bytes_written, max_state_size, + virtual_url_.spec()); + + WriteString16ToPickle(pickle, &bytes_written, max_state_size, title_); + + std::string content_state = content_state_; + if (has_post_data_) { + content_state = + webkit_glue::RemovePasswordDataFromHistoryState(content_state); + } + WriteStringToPickle(pickle, &bytes_written, max_state_size, content_state); + + pickle->WriteInt(transition_type_); + + const int type_mask = has_post_data_ ? HAS_POST_DATA : 0; + pickle->WriteInt(type_mask); + + WriteStringToPickle( + pickle, &bytes_written, max_state_size, + referrer_.url.is_valid() ? referrer_.url.spec() : std::string()); + + pickle->WriteInt(referrer_.policy); + + // Save info required to override the user agent. + WriteStringToPickle( + pickle, &bytes_written, max_state_size, + original_request_url_.is_valid() ? + original_request_url_.spec() : std::string()); + pickle->WriteBool(is_overriding_user_agent_); + + // TODO(akalin): Persist timestamp. } -TabNavigation& TabNavigation::operator=(const TabNavigation& tab) { - virtual_url_ = tab.virtual_url_; - referrer_ = tab.referrer_; - title_ = tab.title_; - state_ = tab.state_; - transition_ = tab.transition_; - type_mask_ = tab.type_mask_; - post_id_ = tab.post_id_; - index_ = tab.index_; - original_request_url_ = tab.original_request_url_; - is_overriding_user_agent_ = tab.is_overriding_user_agent_; - return *this; +bool TabNavigation::ReadFromPickle(PickleIterator* iterator) { + *this = TabNavigation(); + std::string virtual_url_spec; + int transition_type_int = 0; + if (!iterator->ReadInt(&index_) || + !iterator->ReadString(&virtual_url_spec) || + !iterator->ReadString16(&title_) || + !iterator->ReadString(&content_state_) || + !iterator->ReadInt(&transition_type_int)) + return false; + virtual_url_ = GURL(virtual_url_spec); + transition_type_ = static_cast<content::PageTransition>(transition_type_int); + + // type_mask did not always exist in the written stream. As such, we + // don't fail if it can't be read. + int type_mask = 0; + bool has_type_mask = iterator->ReadInt(&type_mask); + + if (has_type_mask) { + has_post_data_ = type_mask & HAS_POST_DATA; + // the "referrer" property was added after type_mask to the written + // stream. As such, we don't fail if it can't be read. + std::string referrer_spec; + if (!iterator->ReadString(&referrer_spec)) + referrer_spec = std::string(); + // The "referrer policy" property was added even later, so we fall back to + // the default policy if the property is not present. + int policy_int; + WebKit::WebReferrerPolicy policy; + if (iterator->ReadInt(&policy_int)) + policy = static_cast<WebKit::WebReferrerPolicy>(policy_int); + else + policy = WebKit::WebReferrerPolicyDefault; + referrer_ = content::Referrer(GURL(referrer_spec), policy); + + // If the original URL can't be found, leave it empty. + std::string original_request_url_spec; + if (!iterator->ReadString(&original_request_url_spec)) + original_request_url_spec = std::string(); + original_request_url_ = GURL(original_request_url_spec); + + // Default to not overriding the user agent if we don't have info. + if (!iterator->ReadBool(&is_overriding_user_agent_)) + is_overriding_user_agent_ = false; + } + + // TODO(akalin): Restore timestamp when it is persisted. + return true; } -// static -NavigationEntry* TabNavigation::ToNavigationEntry( - int page_id, Profile *profile) const { - NavigationEntry* entry = content::NavigationController::CreateNavigationEntry( - virtual_url_, - referrer_, - // Use a transition type of reload so that we don't incorrectly - // increase the typed count. - content::PAGE_TRANSITION_RELOAD, - false, - // The extra headers are not sync'ed across sessions. - std::string(), - profile); +scoped_ptr<NavigationEntry> TabNavigation::ToNavigationEntry( + int page_id, + content::BrowserContext* browser_context) const { + scoped_ptr<NavigationEntry> entry( + content::NavigationController::CreateNavigationEntry( + virtual_url_, + referrer_, + // Use a transition type of reload so that we don't incorrectly + // increase the typed count. + content::PAGE_TRANSITION_RELOAD, + false, + // The extra headers are not sync'ed across sessions. + std::string(), + browser_context)); - entry->SetPageID(page_id); entry->SetTitle(title_); - entry->SetContentState(state_); - entry->SetHasPostData(type_mask_ & TabNavigation::HAS_POST_DATA); + entry->SetContentState(content_state_); + entry->SetPageID(page_id); + entry->SetHasPostData(has_post_data_); entry->SetPostID(post_id_); entry->SetOriginalRequestURL(original_request_url_); entry->SetIsOverridingUserAgent(is_overriding_user_agent_); - return entry; + // TODO(akalin): Set |entry|'s timestamp once NavigationEntry has a + // field for it. + + return entry.Pass(); } -void TabNavigation::SetFromNavigationEntry(const NavigationEntry& entry) { - virtual_url_ = entry.GetVirtualURL(); - referrer_ = entry.GetReferrer(); - title_ = entry.GetTitle(); - state_ = entry.GetContentState(); - transition_ = entry.GetTransitionType(); - type_mask_ = entry.GetHasPostData() ? TabNavigation::HAS_POST_DATA : 0; - post_id_ = entry.GetPostID(); - original_request_url_ = entry.GetOriginalRequestURL(); - is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); +// TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? +// See http://crbug.com/67068. +sync_pb::TabNavigation TabNavigation::ToSyncData() const { + sync_pb::TabNavigation sync_data; + sync_data.set_virtual_url(virtual_url_.spec()); + // FIXME(zea): Support referrer policy? + sync_data.set_referrer(referrer_.url.spec()); + sync_data.set_title(UTF16ToUTF8(title_)); + switch (transition_type_) { + case content::PAGE_TRANSITION_LINK: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_LINK); + break; + case content::PAGE_TRANSITION_TYPED: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_TYPED); + break; + case content::PAGE_TRANSITION_AUTO_BOOKMARK: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK); + break; + case content::PAGE_TRANSITION_AUTO_SUBFRAME: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME); + break; + case content::PAGE_TRANSITION_MANUAL_SUBFRAME: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME); + break; + case content::PAGE_TRANSITION_GENERATED: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_GENERATED); + break; + case content::PAGE_TRANSITION_AUTO_TOPLEVEL: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL); + break; + case content::PAGE_TRANSITION_FORM_SUBMIT: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_FORM_SUBMIT); + break; + case content::PAGE_TRANSITION_RELOAD: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_RELOAD); + break; + case content::PAGE_TRANSITION_KEYWORD: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_KEYWORD); + break; + case content::PAGE_TRANSITION_KEYWORD_GENERATED: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED); + break; + case content::PAGE_TRANSITION_CHAIN_START: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_CHAIN_START); + break; + case content::PAGE_TRANSITION_CHAIN_END: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_CHAIN_END); + break; + case content::PAGE_TRANSITION_CLIENT_REDIRECT: + sync_data.set_navigation_qualifier( + sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT); + break; + case content::PAGE_TRANSITION_SERVER_REDIRECT: + sync_data.set_navigation_qualifier( + sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT); + break; + default: + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_TYPED); + } + sync_data.set_unique_id(unique_id_); + sync_data.set_timestamp(syncer::TimeToProtoTime(timestamp_)); + return sync_data; } // static -void TabNavigation::CreateNavigationEntriesFromTabNavigations( - Profile* profile, +std::vector<NavigationEntry*> +TabNavigation::CreateNavigationEntriesFromTabNavigations( const std::vector<TabNavigation>& navigations, - std::vector<NavigationEntry*>* entries) { + content::BrowserContext* browser_context) { int page_id = 0; - for (std::vector<TabNavigation>::const_iterator i = - navigations.begin(); i != navigations.end(); ++i, ++page_id) { - entries->push_back(i->ToNavigationEntry(page_id, profile)); + std::vector<NavigationEntry*> entries; + for (std::vector<TabNavigation>::const_iterator it = navigations.begin(); + it != navigations.end(); ++it) { + entries.push_back( + it->ToNavigationEntry(page_id, browser_context).release()); + ++page_id; } + return entries; } // SessionTab ----------------------------------------------------------------- diff --git a/chrome/browser/sessions/session_types.h b/chrome/browser/sessions/session_types.h index 0c3335b..dc9c7ba 100644 --- a/chrome/browser/sessions/session_types.h +++ b/chrome/browser/sessions/session_types.h @@ -8,119 +8,121 @@ #include <string> #include <vector> -#include "base/stl_util.h" +#include "base/memory/scoped_ptr.h" #include "base/string16.h" #include "base/time.h" #include "chrome/browser/sessions/session_id.h" #include "content/public/common/page_transition_types.h" #include "content/public/common/referrer.h" #include "googleurl/src/gurl.h" +#include "sync/protocol/session_specifics.pb.h" #include "ui/base/ui_base_types.h" #include "ui/gfx/rect.h" -class Profile; +class Pickle; +class PickleIterator; namespace content { +class BrowserContext; class NavigationEntry; } // TabNavigation ------------------------------------------------------------- -// TabNavigation corresponds to the parts of NavigationEntry needed to restore -// the NavigationEntry during session restore and tab restore. +// TabNavigation is a "freeze-dried" version of NavigationEntry. It +// contains the data needed to restore a NavigationEntry during +// session restore and tab restore, and it can also be pickled and +// unpickled. It is also convertible to a sync protocol buffer for +// session syncing. // -// TabNavigation is cheap and supports copy semantics. +// Default copy constructor and assignment operator welcome. class TabNavigation { public: - enum TypeMask { - HAS_POST_DATA = 1 - }; - + // Creates an invalid (index < 0) TabNavigation. TabNavigation(); - TabNavigation(int index, - const GURL& virtual_url, - const content::Referrer& referrer, - const string16& title, - const std::string& state, - content::PageTransition transition); - TabNavigation(const TabNavigation& tab); - virtual ~TabNavigation(); - TabNavigation& operator=(const TabNavigation& tab); - - // Converts this TabNavigation into a NavigationEntry with a page id of - // |page_id|. The caller owns the returned NavigationEntry. - content::NavigationEntry* ToNavigationEntry(int page_id, - Profile* profile) const; - - // Resets this TabNavigation from |entry|. - void SetFromNavigationEntry(const content::NavigationEntry& entry); - - // Virtual URL of the page. See NavigationEntry::GetVirtualURL() for details. - void set_virtual_url(const GURL& url) { virtual_url_ = url; } - const GURL& virtual_url() const { return virtual_url_; } - - // The referrer. - const content::Referrer& referrer() const { return referrer_; } - - // The title of the page. - void set_title(const string16& title) { title_ = title; } - const string16& title() const { return title_; } - - // State bits. - const std::string& state() const { return state_; } + ~TabNavigation(); - // Transition type. - void set_transition(content::PageTransition transition) { - transition_ = transition; - } - content::PageTransition transition() const { return transition_; } - - // A mask used for arbitrary boolean values needed to represent a - // NavigationEntry. Currently only contains HAS_POST_DATA or 0. - void set_type_mask(int type_mask) { type_mask_ = type_mask; } - int type_mask() const { return type_mask_; } - - // The index in the NavigationController. If this is -1, it means this - // TabNavigation is bogus. + // Construct a TabNavigation for a particular index from a + // NavigationEntry with the given timestamp. // - // This is used when determining the selected TabNavigation and only useful - // by BaseSessionService and SessionService. - void set_index(int index) { index_ = index; } + // TODO(akalin): Add a timestamp field to + // navigation::NavigationEntry and use that instead of passing a + // separate timestamp. + static TabNavigation FromNavigationEntry( + int index, + const content::NavigationEntry& entry, + base::Time timestamp); + + // Construct a TabNavigation for a particular index from a sync + // protocol buffer. Note that the sync protocol buffer doesn't + // contain all TabNavigation fields. + static TabNavigation FromSyncData( + int index, + const sync_pb::TabNavigation& specifics); + + // Note that not all TabNavigation fields are preserved. + void WriteToPickle(Pickle* pickle) const; + bool ReadFromPickle(PickleIterator* iterator); + + // Convert this TabNavigation into a NavigationEntry with the given + // page ID and context. The NavigationEntry will have a transition + // type of PAGE_TRANSITION_RELOAD and a new unique ID. + scoped_ptr<content::NavigationEntry> ToNavigationEntry( + int page_id, + content::BrowserContext* browser_context) const; + + // Convert this navigation into its sync protocol buffer equivalent. + // Note that the protocol buffer doesn't contain all TabNavigation + // fields. + sync_pb::TabNavigation ToSyncData() const; + + // The index in the NavigationController. This TabNavigation is + // valid only when the index is non-negative. + // + // This is used when determining the selected TabNavigation and only + // used by SessionService. int index() const { return index_; } + void set_index(int index) { index_ = index; } - // The URL that initially spawned the NavigationEntry. - const GURL& original_request_url() const { return original_request_url_; } - void set_original_request_url(const GURL& url) { - original_request_url_ = url; - } + // Accessors for some fields taken from NavigationEntry. + int unique_id() const { return unique_id_; } + const GURL& virtual_url() const { return virtual_url_; } + const string16& title() const { return title_; } + const std::string& content_state() const { return content_state_; } - // Whether or not we're overriding the standard user agent. - bool is_overriding_user_agent() const { return is_overriding_user_agent_; } - void set_is_overriding_user_agent(bool state) { - is_overriding_user_agent_ = state; - } + // Timestamp this navigation occurred. + base::Time timestamp() const { return timestamp_; } - // Converts a set of TabNavigations into a set of NavigationEntrys. The - // caller owns the NavigationEntrys. - static void CreateNavigationEntriesFromTabNavigations( - Profile* profile, + // Converts a set of TabNavigations into a list of NavigationEntrys + // with sequential page IDs and the given context. The caller owns + // the returned NavigationEntrys. + static std::vector<content::NavigationEntry*> + CreateNavigationEntriesFromTabNavigations( const std::vector<TabNavigation>& navigations, - std::vector<content::NavigationEntry*>* entries); + content::BrowserContext* browser_context); private: - friend class BaseSessionService; + friend struct SessionTypesTestHelper; - GURL virtual_url_; + // Index in the NavigationController. + int index_; + + // Member variables corresponding to NavigationEntry fields. + int unique_id_; content::Referrer referrer_; + GURL virtual_url_; string16 title_; - std::string state_; - content::PageTransition transition_; - int type_mask_; + std::string content_state_; + content::PageTransition transition_type_; + bool has_post_data_; int64 post_id_; - - int index_; GURL original_request_url_; bool is_overriding_user_agent_; + + // Timestamp when the navigation occurred. + // + // TODO(akalin): Add a timestamp field to NavigationEntry. + base::Time timestamp_; }; // SessionTab ---------------------------------------------------------------- diff --git a/chrome/browser/sessions/session_types_test_helper.cc b/chrome/browser/sessions/session_types_test_helper.cc new file mode 100644 index 0000000..f2201e4 --- /dev/null +++ b/chrome/browser/sessions/session_types_test_helper.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "chrome/browser/sessions/session_types_test_helper.h" + +#include "base/basictypes.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/sessions/session_types.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h" + +void SessionTypesTestHelper::ExpectNavigationEquals( + const TabNavigation& expected, + const TabNavigation& actual) { + EXPECT_EQ(expected.referrer_.url, actual.referrer_.url); + EXPECT_EQ(expected.referrer_.policy, actual.referrer_.policy); + EXPECT_EQ(expected.virtual_url_, actual.virtual_url_); + EXPECT_EQ(expected.title_, actual.title_); + EXPECT_EQ(expected.content_state_, actual.content_state_); + EXPECT_EQ(expected.transition_type_, actual.transition_type_); + EXPECT_EQ(expected.has_post_data_, actual.has_post_data_); + EXPECT_EQ(expected.original_request_url_, actual.original_request_url_); + EXPECT_EQ(expected.is_overriding_user_agent_, + actual.is_overriding_user_agent_); +} + +TabNavigation SessionTypesTestHelper::CreateNavigation( + const std::string& virtual_url, + const std::string& title) { + TabNavigation navigation; + navigation.index_ = 0; + navigation.referrer_ = + content::Referrer(GURL("http://www.referrer.com"), + WebKit::WebReferrerPolicyDefault); + navigation.virtual_url_ = GURL(virtual_url); + navigation.title_ = UTF8ToUTF16(title); + navigation.content_state_ = "fake_state"; + navigation.timestamp_ = base::Time::Now(); + return navigation; +} + +const content::Referrer& SessionTypesTestHelper::GetReferrer( + const TabNavigation& navigation) { + return navigation.referrer_; +} + +content::PageTransition SessionTypesTestHelper::GetTransitionType( + const TabNavigation& navigation) { + return navigation.transition_type_; +} + +bool SessionTypesTestHelper::GetHasPostData(const TabNavigation& navigation) { + return navigation.has_post_data_; +} + +int64 SessionTypesTestHelper::GetPostID(const TabNavigation& navigation) { + return navigation.post_id_; +} + +const GURL& SessionTypesTestHelper::GetOriginalRequestURL( + const TabNavigation& navigation) { + return navigation.original_request_url_; +} + +bool SessionTypesTestHelper::GetIsOverridingUserAgent( + const TabNavigation& navigation) { + return navigation.is_overriding_user_agent_; +} + +void SessionTypesTestHelper::SetContentState( + TabNavigation* navigation, + const std::string& content_state) { + navigation->content_state_ = content_state; +} + +void SessionTypesTestHelper::SetHasPostData(TabNavigation* navigation, + bool has_post_data) { + navigation->has_post_data_ = has_post_data; +} + +void SessionTypesTestHelper::SetOriginalRequestURL( + TabNavigation* navigation, + const GURL& original_request_url) { + navigation->original_request_url_ = original_request_url; +} + +void SessionTypesTestHelper::SetIsOverridingUserAgent( + TabNavigation* navigation, + bool is_overriding_user_agent) { + navigation->is_overriding_user_agent_ = is_overriding_user_agent; +} diff --git a/chrome/browser/sessions/session_types_test_helper.h b/chrome/browser/sessions/session_types_test_helper.h new file mode 100644 index 0000000..50eb2e3 --- /dev/null +++ b/chrome/browser/sessions/session_types_test_helper.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SESSIONS_SESSION_TYPES_TEST_HELPER_H_ +#define CHROME_BROWSER_SESSIONS_SESSION_TYPES_TEST_HELPER_H_ + +#include <string> + +#include "content/public/common/page_transition_types.h" + +class GURL; +class TabNavigation; + +namespace content { +struct Referrer; +} + +struct SessionTypesTestHelper { + // Compares everything except index, unique ID, post ID, and + // timestamp. + static void ExpectNavigationEquals(const TabNavigation& expected, + const TabNavigation& actual); + + // Create a TabNavigation with the given URL and title and some + // common values for the other fields. + static TabNavigation CreateNavigation(const std::string& virtual_url, + const std::string& title); + + // Getters. + + static const content::Referrer& GetReferrer(const TabNavigation& navigation); + + static content::PageTransition GetTransitionType( + const TabNavigation& navigation); + + static bool GetHasPostData(const TabNavigation& navigation); + + static int64 GetPostID(const TabNavigation& navigation); + + static const GURL& GetOriginalRequestURL(const TabNavigation& navigation); + + static bool GetIsOverridingUserAgent(const TabNavigation& navigation); + + // Setters. + + static void SetContentState(TabNavigation* navigation, + const std::string& content_state); + + static void SetHasPostData(TabNavigation* navigation, + bool has_post_data); + + static void SetOriginalRequestURL(TabNavigation* navigation, + const GURL& original_request_url); + + static void SetIsOverridingUserAgent(TabNavigation* navigation, + bool is_overriding_user_agent); +}; + +#endif // CHROME_BROWSER_SESSIONS_SESSION_TYPES_TEST_HELPER_H_ diff --git a/chrome/browser/sessions/session_types_unittest.cc b/chrome/browser/sessions/session_types_unittest.cc new file mode 100644 index 0000000..0e8030b --- /dev/null +++ b/chrome/browser/sessions/session_types_unittest.cc @@ -0,0 +1,246 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <cstddef> +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/pickle.h" +#include "base/string16.h" +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/common/page_transition_types.h" +#include "content/public/common/referrer.h" +#include "googleurl/src/gurl.h" +#include "sync/protocol/session_specifics.pb.h" +#include "sync/util/time.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h" + +namespace { + +const int kIndex = 3; +const int kUniqueID = 50; +const content::Referrer kReferrer = + content::Referrer(GURL("http://www.referrer.com"), + WebKit::WebReferrerPolicyAlways); +const GURL kVirtualURL("http://www.virtual-url.com"); +const string16 kTitle = ASCIIToUTF16("title"); +const std::string kContentState = "content state"; +const content::PageTransition kTransitionType = + content::PAGE_TRANSITION_AUTO_SUBFRAME; +const bool kHasPostData = true; +const int64 kPostID = 100; +const GURL kOriginalRequestURL("http://www.original-request.com"); +const bool kIsOverridingUserAgent = true; +const base::Time kTimestamp = syncer::ProtoTimeToTime(100); + +const int kPageID = 10; + +// Create a NavigationEntry from the constants above. +scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() { + scoped_ptr<content::NavigationEntry> navigation_entry( + content::NavigationEntry::Create()); + navigation_entry->SetReferrer(kReferrer); + navigation_entry->SetVirtualURL(kVirtualURL); + navigation_entry->SetTitle(kTitle); + navigation_entry->SetContentState(kContentState); + navigation_entry->SetTransitionType(kTransitionType); + navigation_entry->SetHasPostData(kHasPostData); + navigation_entry->SetPostID(kPostID); + navigation_entry->SetOriginalRequestURL(kOriginalRequestURL); + navigation_entry->SetIsOverridingUserAgent(kIsOverridingUserAgent); + return navigation_entry.Pass(); +} + +// Create a sync_pb::TabNavigation from the constants above. +sync_pb::TabNavigation MakeSyncDataForTest() { + sync_pb::TabNavigation sync_data; + sync_data.set_virtual_url(kVirtualURL.spec()); + sync_data.set_referrer(kReferrer.url.spec()); + sync_data.set_title(UTF16ToUTF8(kTitle)); + sync_data.set_state(kContentState); + sync_data.set_page_transition( + sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME); + sync_data.set_unique_id(kUniqueID); + sync_data.set_timestamp(syncer::TimeToProtoTime(kTimestamp)); + return sync_data; +} + +// Create a default TabNavigation. All its fields should be +// initialized to their respective default values. +TEST(TabNavigationTest, DefaultInitializer) { + const TabNavigation navigation; + EXPECT_EQ(-1, navigation.index()); + EXPECT_EQ(0, navigation.unique_id()); + EXPECT_EQ(GURL(), SessionTypesTestHelper::GetReferrer(navigation).url); + EXPECT_EQ(WebKit::WebReferrerPolicyDefault, + SessionTypesTestHelper::GetReferrer(navigation).policy); + EXPECT_EQ(GURL(), navigation.virtual_url()); + EXPECT_TRUE(navigation.title().empty()); + EXPECT_TRUE(navigation.content_state().empty()); + EXPECT_EQ(content::PAGE_TRANSITION_TYPED, + SessionTypesTestHelper::GetTransitionType(navigation)); + EXPECT_FALSE(SessionTypesTestHelper::GetHasPostData(navigation)); + EXPECT_EQ(-1, SessionTypesTestHelper::GetPostID(navigation)); + EXPECT_EQ(GURL(), SessionTypesTestHelper::GetOriginalRequestURL(navigation)); + EXPECT_FALSE(SessionTypesTestHelper::GetIsOverridingUserAgent(navigation)); + EXPECT_EQ(base::Time(), navigation.timestamp()); +} + +// Create a TabNavigation from a NavigationEntry. All its fields +// should match the NavigationEntry's. +TEST(TabNavigationTest, FromNavigationEntry) { + const scoped_ptr<content::NavigationEntry> navigation_entry( + MakeNavigationEntryForTest()); + + const TabNavigation& navigation = + TabNavigation::FromNavigationEntry( + kIndex, *navigation_entry, kTimestamp); + + EXPECT_EQ(kIndex, navigation.index()); + + EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id()); + EXPECT_EQ(kReferrer.url, + SessionTypesTestHelper::GetReferrer(navigation).url); + EXPECT_EQ(kReferrer.policy, + SessionTypesTestHelper::GetReferrer(navigation).policy); + EXPECT_EQ(kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(kTitle, navigation.title()); + EXPECT_EQ(kContentState, navigation.content_state()); + EXPECT_EQ(kTransitionType, + SessionTypesTestHelper::GetTransitionType(navigation)); + EXPECT_EQ(kHasPostData, SessionTypesTestHelper::GetHasPostData(navigation)); + EXPECT_EQ(kPostID, SessionTypesTestHelper::GetPostID(navigation)); + EXPECT_EQ(kOriginalRequestURL, + SessionTypesTestHelper::GetOriginalRequestURL(navigation)); + EXPECT_EQ(kIsOverridingUserAgent, + SessionTypesTestHelper::GetIsOverridingUserAgent(navigation)); + EXPECT_EQ(kTimestamp, navigation.timestamp()); +} + +// Create a TabNavigation from a sync_pb::TabNavigation. All its +// fields should match the protocol buffer's if it exists there, and +// sbould be set to the default value otherwise. +TEST(TabNavigationTest, FromSyncData) { + const sync_pb::TabNavigation sync_data = MakeSyncDataForTest(); + + const TabNavigation& navigation = + TabNavigation::FromSyncData(kIndex, sync_data); + + EXPECT_EQ(kIndex, navigation.index()); + EXPECT_EQ(kUniqueID, navigation.unique_id()); + EXPECT_EQ(kReferrer.url, + SessionTypesTestHelper::GetReferrer(navigation).url); + EXPECT_EQ(WebKit::WebReferrerPolicyDefault, + SessionTypesTestHelper::GetReferrer(navigation).policy); + EXPECT_EQ(kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(kTitle, navigation.title()); + EXPECT_EQ(kContentState, navigation.content_state()); + EXPECT_EQ(kTransitionType, + SessionTypesTestHelper::GetTransitionType(navigation)); + EXPECT_FALSE(SessionTypesTestHelper::GetHasPostData(navigation)); + EXPECT_EQ(-1, SessionTypesTestHelper::GetPostID(navigation)); + EXPECT_EQ(GURL(), SessionTypesTestHelper::GetOriginalRequestURL(navigation)); + EXPECT_FALSE(SessionTypesTestHelper::GetIsOverridingUserAgent(navigation)); + EXPECT_EQ(kTimestamp, navigation.timestamp()); +} + +// Create a TabNavigation, pickle it, then create another one by +// unpickling. The new one should match the old one except for fields +// that aren't pickled, which should be set to default values. +TEST(TabNavigationTest, Pickle) { + const TabNavigation& old_navigation = + TabNavigation::FromNavigationEntry( + kIndex, *MakeNavigationEntryForTest(), kTimestamp); + + Pickle pickle; + old_navigation.WriteToPickle(&pickle); + + TabNavigation new_navigation; + PickleIterator pickle_iterator(pickle); + EXPECT_TRUE(new_navigation.ReadFromPickle(&pickle_iterator)); + + EXPECT_EQ(kIndex, new_navigation.index()); + + EXPECT_EQ(0, new_navigation.unique_id()); + EXPECT_EQ(kReferrer.url, + SessionTypesTestHelper::GetReferrer(new_navigation).url); + EXPECT_EQ(kReferrer.policy, + SessionTypesTestHelper::GetReferrer(new_navigation).policy); + EXPECT_EQ(kVirtualURL, new_navigation.virtual_url()); + EXPECT_EQ(kTitle, new_navigation.title()); + EXPECT_TRUE(new_navigation.content_state().empty()); + EXPECT_EQ(kTransitionType, + SessionTypesTestHelper::GetTransitionType(new_navigation)); + EXPECT_EQ(kHasPostData, + SessionTypesTestHelper::GetHasPostData(new_navigation)); + EXPECT_EQ(-1, SessionTypesTestHelper::GetPostID(new_navigation)); + EXPECT_EQ(kOriginalRequestURL, + SessionTypesTestHelper::GetOriginalRequestURL(new_navigation)); + EXPECT_EQ(kIsOverridingUserAgent, + SessionTypesTestHelper::GetIsOverridingUserAgent(new_navigation)); + EXPECT_EQ(base::Time(), new_navigation.timestamp()); +} + +// Create a NavigationEntry, then create another one by converting to +// a TabNavigation and back. The new one should match the old one +// except for fields that aren't preserved, which should be set to +// expected values. +TEST(TabNavigationTest, ToNavigationEntry) { + const scoped_ptr<content::NavigationEntry> old_navigation_entry( + MakeNavigationEntryForTest()); + + const TabNavigation& navigation = + TabNavigation::FromNavigationEntry( + kIndex, *old_navigation_entry, kTimestamp); + + const scoped_ptr<content::NavigationEntry> new_navigation_entry( + navigation.ToNavigationEntry(kPageID, NULL)); + + EXPECT_EQ(kReferrer.url, new_navigation_entry->GetReferrer().url); + EXPECT_EQ(kReferrer.policy, new_navigation_entry->GetReferrer().policy); + EXPECT_EQ(kVirtualURL, new_navigation_entry->GetVirtualURL()); + EXPECT_EQ(kTitle, new_navigation_entry->GetTitle()); + EXPECT_EQ(kContentState, new_navigation_entry->GetContentState()); + EXPECT_EQ(kPageID, new_navigation_entry->GetPageID()); + EXPECT_EQ(content::PAGE_TRANSITION_RELOAD, + new_navigation_entry->GetTransitionType()); + EXPECT_EQ(kHasPostData, new_navigation_entry->GetHasPostData()); + EXPECT_EQ(kPostID, new_navigation_entry->GetPostID()); + EXPECT_EQ(kOriginalRequestURL, + new_navigation_entry->GetOriginalRequestURL()); + EXPECT_EQ(kIsOverridingUserAgent, + new_navigation_entry->GetIsOverridingUserAgent()); +} + +// Create a NavigationEntry, convert it to a TabNavigation, then +// create a sync protocol buffer from it. The protocol buffer should +// have matching fields to the NavigationEntry (when applicable). +TEST(TabNavigationTest, ToSyncData) { + const scoped_ptr<content::NavigationEntry> navigation_entry( + MakeNavigationEntryForTest()); + + const TabNavigation& navigation = + TabNavigation::FromNavigationEntry( + kIndex, *navigation_entry, kTimestamp); + + const sync_pb::TabNavigation sync_data = navigation.ToSyncData(); + + EXPECT_EQ(kVirtualURL.spec(), sync_data.virtual_url()); + EXPECT_EQ(kReferrer.url.spec(), sync_data.referrer()); + EXPECT_EQ(kTitle, ASCIIToUTF16(sync_data.title())); + EXPECT_TRUE(sync_data.state().empty()); + EXPECT_EQ(sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME, + sync_data.page_transition()); + EXPECT_FALSE(sync_data.has_navigation_qualifier()); + EXPECT_EQ(navigation_entry->GetUniqueID(), sync_data.unique_id()); + EXPECT_EQ(syncer::TimeToProtoTime(kTimestamp), sync_data.timestamp()); +} + +} // namespace diff --git a/chrome/browser/sessions/tab_restore_service.cc b/chrome/browser/sessions/tab_restore_service.cc index 19f5ada..cb7b68f 100644 --- a/chrome/browser/sessions/tab_restore_service.cc +++ b/chrome/browser/sessions/tab_restore_service.cc @@ -17,9 +17,9 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sessions/session_command.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" -#include "chrome/browser/sessions/session_command.h" #include "chrome/browser/sessions/session_types.h" #include "chrome/browser/sessions/tab_restore_service_delegate.h" #include "chrome/browser/sessions/tab_restore_service_observer.h" @@ -529,7 +529,8 @@ void TabRestoreService::PopulateTab(Tab* tab, for (int i = 0; i < entry_count; ++i) { NavigationEntry* entry = (i == pending_index) ? controller->GetPendingEntry() : controller->GetEntryAtIndex(i); - tab->navigations[i].SetFromNavigationEntry(*entry); + tab->navigations[i] = + TabNavigation::FromNavigationEntry(i, *entry, base::Time::Now()); } tab->timestamp = TimeNow(); tab->current_navigation_index = controller->GetCurrentEntryIndex(); @@ -708,14 +709,9 @@ void TabRestoreService::ScheduleCommandsForTab(const Tab& tab, for (int i = first_index_to_persist, wrote_count = 0; i < max_index && wrote_count < 2 * max_persist_navigation_count; ++i) { if (ShouldTrackEntry(navigations[i].virtual_url())) { - // Creating a NavigationEntry isn't the most efficient way to go about - // this, but it simplifies the code and makes it less error prone as we - // add new data to NavigationEntry. - scoped_ptr<NavigationEntry> entry( - navigations[i].ToNavigationEntry(wrote_count, profile())); ScheduleCommand( CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, tab.id, - wrote_count++, *entry)); + navigations[i])); } } } diff --git a/chrome/browser/sessions/tab_restore_service_browsertest.cc b/chrome/browser/sessions/tab_restore_service_browsertest.cc index cd1d4ba..17ee22e 100644 --- a/chrome/browser/sessions/tab_restore_service_browsertest.cc +++ b/chrome/browser/sessions/tab_restore_service_browsertest.cc @@ -4,9 +4,10 @@ #include "base/stringprintf.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/session_service.h" +#include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/ui/browser_window.h" @@ -119,9 +120,9 @@ class TabRestoreServiceTest : public ChromeRenderViewHostTestHarness { session_service->SetSelectedTabInWindow(window_id, 0); if (pinned) session_service->SetPinnedState(window_id, tab_id, true); - scoped_ptr<NavigationEntry> entry(NavigationEntry::Create()); - entry->SetURL(url1_); - session_service->UpdateTabNavigation(window_id, tab_id, 0, *entry.get()); + session_service->UpdateTabNavigation( + window_id, tab_id, + SessionTypesTestHelper::CreateNavigation(url1_.spec(), "title")); } // Creates a SessionService and assigns it to the Profile. The SessionService @@ -557,10 +558,10 @@ TEST_F(TabRestoreServiceTest, PruneEntries) { const size_t max_entries = TabRestoreService::kMaxEntries; for (size_t i = 0; i < max_entries + 5; i++) { - TabNavigation navigation; - navigation.set_virtual_url(GURL(StringPrintf("http://%d", - static_cast<int>(i)))); - navigation.set_title(ASCIIToUTF16(StringPrintf("%d", static_cast<int>(i)))); + TabNavigation navigation = + SessionTypesTestHelper::CreateNavigation( + StringPrintf("http://%d", static_cast<int>(i)), + StringPrintf("%d", static_cast<int>(i))); Tab* tab = new Tab(); tab->navigations.push_back(navigation); @@ -578,10 +579,9 @@ TEST_F(TabRestoreServiceTest, PruneEntries) { EXPECT_EQ(max_entries, service_->entries_.size()); // Prune older first. - TabNavigation navigation; const char kRecentUrl[] = "http://recent"; - navigation.set_virtual_url(GURL(kRecentUrl)); - navigation.set_title(ASCIIToUTF16("Most recent")); + TabNavigation navigation = + SessionTypesTestHelper::CreateNavigation(kRecentUrl, "Most recent"); Tab* tab = new Tab(); tab->navigations.push_back(navigation); tab->current_navigation_index = 0; @@ -594,8 +594,9 @@ TEST_F(TabRestoreServiceTest, PruneEntries) { navigations[0].virtual_url()); // Ignore NTPs. - navigation.set_virtual_url(GURL(chrome::kChromeUINewTabURL)); - navigation.set_title(ASCIIToUTF16("New tab")); + navigation = + SessionTypesTestHelper::CreateNavigation( + chrome::kChromeUINewTabURL, "New tab"); tab = new Tab(); tab->navigations.push_back(navigation); diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc index 0457f72..92e7557 100644 --- a/chrome/browser/sync/glue/session_model_associator.cc +++ b/chrome/browser/sync/glue/session_model_associator.cc @@ -256,7 +256,7 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, // change processor calling AssociateTab for all modified tabs. // Therefore, we can key whether this window has valid tabs based on // the tab's presence in the tracker. - const SyncedSessionTab* tab; + const SessionTab* tab = NULL; if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { found_tabs = true; window_s.add_tab(tab_id); @@ -385,7 +385,7 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( // Load the last stored version of this tab so we can compare changes. If this // is a new tab, session_tab will be a blank/newly created SessionTab object. - SyncedSessionTab* session_tab = + SessionTab* session_tab = synced_session_tracker_.GetTab(GetCurrentMachineTag(), tab.GetSessionId()); @@ -453,7 +453,7 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( void SessionModelAssociator::AssociateTabContents( const SyncedWindowDelegate& window, const SyncedTabDelegate& new_tab, - SyncedSessionTab* prev_tab, + SessionTab* prev_tab, sync_pb::SessionTab* sync_tab, GURL* new_url) { DCHECK(prev_tab); @@ -475,8 +475,8 @@ void SessionModelAssociator::AssociateTabContents( } sync_tab->mutable_navigation()->Clear(); - std::vector<SyncedTabNavigation>::const_iterator prev_nav_iter = - prev_tab->synced_tab_navigations.begin(); + std::vector<TabNavigation>::const_iterator prev_nav_iter = + prev_tab->navigations.begin(); for (int i = min_index; i < max_index; ++i) { const NavigationEntry* entry = (i == pending_index) ? new_tab.GetPendingEntry() : new_tab.GetEntryAtIndex(i); @@ -485,7 +485,7 @@ void SessionModelAssociator::AssociateTabContents( // Find the location of the first navigation within the previous list of // navigations. We only need to do this once, as all subsequent // navigations are either contiguous or completely new. - for (;prev_nav_iter != prev_tab->synced_tab_navigations.end(); + for (;prev_nav_iter != prev_tab->navigations.end(); ++prev_nav_iter) { if (prev_nav_iter->unique_id() == entry->GetUniqueID()) break; @@ -500,11 +500,13 @@ void SessionModelAssociator::AssociateTabContents( } sync_pb::TabNavigation* sync_nav = sync_tab->add_navigation(); - PopulateSessionSpecificsNavigation(*entry, sync_nav); + const TabNavigation& navigation = + TabNavigation::FromNavigationEntry(i, *entry, base::Time::Now()); + *sync_nav = navigation.ToSyncData(); // If this navigation is an old one, reuse the old timestamp. Otherwise we // leave the timestamp as the current time. - if (prev_nav_iter != prev_tab->synced_tab_navigations.end() && + if (prev_nav_iter != prev_tab->navigations.end() && prev_nav_iter->unique_id() == entry->GetUniqueID()) { // Check that we haven't gone back/foward in the nav stack to this page // (if so, we want to refresh the timestamp). @@ -520,7 +522,7 @@ void SessionModelAssociator::AssociateTabContents( // old timestamps preserved. ++prev_nav_iter; } else if (current_index != i && - prev_tab->synced_tab_navigations.empty()) { + prev_tab->navigations.empty()) { // If this is a new tab, and has more than one navigation, we don't // actually want to assign the current timestamp to other navigations. // Override the timestamp to 0 in that case. @@ -647,86 +649,6 @@ void SessionModelAssociator::FaviconsUpdated( } } -// Static -// TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? -// See http://crbug.com/67068. -void SessionModelAssociator::PopulateSessionSpecificsNavigation( - const NavigationEntry& navigation, - sync_pb::TabNavigation* tab_navigation) { - tab_navigation->set_virtual_url(navigation.GetVirtualURL().spec()); - // FIXME(zea): Support referrer policy? - tab_navigation->set_referrer(navigation.GetReferrer().url.spec()); - tab_navigation->set_title(UTF16ToUTF8(navigation.GetTitle())); - switch (navigation.GetTransitionType()) { - case content::PAGE_TRANSITION_LINK: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_LINK); - break; - case content::PAGE_TRANSITION_TYPED: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_TYPED); - break; - case content::PAGE_TRANSITION_AUTO_BOOKMARK: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK); - break; - case content::PAGE_TRANSITION_AUTO_SUBFRAME: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME); - break; - case content::PAGE_TRANSITION_MANUAL_SUBFRAME: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME); - break; - case content::PAGE_TRANSITION_GENERATED: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_GENERATED); - break; - case content::PAGE_TRANSITION_AUTO_TOPLEVEL: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL); - break; - case content::PAGE_TRANSITION_FORM_SUBMIT: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_FORM_SUBMIT); - break; - case content::PAGE_TRANSITION_RELOAD: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_RELOAD); - break; - case content::PAGE_TRANSITION_KEYWORD: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_KEYWORD); - break; - case content::PAGE_TRANSITION_KEYWORD_GENERATED: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED); - break; - case content::PAGE_TRANSITION_CHAIN_START: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_CHAIN_START); - break; - case content::PAGE_TRANSITION_CHAIN_END: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_CHAIN_END); - break; - case content::PAGE_TRANSITION_CLIENT_REDIRECT: - tab_navigation->set_navigation_qualifier( - sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT); - break; - case content::PAGE_TRANSITION_SERVER_REDIRECT: - tab_navigation->set_navigation_qualifier( - sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT); - break; - default: - tab_navigation->set_page_transition( - sync_pb::SyncEnums_PageTransition_TYPED); - } - tab_navigation->set_unique_id(navigation.GetUniqueID()); - tab_navigation->set_timestamp( - syncer::TimeToProtoTime(base::Time::Now())); -} - void SessionModelAssociator::Associate(const SyncedTabDelegate* tab, int64 sync_id) { NOTIMPLEMENTED(); @@ -1026,7 +948,7 @@ void SessionModelAssociator::AssociateForeignSpecifics( } else if (specifics.has_tab()) { const sync_pb::SessionTab& tab_s = specifics.tab(); SessionID::id_type tab_id = tab_s.tab_id(); - SyncedSessionTab* tab = + SessionTab* tab = synced_session_tracker_.GetTab(foreign_session_tag, tab_id); // Figure out what the previous url for this tab was (may be empty string @@ -1185,7 +1107,7 @@ void SessionModelAssociator::PopulateSessionWindowFromSpecifics( void SessionModelAssociator::PopulateSessionTabFromSpecifics( const sync_pb::SessionTab& specifics, const base::Time& mtime, - SyncedSessionTab* tab) { + SessionTab* tab) { DCHECK_EQ(tab->tab_id.id(), specifics.tab_id()); if (specifics.has_tab_id()) tab->tab_id.set_id(specifics.tab_id()); @@ -1202,108 +1124,10 @@ void SessionModelAssociator::PopulateSessionTabFromSpecifics( tab->timestamp = mtime; // Cleared in case we reuse a pre-existing SyncedSessionTab object. tab->navigations.clear(); - tab->synced_tab_navigations.clear(); for (int i = 0; i < specifics.navigation_size(); ++i) { - AppendSessionTabNavigation(specifics.navigation(i), - tab); - } -} - -// Static -void SessionModelAssociator::AppendSessionTabNavigation( - const sync_pb::TabNavigation& specifics, - SyncedSessionTab* tab) { - int index = 0; - GURL virtual_url; - GURL referrer; - string16 title; - std::string state; - content::PageTransition transition(content::PAGE_TRANSITION_LINK); - base::Time timestamp; - int unique_id = 0; - if (specifics.has_virtual_url()) { - GURL gurl(specifics.virtual_url()); - virtual_url = gurl; - } - if (specifics.has_referrer()) { - GURL gurl(specifics.referrer()); - referrer = gurl; - } - if (specifics.has_title()) - title = UTF8ToUTF16(specifics.title()); - if (specifics.has_state()) - state = specifics.state(); - if (specifics.has_page_transition() || - specifics.has_navigation_qualifier()) { - switch (specifics.page_transition()) { - case sync_pb::SyncEnums_PageTransition_LINK: - transition = content::PAGE_TRANSITION_LINK; - break; - case sync_pb::SyncEnums_PageTransition_TYPED: - transition = content::PAGE_TRANSITION_TYPED; - break; - case sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK: - transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; - break; - case sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME: - transition = content::PAGE_TRANSITION_AUTO_SUBFRAME; - break; - case sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME: - transition = content::PAGE_TRANSITION_MANUAL_SUBFRAME; - break; - case sync_pb::SyncEnums_PageTransition_GENERATED: - transition = content::PAGE_TRANSITION_GENERATED; - break; - case sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL: - transition = content::PAGE_TRANSITION_AUTO_TOPLEVEL; - break; - case sync_pb::SyncEnums_PageTransition_FORM_SUBMIT: - transition = content::PAGE_TRANSITION_FORM_SUBMIT; - break; - case sync_pb::SyncEnums_PageTransition_RELOAD: - transition = content::PAGE_TRANSITION_RELOAD; - break; - case sync_pb::SyncEnums_PageTransition_KEYWORD: - transition = content::PAGE_TRANSITION_KEYWORD; - break; - case sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED: - transition = content::PAGE_TRANSITION_KEYWORD_GENERATED; - break; - case sync_pb::SyncEnums_PageTransition_CHAIN_START: - transition = content::PAGE_TRANSITION_CHAIN_START; - break; - case sync_pb::SyncEnums_PageTransition_CHAIN_END: - transition = content::PAGE_TRANSITION_CHAIN_END; - break; - default: - switch (specifics.navigation_qualifier()) { - case sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT: - transition = content::PAGE_TRANSITION_CLIENT_REDIRECT; - break; - case sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT: - transition = content::PAGE_TRANSITION_SERVER_REDIRECT; - break; - default: - transition = content::PAGE_TRANSITION_TYPED; - } - } - } - if (specifics.has_timestamp()) { - timestamp = syncer::ProtoTimeToTime(specifics.timestamp()); - } - if (specifics.has_unique_id()) { - unique_id = specifics.unique_id(); + tab->navigations.push_back( + TabNavigation::FromSyncData(i, specifics.navigation(i))); } - SyncedTabNavigation tab_navigation( - index, virtual_url, - content::Referrer(referrer, WebKit::WebReferrerPolicyDefault), title, - state, transition, unique_id, timestamp); - // We insert it twice, once for our SyncedTabNavigations, once for the normal - // TabNavigation (used by the session restore UI). - tab->synced_tab_navigations.insert(tab->synced_tab_navigations.end(), - tab_navigation); - tab->navigations.insert(tab->navigations.end(), - tab_navigation); } void SessionModelAssociator::LoadForeignTabFavicon( @@ -1450,7 +1274,7 @@ bool SessionModelAssociator::GetForeignTab( const SessionID::id_type tab_id, const SessionTab** tab) { DCHECK(CalledOnValidThread()); - const SyncedSessionTab* synced_tab; + const SessionTab* synced_tab = NULL; bool success = synced_session_tracker_.LookupSessionTab(tag, tab_id, &synced_tab); diff --git a/chrome/browser/sync/glue/session_model_associator.h b/chrome/browser/sync/glue/session_model_associator.h index 76a1fb8..577b7cf 100644 --- a/chrome/browser/sync/glue/session_model_associator.h +++ b/chrome/browser/sync/glue/session_model_associator.h @@ -422,7 +422,7 @@ class SessionModelAssociator // |new_url| will be the tab's current url. void AssociateTabContents(const SyncedWindowDelegate& window, const SyncedTabDelegate& new_tab, - SyncedSessionTab* prev_tab, + SessionTab* prev_tab, sync_pb::SessionTab* sync_tab, GURL* new_url); @@ -456,23 +456,13 @@ class SessionModelAssociator // Used to populate a session tab from the session specifics tab provided. static void PopulateSessionTabFromSpecifics(const sync_pb::SessionTab& tab, const base::Time& mtime, - SyncedSessionTab* session_tab); + SessionTab* session_tab); // Helper method to load the favicon data from the tab specifics. If the // favicon is valid, stores the favicon data and increments the usage counter // in |synced_favicons_| and updates |synced_favicon_pages_| appropriately. void LoadForeignTabFavicon(const sync_pb::SessionTab& tab); - // Append a new navigation from sync specifics onto |tab| navigation vectors. - static void AppendSessionTabNavigation( - const sync_pb::TabNavigation& navigation, - SyncedSessionTab* tab); - - // Populates the navigation portion of the session specifics. - static void PopulateSessionSpecificsNavigation( - const content::NavigationEntry& navigation, - sync_pb::TabNavigation* tab_navigation); - // Returns true if this tab belongs to this profile and belongs to a window, // false otherwise. bool IsValidTab(const SyncedTabDelegate& tab) const; diff --git a/chrome/browser/sync/glue/session_model_associator_unittest.cc b/chrome/browser/sync/glue/session_model_associator_unittest.cc index 8d7f6b4..64c97d7 100644 --- a/chrome/browser/sync/glue/session_model_associator_unittest.cc +++ b/chrome/browser/sync/glue/session_model_associator_unittest.cc @@ -7,7 +7,9 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" +#include "base/string_number_conversions.h" #include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sync/glue/session_model_associator.h" #include "chrome/browser/sync/glue/synced_tab_delegate.h" #include "chrome/browser/sync/profile_sync_service_mock.h" @@ -57,7 +59,7 @@ class SyncSessionModelAssociatorTest : public testing::Test { void AssociateTabContents(const SyncedWindowDelegate& window, const SyncedTabDelegate& new_tab, - SyncedSessionTab* prev_tab, + SessionTab* prev_tab, sync_pb::SessionTab* sync_tab, GURL* new_url) { model_associator_.AssociateTabContents(window, @@ -81,31 +83,23 @@ TEST_F(SyncSessionModelAssociatorTest, SessionWindowHasNoTabsToSync) { scoped_ptr<SessionTab> tab(new SessionTab()); win.tabs.push_back(tab.release()); ASSERT_TRUE(SessionWindowHasNoTabsToSync(win)); - TabNavigation nav(0, GURL("about:bubba"), - content::Referrer(GURL("about:referrer"), - WebKit::WebReferrerPolicyDefault), - string16(ASCIIToUTF16("title")), - std::string("state"), content::PageTransitionFromInt(0)); + TabNavigation nav = + SessionTypesTestHelper::CreateNavigation("about:bubba", "title"); win.tabs[0]->navigations.push_back(nav); ASSERT_FALSE(SessionWindowHasNoTabsToSync(win)); } TEST_F(SyncSessionModelAssociatorTest, ShouldSyncSessionTab) { - SyncedSessionTab tab; + SessionTab tab; ASSERT_FALSE(ShouldSyncSessionTab(tab)); - TabNavigation nav(0, GURL(chrome::kChromeUINewTabURL), - content::Referrer(GURL("about:referrer"), - WebKit::WebReferrerPolicyDefault), - string16(ASCIIToUTF16("title")), - std::string("state"), content::PageTransitionFromInt(0)); + TabNavigation nav = + SessionTypesTestHelper::CreateNavigation( + chrome::kChromeUINewTabURL, "title"); tab.navigations.push_back(nav); // NewTab does not count as valid if it's the only navigation. ASSERT_FALSE(ShouldSyncSessionTab(tab)); - TabNavigation nav2(0, GURL("about:bubba"), - content::Referrer(GURL("about:referrer"), - WebKit::WebReferrerPolicyDefault), - string16(ASCIIToUTF16("title")), - std::string("state"), content::PageTransitionFromInt(0)); + TabNavigation nav2 = + SessionTypesTestHelper::CreateNavigation("about:bubba", "title"); tab.navigations.push_back(nav2); // Once there's another navigation, the tab is valid. ASSERT_TRUE(ShouldSyncSessionTab(tab)); @@ -113,14 +107,11 @@ TEST_F(SyncSessionModelAssociatorTest, ShouldSyncSessionTab) { TEST_F(SyncSessionModelAssociatorTest, ShouldSyncSessionTabIgnoresFragmentForNtp) { - SyncedSessionTab tab; + SessionTab tab; ASSERT_FALSE(ShouldSyncSessionTab(tab)); - TabNavigation nav(0, GURL(std::string(chrome::kChromeUINewTabURL) + - "#bookmarks"), - content::Referrer(GURL("about:referrer"), - WebKit::WebReferrerPolicyDefault), - string16(ASCIIToUTF16("title")), - std::string("state"), content::PageTransitionFromInt(0)); + TabNavigation nav = + SessionTypesTestHelper::CreateNavigation( + std::string(chrome::kChromeUINewTabURL) + "#bookmarks", "title"); tab.navigations.push_back(nav); // NewTab does not count as valid if it's the only navigation. ASSERT_FALSE(ShouldSyncSessionTab(tab)); @@ -166,13 +157,15 @@ TEST_F(SyncSessionModelAssociatorTest, PopulateSessionTab) { tab_s.set_current_navigation_index(3); tab_s.set_pinned(true); tab_s.set_extension_app_id("app_id"); - sync_pb::TabNavigation* navigation = tab_s.add_navigation(); - navigation->set_virtual_url("http://foo/1"); - navigation->set_referrer("referrer"); - navigation->set_title("title"); - navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED); + for (int i = 0; i < 5; ++i) { + sync_pb::TabNavigation* navigation = tab_s.add_navigation(); + navigation->set_virtual_url("http://foo/" + base::IntToString(i)); + navigation->set_referrer("referrer"); + navigation->set_title("title"); + navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED); + } - SyncedSessionTab tab; + SessionTab tab; tab.tab_id.set_id(5); // Expected to be set by the SyncedSessionTracker. SessionModelAssociator::PopulateSessionTabFromSpecifics( tab_s, base::Time(), &tab); @@ -181,10 +174,17 @@ TEST_F(SyncSessionModelAssociatorTest, PopulateSessionTab) { ASSERT_EQ(3, tab.current_navigation_index); ASSERT_TRUE(tab.pinned); ASSERT_EQ("app_id", tab.extension_app_id); - ASSERT_EQ(GURL("referrer"), tab.navigations[0].referrer().url); - ASSERT_EQ(string16(ASCIIToUTF16("title")), tab.navigations[0].title()); - ASSERT_EQ(content::PAGE_TRANSITION_TYPED, tab.navigations[0].transition()); - ASSERT_EQ(GURL("http://foo/1"), tab.navigations[0].virtual_url()); + ASSERT_EQ(5u, tab.navigations.size()); + for (int i = 0; i < 5; ++i) { + ASSERT_EQ(i, tab.navigations[i].index()); + ASSERT_EQ(GURL("referrer"), + SessionTypesTestHelper::GetReferrer(tab.navigations[i]).url); + ASSERT_EQ(string16(ASCIIToUTF16("title")), tab.navigations[i].title()); + ASSERT_EQ(content::PAGE_TRANSITION_TYPED, + SessionTypesTestHelper::GetTransitionType(tab.navigations[i])); + ASSERT_EQ(GURL("http://foo/" + base::IntToString(i)), + tab.navigations[i].virtual_url()); + } } TEST_F(SyncSessionModelAssociatorTest, TabNodePool) { @@ -591,7 +591,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateNewTab) { EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); // This tab is new, so prev_tab is the default SyncedSessionTab object. - SyncedSessionTab prev_tab; + SessionTab prev_tab; prev_tab.tab_id.set_id(0); sync_pb::SessionTab sync_tab; @@ -641,7 +641,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateExistingTab) { EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); // This tab is new, so prev_tab is the default SyncedSessionTab object. - SyncedSessionTab prev_tab; + SessionTab prev_tab; prev_tab.tab_id.set_id(0); // The initial AssociateTabContents call builds the prev_tab. @@ -649,10 +649,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateExistingTab) { GURL new_url; AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); - // Override the timestamps to arbitrary old values we can compare against. - prev_tab.synced_tab_navigations[0].set_timestamp(syncer::ProtoTimeToTime(1)); - prev_tab.synced_tab_navigations[1].set_timestamp(syncer::ProtoTimeToTime(2)); - prev_tab.synced_tab_navigations[2].set_timestamp(syncer::ProtoTimeToTime(3)); + ASSERT_EQ(3u, prev_tab.navigations.size()); // Now re-associate with the same data. AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); @@ -666,11 +663,13 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateExistingTab) { EXPECT_EQ(entry3->GetVirtualURL().spec(), sync_tab.navigation(2).virtual_url()); EXPECT_EQ(2, sync_tab.current_navigation_index()); - EXPECT_EQ(1, sync_tab.navigation(0).timestamp()); - EXPECT_EQ(2, sync_tab.navigation(1).timestamp()); - EXPECT_EQ(3, sync_tab.navigation(2).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), + sync_tab.navigation(0).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[1].timestamp()), + sync_tab.navigation(1).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[2].timestamp()), + sync_tab.navigation(2).timestamp()); EXPECT_EQ(3U, prev_tab.navigations.size()); - EXPECT_EQ(3U, prev_tab.synced_tab_navigations.size()); } // Ensure we add a fresh timestamp for new entries appended to the end. @@ -701,7 +700,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateAppendedTab) { EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); // This tab is new, so prev_tab is the default SyncedSessionTab object. - SyncedSessionTab prev_tab; + SessionTab prev_tab; prev_tab.tab_id.set_id(0); // The initial AssociateTabContents call builds the prev_tab. @@ -709,10 +708,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateAppendedTab) { GURL new_url; AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); - // Override the timestamps to arbitrary old values we can compare against. - prev_tab.synced_tab_navigations[0].set_timestamp(syncer::ProtoTimeToTime(1)); - prev_tab.synced_tab_navigations[1].set_timestamp(syncer::ProtoTimeToTime(2)); - prev_tab.synced_tab_navigations[2].set_timestamp(syncer::ProtoTimeToTime(3)); + ASSERT_EQ(3u, prev_tab.navigations.size()); // Add a new entry and change the current navigation index. scoped_ptr<content::NavigationEntry> entry4( @@ -740,12 +736,14 @@ TEST_F(SyncSessionModelAssociatorTest, AssociateAppendedTab) { EXPECT_EQ(entry4->GetVirtualURL().spec(), sync_tab.navigation(3).virtual_url()); EXPECT_EQ(3, sync_tab.current_navigation_index()); - EXPECT_EQ(1, sync_tab.navigation(0).timestamp()); - EXPECT_EQ(2, sync_tab.navigation(1).timestamp()); - EXPECT_EQ(3, sync_tab.navigation(2).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), + sync_tab.navigation(0).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[1].timestamp()), + sync_tab.navigation(1).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[2].timestamp()), + sync_tab.navigation(2).timestamp()); EXPECT_LE(now, sync_tab.navigation(3).timestamp()); EXPECT_EQ(4U, prev_tab.navigations.size()); - EXPECT_EQ(4U, prev_tab.synced_tab_navigations.size()); } // We shouldn't get confused when old/new entries from the previous tab have @@ -783,7 +781,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociatePrunedTab) { EXPECT_CALL(tab_mock, GetPendingEntryIndex()).WillRepeatedly(Return(-1)); // This tab is new, so prev_tab is the default SyncedSessionTab object. - SyncedSessionTab prev_tab; + SessionTab prev_tab; prev_tab.tab_id.set_id(0); // The initial AssociateTabContents call builds the prev_tab. @@ -791,11 +789,7 @@ TEST_F(SyncSessionModelAssociatorTest, AssociatePrunedTab) { GURL new_url; AssociateTabContents(window_mock, tab_mock, &prev_tab, &sync_tab, &new_url); - // Override the timestamps to arbitrary old values we can compare against. - prev_tab.synced_tab_navigations[0].set_timestamp(syncer::ProtoTimeToTime(1)); - prev_tab.synced_tab_navigations[1].set_timestamp(syncer::ProtoTimeToTime(2)); - prev_tab.synced_tab_navigations[2].set_timestamp(syncer::ProtoTimeToTime(3)); - prev_tab.synced_tab_navigations[2].set_timestamp(syncer::ProtoTimeToTime(4)); + ASSERT_EQ(4u, prev_tab.navigations.size()); // Reset new tab to have the oldest entry pruned, the current navigation // set to entry3, and a new entry added in place of entry4. @@ -830,11 +824,11 @@ TEST_F(SyncSessionModelAssociatorTest, AssociatePrunedTab) { EXPECT_EQ(entry5->GetVirtualURL().spec(), sync_tab.navigation(2).virtual_url()); EXPECT_EQ(1, sync_tab.current_navigation_index()); - EXPECT_EQ(2, sync_tab.navigation(0).timestamp()); + EXPECT_EQ(syncer::TimeToProtoTime(prev_tab.navigations[0].timestamp()), + sync_tab.navigation(0).timestamp()); EXPECT_LE(now, sync_tab.navigation(1).timestamp()); EXPECT_LE(now, sync_tab.navigation(2).timestamp()); EXPECT_EQ(3U, prev_tab.navigations.size()); - EXPECT_EQ(3U, prev_tab.synced_tab_navigations.size()); } } // namespace browser_sync diff --git a/chrome/browser/sync/glue/synced_session.cc b/chrome/browser/sync/glue/synced_session.cc index fc5f924..6da145d 100644 --- a/chrome/browser/sync/glue/synced_session.cc +++ b/chrome/browser/sync/glue/synced_session.cc @@ -10,49 +10,6 @@ namespace browser_sync { -SyncedTabNavigation::SyncedTabNavigation() : unique_id_(0) { -} - -SyncedTabNavigation::SyncedTabNavigation(const SyncedTabNavigation& tab) - : TabNavigation(tab), - unique_id_(tab.unique_id_), - timestamp_(tab.timestamp_) { -} - -SyncedTabNavigation::SyncedTabNavigation(int index, - const GURL& virtual_url, - const content::Referrer& referrer, - const string16& title, - const std::string& state, - content::PageTransition transition, - int unique_id, - const base::Time& timestamp) - : TabNavigation(index, virtual_url, referrer, title, state, transition), - unique_id_(unique_id), - timestamp_(timestamp) { -} - -SyncedTabNavigation::~SyncedTabNavigation() { -} - -void SyncedTabNavigation::set_unique_id(int unique_id) { - unique_id_ = unique_id; -} - -int SyncedTabNavigation::unique_id() const { - return unique_id_; -} - -void SyncedTabNavigation::set_timestamp(const base::Time& timestamp) { - timestamp_ = timestamp; -} -base::Time SyncedTabNavigation::timestamp() const { - return timestamp_; -} - -SyncedSessionTab::SyncedSessionTab() {} -SyncedSessionTab::~SyncedSessionTab() {} - SyncedSession::SyncedSession() : session_tag("invalid"), device_type(TYPE_UNSET) { } diff --git a/chrome/browser/sync/glue/synced_session.h b/chrome/browser/sync/glue/synced_session.h index e7aada6..a1d0d68 100644 --- a/chrome/browser/sync/glue/synced_session.h +++ b/chrome/browser/sync/glue/synced_session.h @@ -18,45 +18,6 @@ class NavigationEntry; namespace browser_sync { -// Sync-specific wrapper around a normal TabNavigation. -// Copy semantics supported. -class SyncedTabNavigation : public TabNavigation { - public: - SyncedTabNavigation(); - SyncedTabNavigation(const SyncedTabNavigation& tab); - SyncedTabNavigation(int index, - const GURL& virtual_url, - const content::Referrer& referrer, - const string16& title, - const std::string& state, - content::PageTransition transition, - int unique_id, - const base::Time& timestamp); - virtual ~SyncedTabNavigation(); - - // Unique id for this navigation. - void set_unique_id(int unique_id); - int unique_id() const; - - // Timestamp this navigation occurred. - void set_timestamp(const base::Time& timestamp); - base::Time timestamp() const; - - private: - int unique_id_; - base::Time timestamp_; -}; - -// Sync-specific wrapper around a normal SessionTab to support using -// SyncedTabNavigation. -struct SyncedSessionTab : public SessionTab { - public: - SyncedSessionTab(); - virtual ~SyncedSessionTab(); - - std::vector<SyncedTabNavigation> synced_tab_navigations; -}; - // Defines a synced session for use by session sync. A synced session is a // list of windows along with a unique session identifer (tag) and meta-data // about the device being synced. diff --git a/chrome/browser/sync/glue/synced_session_tracker.cc b/chrome/browser/sync/glue/synced_session_tracker.cc index 1eb9054..0a482d0 100644 --- a/chrome/browser/sync/glue/synced_session_tracker.cc +++ b/chrome/browser/sync/glue/synced_session_tracker.cc @@ -67,7 +67,7 @@ bool SyncedSessionTracker::LookupSessionWindows( bool SyncedSessionTracker::LookupSessionTab( const std::string& tag, SessionID::id_type tab_id, - const SyncedSessionTab** tab) const { + const SessionTab** tab) const { DCHECK(tab); SyncedTabMap::const_iterator tab_map_iter = synced_tab_map_.find(tag); if (tab_map_iter == synced_tab_map_.end()) { @@ -165,7 +165,7 @@ bool SyncedSessionTracker::DeleteOldSessionTabIfNecessary( SessionTabWrapper tab_wrapper) { if (!tab_wrapper.owned) { if (VLOG_IS_ON(1)) { - SyncedSessionTab* tab_ptr = tab_wrapper.tab_ptr; + SessionTab* tab_ptr = tab_wrapper.tab_ptr; std::string title; if (tab_ptr->navigations.size() > 0) { title = " (" + UTF16ToUTF8( @@ -239,7 +239,7 @@ void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag, SessionID::id_type window_id, SessionID::id_type tab_id, size_t tab_index) { - SyncedSessionTab* tab_ptr = GetTab(session_tag, tab_id); + SessionTab* tab_ptr = GetTab(session_tag, tab_id); unmapped_tabs_.erase(tab_ptr); synced_tab_map_[session_tag][tab_id].owned = true; tab_ptr->window_id.set_id(window_id); @@ -251,14 +251,14 @@ void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag, if (window_tabs.size() <= tab_index) { window_tabs.resize(tab_index+1, NULL); } - DCHECK_EQ((SyncedSessionTab*)NULL, window_tabs[tab_index]); + DCHECK(!window_tabs[tab_index]); window_tabs[tab_index] = tab_ptr; } -SyncedSessionTab* SyncedSessionTracker::GetTab( +SessionTab* SyncedSessionTracker::GetTab( const std::string& session_tag, SessionID::id_type tab_id) { - SyncedSessionTab* tab_ptr = NULL; + SessionTab* tab_ptr = NULL; IDToSessionTabMap::iterator iter = synced_tab_map_[session_tag].find(tab_id); if (iter != synced_tab_map_[session_tag].end()) { @@ -275,7 +275,7 @@ SyncedSessionTab* SyncedSessionTracker::GetTab( << "'s seen tab " << tab_id << " at " << tab_ptr << title; } } else { - tab_ptr = new SyncedSessionTab(); + tab_ptr = new SessionTab(); tab_ptr->tab_id.set_id(tab_id); synced_tab_map_[session_tag][tab_id] = SessionTabWrapper(tab_ptr, false); unmapped_tabs_.insert(tab_ptr); diff --git a/chrome/browser/sync/glue/synced_session_tracker.h b/chrome/browser/sync/glue/synced_session_tracker.h index 8b46d6f..782a257 100644 --- a/chrome/browser/sync/glue/synced_session_tracker.h +++ b/chrome/browser/sync/glue/synced_session_tracker.h @@ -56,7 +56,7 @@ class SyncedSessionTracker { // - Returns false, tab is set to NULL. bool LookupSessionTab(const std::string& session_tag, SessionID::id_type tab_id, - const SyncedSessionTab** tab) const; + const SessionTab** tab) const; // Returns a pointer to the SyncedSession object associated with // |session_tag|. If none exists, creates one. Ownership of the @@ -103,8 +103,8 @@ class SyncedSessionTracker { // Returns a pointer to the SessionTab object associated with |tab_id| for // the session specified with |session_tag|. If none exists, creates one. // Ownership of the SessionTab remains within the SyncedSessionTracker. - SyncedSessionTab* GetTab(const std::string& session_tag, - SessionID::id_type tab_id); + SessionTab* GetTab(const std::string& session_tag, + SessionID::id_type tab_id); // Free the memory for all dynamically allocated objects and clear the // tracking structures. @@ -138,10 +138,10 @@ class SyncedSessionTracker { // above). struct SessionTabWrapper { SessionTabWrapper() : tab_ptr(NULL), owned(false) {} - SessionTabWrapper(SyncedSessionTab* tab_ptr, bool owned) + SessionTabWrapper(SessionTab* tab_ptr, bool owned) : tab_ptr(tab_ptr), owned(owned) {} - SyncedSessionTab* tab_ptr; + SessionTab* tab_ptr; bool owned; }; typedef std::map<SessionID::id_type, SessionTabWrapper> IDToSessionTabMap; @@ -184,7 +184,7 @@ class SyncedSessionTracker { // have not yet mapped to SyncedSessions. These are temporarily orphaned // tabs, and won't be deleted if we delete synced_session_map_, but are still // owned by the SyncedSessionTracker itself (and deleted on Clear()). - std::set<SyncedSessionTab*> unmapped_tabs_; + std::set<SessionTab*> unmapped_tabs_; // The tag for this machine's local session, so we can distinguish the foreign // sessions. diff --git a/chrome/browser/sync/glue/synced_session_tracker_unittest.cc b/chrome/browser/sync/glue/synced_session_tracker_unittest.cc index 985f885..a5d477d 100644 --- a/chrome/browser/sync/glue/synced_session_tracker_unittest.cc +++ b/chrome/browser/sync/glue/synced_session_tracker_unittest.cc @@ -10,6 +10,7 @@ #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "chrome/browser/sessions/session_types.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sync/glue/synced_session_tracker.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,7 +29,7 @@ TEST_F(SyncedSessionTrackerTest, GetSession) { TEST_F(SyncedSessionTrackerTest, GetTabUnmapped) { SyncedSessionTracker tracker; - SyncedSessionTab* tab = tracker.GetTab("tag", 0); + SessionTab* tab = tracker.GetTab("tag", 0); ASSERT_EQ(tab, tracker.GetTab("tag", 0)); // Should clean up memory on its own. } @@ -60,12 +61,10 @@ TEST_F(SyncedSessionTrackerTest, LookupAllForeignSessions) { tracker.GetSession("tag2"); tracker.PutWindowInSession("tag1", 0); tracker.PutTabInWindow("tag1", 0, 15, 0); - SyncedSessionTab* tab = tracker.GetTab("tag1", 15); + SessionTab* tab = tracker.GetTab("tag1", 15); ASSERT_TRUE(tab); - tab->navigations.push_back(TabNavigation( - 0, GURL("bla://valid_url"), content::Referrer(GURL("bla://referrer"), - WebKit::WebReferrerPolicyDefault), string16(ASCIIToUTF16("title")), - std::string("state"), content::PageTransitionFromInt(0))); + tab->navigations.push_back(SessionTypesTestHelper::CreateNavigation( + "bla://valid_url", "title")); ASSERT_TRUE(tracker.LookupAllForeignSessions(&sessions)); // Only the session with a valid window and tab gets returned. ASSERT_EQ(1U, sessions.size()); @@ -91,13 +90,13 @@ TEST_F(SyncedSessionTrackerTest, LookupSessionWindows) { TEST_F(SyncedSessionTrackerTest, LookupSessionTab) { SyncedSessionTracker tracker; - const SyncedSessionTab* tab; + const SessionTab* tab; ASSERT_FALSE(tracker.LookupSessionTab("tag1", 5, &tab)); tracker.GetSession("tag1"); tracker.PutWindowInSession("tag1", 0); tracker.PutTabInWindow("tag1", 0, 5, 0); ASSERT_TRUE(tracker.LookupSessionTab("tag1", 5, &tab)); - ASSERT_NE((SyncedSessionTab*)NULL, tab); + ASSERT_NE((SessionTab*)NULL, tab); } TEST_F(SyncedSessionTrackerTest, Complex) { @@ -105,8 +104,8 @@ TEST_F(SyncedSessionTrackerTest, Complex) { const std::string tag2 = "tag2"; const std::string tag3 = "tag3"; SyncedSessionTracker tracker; - std::vector<SyncedSessionTab*> tabs1, tabs2; - SyncedSessionTab* temp_tab; + std::vector<SessionTab*> tabs1, tabs2; + SessionTab* temp_tab; ASSERT_TRUE(tracker.Empty()); ASSERT_EQ(0U, tracker.num_synced_sessions()); ASSERT_EQ(0U, tracker.num_synced_tabs(tag1)); @@ -141,13 +140,13 @@ TEST_F(SyncedSessionTrackerTest, Complex) { tracker.PutTabInWindow(tag1, 0, 2, 0); // No longer unmapped. ASSERT_EQ(3U, tracker.num_synced_tabs(tag1)); // Has not changed. - const SyncedSessionTab *tab_ptr; + const SessionTab *tab_ptr; ASSERT_TRUE(tracker.LookupSessionTab(tag1, 0, &tab_ptr)); ASSERT_EQ(tab_ptr, tabs1[0]); ASSERT_TRUE(tracker.LookupSessionTab(tag1, 2, &tab_ptr)); ASSERT_EQ(tab_ptr, tabs1[2]); ASSERT_FALSE(tracker.LookupSessionTab(tag1, 3, &tab_ptr)); - ASSERT_EQ(static_cast<const SyncedSessionTab*>(NULL), tab_ptr); + ASSERT_EQ(static_cast<const SessionTab*>(NULL), tab_ptr); std::vector<const SessionWindow*> windows; ASSERT_TRUE(tracker.LookupSessionWindows(tag1, &windows)); @@ -177,7 +176,7 @@ TEST_F(SyncedSessionTrackerTest, ManyGetTabs) { // More attempts than tabs means we'll sometimes get the same tabs, // sometimes have to allocate new tabs. int rand_tab_num = base::RandInt(0, kMaxTabs); - SyncedSessionTab* tab = tracker.GetTab(tag, rand_tab_num); + SessionTab* tab = tracker.GetTab(tag, rand_tab_num); ASSERT_TRUE(tab); } } diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc index 33790cf..9878a55 100644 --- a/chrome/browser/sync/profile_sync_service_session_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc @@ -15,6 +15,7 @@ #include "base/scoped_temp_dir.h" #include "base/stl_util.h" #include "base/time.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/token_service_factory.h" @@ -139,9 +140,10 @@ void VerifySyncedSession( ASSERT_EQ("app_id", tab->extension_app_id); ASSERT_EQ(1U, tab->navigations.size()); ASSERT_EQ(tab->navigations[0].virtual_url(), GURL("http://foo/1")); - ASSERT_EQ(tab->navigations[0].referrer().url, GURL("referrer")); + ASSERT_EQ(SessionTypesTestHelper::GetReferrer(tab->navigations[0]).url, + GURL("referrer")); ASSERT_EQ(tab->navigations[0].title(), string16(ASCIIToUTF16("title"))); - ASSERT_EQ(tab->navigations[0].transition(), + ASSERT_EQ(SessionTypesTestHelper::GetTransitionType(tab->navigations[0]), content::PAGE_TRANSITION_TYPED); } } diff --git a/chrome/browser/sync/test/integration/sessions_helper.cc b/chrome/browser/sync/test/integration/sessions_helper.cc index ed41974..7a0b916 100644 --- a/chrome/browser/sync/test/integration/sessions_helper.cc +++ b/chrome/browser/sync/test/integration/sessions_helper.cc @@ -10,14 +10,15 @@ #include "base/test/test_timeouts.h" #include "base/time.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sync/glue/session_model_associator.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" -#include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/browser/ui/singleton_tabs.h" +#include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/browser_thread.h" #include "googleurl/src/gurl.h" @@ -240,9 +241,12 @@ bool NavigationEquals(const TabNavigation& expected, << ", actual " << actual.virtual_url(); return false; } - if (expected.referrer().url != actual.referrer().url) { - LOG(ERROR) << "Expected referrer " << expected.referrer().url - << ", actual " << actual.referrer().url; + if (SessionTypesTestHelper::GetReferrer(expected).url != + SessionTypesTestHelper::GetReferrer(actual).url) { + LOG(ERROR) << "Expected referrer " + << SessionTypesTestHelper::GetReferrer(expected).url + << ", actual " + << SessionTypesTestHelper::GetReferrer(actual).url; return false; } if (expected.title() != actual.title()) { @@ -250,9 +254,12 @@ bool NavigationEquals(const TabNavigation& expected, << ", actual " << actual.title(); return false; } - if (expected.transition() != actual.transition()) { - LOG(ERROR) << "Expected transition " << expected.transition() - << ", actual " << actual.transition(); + if (SessionTypesTestHelper::GetTransitionType(expected) != + SessionTypesTestHelper::GetTransitionType(actual)) { + LOG(ERROR) << "Expected transition " + << SessionTypesTestHelper::GetTransitionType(expected) + << ", actual " + << SessionTypesTestHelper::GetTransitionType(actual); return false; } return true; diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc index 4443305..da35864 100644 --- a/chrome/browser/ui/browser_tabrestore.cc +++ b/chrome/browser/ui/browser_tabrestore.cc @@ -59,9 +59,9 @@ content::WebContents* AddRestoredTab( WebContents* new_tab = tab_contents->web_contents(); extensions::TabHelper::FromWebContents(new_tab)-> SetExtensionAppById(extension_app_id); - std::vector<NavigationEntry*> entries; - TabNavigation::CreateNavigationEntriesFromTabNavigations( - browser->profile(), navigations, &entries); + std::vector<NavigationEntry*> entries = + TabNavigation::CreateNavigationEntriesFromTabNavigations( + navigations, browser->profile()); new_tab->SetUserAgentOverride(user_agent_override); new_tab->GetController().Restore( selected_navigation, from_last_session, &entries); @@ -123,9 +123,9 @@ void ReplaceRestoredTab( extensions::TabHelper::FromWebContents(replacement)-> SetExtensionAppById(extension_app_id); replacement->SetUserAgentOverride(user_agent_override); - std::vector<NavigationEntry*> entries; - TabNavigation::CreateNavigationEntriesFromTabNavigations( - browser->profile(), navigations, &entries); + std::vector<NavigationEntry*> entries = + TabNavigation::CreateNavigationEntriesFromTabNavigations( + navigations, browser->profile()); replacement->GetController().Restore( selected_navigation, from_last_session, &entries); DCHECK_EQ(0u, entries.size()); diff --git a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm index ccffea9..e80eacb 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm @@ -12,6 +12,7 @@ #include "base/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/cancelable_request.h" +#include "chrome/browser/sessions/session_types_test_helper.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" #include "chrome/browser/ui/cocoa/history_menu_bridge.h" @@ -90,12 +91,12 @@ class HistoryMenuBridgeTest : public CocoaProfileTest { return item; } - MockTRS::Tab CreateSessionTab(const GURL& url, const string16& title) { + MockTRS::Tab CreateSessionTab(const std::string& url, + const std::string& title) { MockTRS::Tab tab; tab.current_navigation_index = 0; tab.navigations.push_back( - TabNavigation(0, url, content::Referrer(), title, std::string(), - content::PAGE_TRANSITION_LINK)); + SessionTypesTestHelper::CreateNavigation(url, title)); return tab; } @@ -213,13 +214,11 @@ TEST_F(HistoryMenuBridgeTest, RecentlyClosedTabs) { scoped_ptr<MockTRS> trs(new MockTRS(profile())); MockTRS::Entries entries; - MockTRS::Tab tab1 = CreateSessionTab(GURL("http://google.com"), - ASCIIToUTF16("Google")); + MockTRS::Tab tab1 = CreateSessionTab("http://google.com", "Google"); tab1.id = 24; entries.push_back(&tab1); - MockTRS::Tab tab2 = CreateSessionTab(GURL("http://apple.com"), - ASCIIToUTF16("Apple")); + MockTRS::Tab tab2 = CreateSessionTab("http://apple.com", "Apple"); tab2.id = 42; entries.push_back(&tab2); @@ -249,37 +248,29 @@ TEST_F(HistoryMenuBridgeTest, RecentlyClosedTabsAndWindows) { scoped_ptr<MockTRS> trs(new MockTRS(profile())); MockTRS::Entries entries; - MockTRS::Tab tab1 = CreateSessionTab(GURL("http://google.com"), - ASCIIToUTF16("Google")); + MockTRS::Tab tab1 = CreateSessionTab("http://google.com", "Google"); tab1.id = 24; entries.push_back(&tab1); MockTRS::Window win1; win1.id = 30; - win1.tabs.push_back( - CreateSessionTab(GURL("http://foo.com"), ASCIIToUTF16("foo"))); + win1.tabs.push_back(CreateSessionTab("http://foo.com", "foo")); win1.tabs[0].id = 31; - win1.tabs.push_back( - CreateSessionTab(GURL("http://bar.com"), ASCIIToUTF16("bar"))); + win1.tabs.push_back(CreateSessionTab("http://bar.com", "bar")); win1.tabs[1].id = 32; entries.push_back(&win1); - MockTRS::Tab tab2 = CreateSessionTab(GURL("http://apple.com"), - ASCIIToUTF16("Apple")); + MockTRS::Tab tab2 = CreateSessionTab("http://apple.com", "Apple"); tab2.id = 42; entries.push_back(&tab2); MockTRS::Window win2; win2.id = 50; - win2.tabs.push_back( - CreateSessionTab(GURL("http://magic.com"), ASCIIToUTF16("magic"))); + win2.tabs.push_back(CreateSessionTab("http://magic.com", "magic")); win2.tabs[0].id = 51; - win2.tabs.push_back( - CreateSessionTab(GURL("http://goats.com"), ASCIIToUTF16("goats"))); + win2.tabs.push_back(CreateSessionTab("http://goats.com", "goats")); win2.tabs[1].id = 52; - win2.tabs.push_back( - CreateSessionTab(GURL("http://teleporter.com"), - ASCIIToUTF16("teleporter"))); + win2.tabs.push_back(CreateSessionTab("http://teleporter.com", "teleporter")); win2.tabs[1].id = 53; entries.push_back(&win2); |