Index: chrome/browser/sync/glue/session_model_associator.cc |
diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc |
index 38c71b72c1fa16162f94c72e16075f60a8be4925..c9d4494fa9ace723aae1d5a4d141e3d0df264248 100644 |
--- a/chrome/browser/sync/glue/session_model_associator.cc |
+++ b/chrome/browser/sync/glue/session_model_associator.cc |
@@ -372,14 +372,24 @@ bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab, |
return WriteTabContentsToSyncModel(tab_link, error); |
} |
+// static |
+GURL SessionModelAssociator::GetCurrentVirtualURL( |
+ const SyncedTabDelegate& tab_delegate) { |
+ GURL new_url; |
+ const int current_index = tab_delegate.GetCurrentEntryIndex(); |
+ const int pending_index = tab_delegate.GetPendingEntryIndex(); |
+ const NavigationEntry* current_entry = |
+ (current_index == pending_index) ? |
+ tab_delegate.GetPendingEntry() : |
+ tab_delegate.GetEntryAtIndex(current_index); |
+ return current_entry->GetVirtualURL(); |
+} |
+ |
bool SessionModelAssociator::WriteTabContentsToSyncModel( |
TabLink* tab_link, |
syncer::SyncError* error) { |
DCHECK(CalledOnValidThread()); |
- const SyncedTabDelegate& tab = *(tab_link->tab()); |
- const SyncedWindowDelegate& window = |
- *SyncedWindowDelegate::FindSyncedWindowDelegateWithId( |
- tab.GetWindowId()); |
+ const SyncedTabDelegate& tab_delegate = *(tab_link->tab()); |
int64 sync_id = tab_link->sync_id(); |
GURL old_tab_url = tab_link->url(); |
@@ -387,13 +397,14 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
// is a new tab, session_tab will be a blank/newly created SessionTab object. |
SessionTab* session_tab = |
synced_session_tracker_.GetTab(GetCurrentMachineTag(), |
- tab.GetSessionId()); |
+ tab_delegate.GetSessionId()); |
- // We build a clean session tab specifics directly from the tab data. |
- sync_pb::SessionTab tab_s; |
+ base::Time now = base::Time::Now(); |
+ UpdateSessionTabFromDelegate(tab_delegate, now, now, session_tab); |
- GURL new_url; |
- AssociateTabContents(window, tab, session_tab, &tab_s, &new_url); |
+ const GURL new_url = GetCurrentVirtualURL(tab_delegate); |
+ DVLOG(1) << "Local tab " << tab_delegate.GetSessionId() |
+ << " now has URL " << new_url.spec(); |
// Trigger the favicon load if needed. We do this before opening the write |
// transaction to avoid jank. |
@@ -418,6 +429,7 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
return false; |
} |
+ sync_pb::SessionTab tab_s = session_tab->ToSyncData(); |
sync_pb::SessionSpecifics specifics = tab_node.GetSessionSpecifics(); |
if (new_url == old_tab_url) { |
// Load the old specifics and copy over the favicon data if needed. |
@@ -438,106 +450,98 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
return true; |
} |
-// Builds |sync_tab| by combining data from |prev_tab| and |new_tab|. Updates |
-// |prev_tab| to reflect the newest version. |
-// Timestamps are chosen from either |prev_tab| or base::Time::Now() based on |
-// the following rules: |
-// 1. If a navigation exists in both |new_tab| and |prev_tab|, as determined |
-// by the unique id, and the navigation didn't just become the current |
-// navigation, we preserve the old timestamp. |
+// Updates |session_tab| by combining existing data and new data from |
+// |tab_delegate|. |
+// |
+// Timestamps are chosen from either |session_tab| or |
+// |default_navigation_timestamp| based on the following rules: |
+// 1. If a navigation exists in both |tab_delegate| and |session_tab|, |
+// as determined by the unique id, and the navigation didn't just |
+// become the current navigation, we preserve the old timestamp. |
// 2. If the navigation exists in both but just become the current navigation |
// (e.g. the user went back in history to this navigation), we update the |
-// timestamp to Now(). |
-// 3. All new navigations not present in |prev_tab| have their timestamps set to |
-// Now(). |
-void SessionModelAssociator::AssociateTabContents( |
- const SyncedWindowDelegate& window, |
- const SyncedTabDelegate& new_tab, |
- SessionTab* prev_tab, |
- sync_pb::SessionTab* sync_tab, |
- GURL* new_url) { |
- DCHECK(prev_tab); |
- DCHECK(sync_tab); |
- DCHECK(new_url); |
- SessionID::id_type tab_id = new_tab.GetSessionId(); |
- sync_tab->set_tab_id(tab_id); |
- sync_tab->set_window_id(new_tab.GetWindowId()); |
- const int current_index = new_tab.GetCurrentEntryIndex(); |
- sync_tab->set_current_navigation_index(current_index); |
+// timestamp to |default_navigation_timestamp|. |
+// 3. All new navigations not present in |session_tab| have their |
+// timestamps set to |default_navigation_timestamp| (if they're the |
+// current one) or nulled out (if not). |
+// |
+// static |
+void SessionModelAssociator::UpdateSessionTabFromDelegate( |
+ const SyncedTabDelegate& tab_delegate, |
+ base::Time mtime, |
+ base::Time default_navigation_timestamp, |
+ SessionTab* session_tab) { |
+ DCHECK(session_tab); |
+ session_tab->window_id.set_id(tab_delegate.GetWindowId()); |
+ session_tab->tab_id.set_id(tab_delegate.GetSessionId()); |
+ session_tab->tab_visual_index = 0; |
+ session_tab->current_navigation_index = tab_delegate.GetCurrentEntryIndex(); |
+ session_tab->pinned = tab_delegate.IsPinned(); |
+ session_tab->extension_app_id = tab_delegate.GetExtensionAppId(); |
+ session_tab->user_agent_override.clear(); |
+ session_tab->timestamp = mtime; |
+ const int current_index = tab_delegate.GetCurrentEntryIndex(); |
+ const int pending_index = tab_delegate.GetPendingEntryIndex(); |
const int min_index = std::max(0, |
current_index - kMaxSyncNavigationCount); |
const int max_index = std::min(current_index + kMaxSyncNavigationCount, |
- new_tab.GetEntryCount()); |
- const int pending_index = new_tab.GetPendingEntryIndex(); |
- sync_tab->set_pinned(window.IsTabPinned(&new_tab)); |
- if (new_tab.HasExtensionAppId()) { |
- sync_tab->set_extension_app_id(new_tab.GetExtensionAppId()); |
- } |
- |
- sync_tab->mutable_navigation()->Clear(); |
+ tab_delegate.GetEntryCount()); |
+ std::vector<TabNavigation> previous_navigations; |
+ previous_navigations.swap(session_tab->navigations); |
Nicolas Zea
2012/09/26 00:26:47
is there any reason you modify previous_navigation
akalin
2012/09/26 00:32:12
session_tab->navigations should be cleared and fil
Nicolas Zea
2012/09/26 00:35:16
Ah, right. Makes sense.
|
std::vector<TabNavigation>::const_iterator prev_nav_iter = |
- prev_tab->navigations.begin(); |
+ previous_navigations.begin(); |
for (int i = min_index; i < max_index; ++i) { |
const NavigationEntry* entry = (i == pending_index) ? |
- new_tab.GetPendingEntry() : new_tab.GetEntryAtIndex(i); |
+ tab_delegate.GetPendingEntry() : tab_delegate.GetEntryAtIndex(i); |
DCHECK(entry); |
if (i == min_index) { |
// 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->navigations.end(); |
+ for (;prev_nav_iter != previous_navigations.end(); |
++prev_nav_iter) { |
if (prev_nav_iter->unique_id() == entry->GetUniqueID()) |
break; |
} |
} |
if (entry->GetVirtualURL().is_valid()) { |
- if (i == current_index) { |
- *new_url = GURL(entry->GetVirtualURL().spec()); |
- DVLOG(1) << "Associating local tab " << new_tab.GetSessionId() |
- << " with url " << new_url->spec() << " and title " |
- << entry->GetTitle(); |
- |
- } |
- sync_pb::TabNavigation* sync_nav = sync_tab->add_navigation(); |
- const TabNavigation& navigation = |
- TabNavigation::FromNavigationEntry(i, *entry, base::Time::Now()); |
- *sync_nav = navigation.ToSyncData(); |
- |
+ // TODO(akalin): Remove this logic once we have a timestamp in |
+ // NavigationEntry (since we can just use those directly). |
+ base::Time timestamp; |
// 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->navigations.end() && |
+ if (prev_nav_iter != previous_navigations.end() && |
prev_nav_iter->unique_id() == entry->GetUniqueID()) { |
- // Check that we haven't gone back/foward in the nav stack to this page |
+ // Check that we haven't gone back/forward in the nav stack to this page |
// (if so, we want to refresh the timestamp). |
- if (!(current_index != prev_tab->current_navigation_index && |
+ if (!(current_index != session_tab->current_navigation_index && |
current_index == i)) { |
- sync_nav->set_timestamp( |
- syncer::TimeToProtoTime(prev_nav_iter->timestamp())); |
- DVLOG(2) << "Nav to " << sync_nav->virtual_url() << " already known, " |
- << "reusing old timestamp " << sync_nav->timestamp(); |
+ timestamp = prev_nav_iter->timestamp(); |
+ DVLOG(2) << "Nav to " << entry->GetVirtualURL() |
+ << " already known, reusing old timestamp " |
+ << timestamp.ToInternalValue(); |
} |
// Even if the user went back in their history, they may have skipped |
// over navigations, so the subsequent navigation entries may need their |
// old timestamps preserved. |
++prev_nav_iter; |
- } else if (current_index != i && |
- prev_tab->navigations.empty()) { |
+ } else if (current_index != i && previous_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. |
// Note: this is primarily to handle restoring sessions at restart, |
// opening recently closed tabs, or opening tabs from other devices. |
// Only the current navigation should have a timestamp in those cases. |
- sync_nav->set_timestamp(0); |
+ timestamp = base::Time(); |
+ } else { |
+ timestamp = default_navigation_timestamp; |
} |
+ |
+ session_tab->navigations.push_back( |
+ TabNavigation::FromNavigationEntry(i, *entry, timestamp)); |
} |
} |
- |
- // Now update our local version with the newest data. |
- PopulateSessionTabFromSpecifics(*sync_tab, |
- base::Time::Now(), |
- prev_tab); |
+ session_tab->session_storage_persistent_id.clear(); |
} |
void SessionModelAssociator::LoadFaviconForTab(TabLink* tab_link) { |
@@ -970,7 +974,7 @@ void SessionModelAssociator::AssociateForeignSpecifics( |
} |
// Update SessionTab based on protobuf. |
- PopulateSessionTabFromSpecifics(tab_s, modification_time, tab); |
+ tab->SetFromSyncData(tab_s, modification_time); |
// Loads the tab favicon, increments the usage counter, and updates |
// synced_favicon_pages_. |
@@ -1038,7 +1042,7 @@ bool SessionModelAssociator::DisassociateForeignSession( |
// Static |
void SessionModelAssociator::PopulateSessionHeaderFromSpecifics( |
const sync_pb::SessionHeader& header_specifics, |
- const base::Time& mtime, |
+ base::Time mtime, |
SyncedSession* session_header) { |
if (header_specifics.has_client_name()) { |
session_header->session_name = header_specifics.client_name(); |
@@ -1077,7 +1081,7 @@ void SessionModelAssociator::PopulateSessionHeaderFromSpecifics( |
void SessionModelAssociator::PopulateSessionWindowFromSpecifics( |
const std::string& session_tag, |
const sync_pb::SessionWindow& specifics, |
- const base::Time& mtime, |
+ base::Time mtime, |
SessionWindow* session_window, |
SyncedSessionTracker* tracker) { |
if (specifics.has_window_id()) |
@@ -1103,33 +1107,6 @@ void SessionModelAssociator::PopulateSessionWindowFromSpecifics( |
} |
} |
-// Static |
-void SessionModelAssociator::PopulateSessionTabFromSpecifics( |
- const sync_pb::SessionTab& specifics, |
- const base::Time& mtime, |
- SessionTab* tab) { |
- DCHECK_EQ(tab->tab_id.id(), specifics.tab_id()); |
- if (specifics.has_tab_id()) |
- tab->tab_id.set_id(specifics.tab_id()); |
- if (specifics.has_window_id()) |
- tab->window_id.set_id(specifics.window_id()); |
- if (specifics.has_tab_visual_index()) |
- tab->tab_visual_index = specifics.tab_visual_index(); |
- if (specifics.has_current_navigation_index()) |
- tab->current_navigation_index = specifics.current_navigation_index(); |
- if (specifics.has_pinned()) |
- tab->pinned = specifics.pinned(); |
- if (specifics.has_extension_app_id()) |
- tab->extension_app_id = specifics.extension_app_id(); |
- tab->timestamp = mtime; |
- // Cleared in case we reuse a pre-existing SyncedSessionTab object. |
- tab->navigations.clear(); |
- for (int i = 0; i < specifics.navigation_size(); ++i) { |
- tab->navigations.push_back( |
- TabNavigation::FromSyncData(i, specifics.navigation(i))); |
- } |
-} |
- |
void SessionModelAssociator::LoadForeignTabFavicon( |
const sync_pb::SessionTab& tab) { |
if (!tab.has_favicon() || tab.favicon().empty()) |