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 798db3a965c303ad16c5cbc22b4db6e9e4e55d31..67a6518dcc98fb7441a7528af8895bc5a52fcc43 100644 |
--- a/chrome/browser/sync/glue/session_model_associator.cc |
+++ b/chrome/browser/sync/glue/session_model_associator.cc |
@@ -143,6 +143,14 @@ bool SessionModelAssociator::InitSyncNodeFromChromeId( |
return false; |
} |
+void SessionModelAssociator::NotifySyncIdGenerated( |
+ const SyncedTabDelegate& tab) { |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_SESSION_SYNC_ID_GENERATED, |
+ content::Source<SessionModelAssociator>(this), |
+ content::Details<const SyncedTabDelegate>(&tab)); |
+} |
+ |
bool SessionModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { |
DCHECK(CalledOnValidThread()); |
CHECK(has_nodes); |
@@ -202,6 +210,7 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
header_s->set_device_type(DeviceInfo::GetLocalDeviceType()); |
synced_session_tracker_.ResetSessionTracking(local_tag); |
+ std::vector<int64> used_sync_ids; |
std::set<SyncedWindowDelegate*> windows = |
SyncedWindowDelegate::GetSyncedWindowDelegates(); |
for (std::set<SyncedWindowDelegate*>::const_iterator i = |
@@ -219,7 +228,7 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
<< (*i)->GetTabCount() << " tabs."; |
window_s.set_window_id(window_id); |
// Note: We don't bother to set selected tab index anymore. We still |
- // consume it when receiving foreign sessions, as reading it is free, but |
+ // consume it when foreign sessions, as reading it is free, but |
// it triggers too many sync cycles with too little value to make setting |
// it worthwhile. |
if ((*i)->IsTypeTabbed()) { |
@@ -232,15 +241,26 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
// Store the order of tabs. |
bool found_tabs = false; |
+ std::vector<SessionID::id_type> used_tabs; |
for (int j = 0; j < (*i)->GetTabCount(); ++j) { |
SessionID::id_type tab_id = (*i)->GetTabIdAt(j); |
+ SyncedTabDelegate* tab_delegate = (*i)->GetTabAt(j); |
if (reload_tabs) { |
- SyncedTabDelegate* tab = (*i)->GetTabAt(j); |
+ if (tab_delegate && !tab_delegate->IsTabInMemory()) { |
+ found_tabs = true; |
+ // Update tab id since it might have changed. |
+ UpdateTabIdForOldTab(tab_delegate->GetSyncSessionId(), tab_id); |
Nicolas Zea
2013/05/16 22:59:03
I don't think you should ever update the tab id. T
shashi
2013/05/17 00:29:16
When restore happens, the tab ids (different from
|
+ window_s.add_tab(tab_id); |
+ used_sync_ids.push_back(tab_delegate->GetSyncSessionId()); |
+ continue; |
+ } |
+ |
// It's possible for GetTabAt to return a null tab if it's not in |
// memory. We can assume this means the tab already existed but hasn't |
// changed, so no need to reassociate. |
- if (tab && !AssociateTab(*tab, error)) { |
+ if (tab_delegate && tab_delegate->IsTabInMemory() && |
+ !AssociateTab(*tab_delegate, error)) { |
// Association failed. Either we need to re-associate, or this is an |
// unrecoverable error. |
return false; |
@@ -254,7 +274,9 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
// the tab's presence in the tracker. |
const SessionTab* tab = NULL; |
if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { |
+ used_tabs.push_back(tab_id); |
found_tabs = true; |
+ used_sync_ids.push_back(tab_delegate->GetSyncSessionId()); |
window_s.add_tab(tab_id); |
} |
} |
@@ -276,6 +298,7 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
} |
// Free memory for closed windows and tabs. |
synced_session_tracker_.CleanupSession(local_tag); |
+ tab_pool_.PurgeOldSyncNodes(used_sync_ids); |
syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
syncer::WriteNode header_node(&trans); |
@@ -294,6 +317,22 @@ bool SessionModelAssociator::AssociateWindows(bool reload_tabs, |
return true; |
} |
+void SessionModelAssociator::UpdateTabIdForOldTab( |
+ int64 sync_id, |
+ SessionID::id_type new_tab_id) { |
+ syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
+ syncer::WriteNode tab_node(&trans); |
+ // Rewrite tab id if required. |
+ if (tab_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { |
+ return; |
+ } |
+ sync_pb::SessionSpecifics session_specifics = tab_node.GetSessionSpecifics(); |
+ DCHECK(session_specifics.has_tab()); |
+ sync_pb::SessionTab* tab_s = session_specifics.mutable_tab(); |
+ tab_s->set_tab_id(new_tab_id); |
+ tab_node.SetSessionSpecifics(session_specifics); |
+} |
+ |
// Static. |
bool SessionModelAssociator::ShouldSyncWindow( |
const SyncedWindowDelegate* window) { |
@@ -316,11 +355,11 @@ bool SessionModelAssociator::AssociateTabs( |
return true; |
} |
-bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab, |
+bool SessionModelAssociator::AssociateTab(SyncedTabDelegate& tab, |
syncer::SyncError* error) { |
DCHECK(CalledOnValidThread()); |
int64 sync_id; |
- SessionID::id_type tab_id = tab.GetSessionId(); |
+ SessionID::id_type tab_id = tab.GetSessionId().id(); |
if (tab.IsBeingDestroyed()) { |
// This tab is closing. |
TabLinksMap::iterator tab_iter = tab_map_.find(tab_id); |
@@ -339,8 +378,17 @@ bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab, |
TabLinksMap::iterator tab_map_iter = tab_map_.find(tab_id); |
TabLink* tab_link = NULL; |
if (tab_map_iter == tab_map_.end()) { |
- // This is a new tab, get a sync node for it. |
- sync_id = tab_pool_.GetFreeTabNode(); |
+ // This is a new tab, get a sync node for it. Check if there is an old sync |
+ // node for it. |
+ sync_id = tab_pool_.GetOldSyncNode(tab.GetSyncSessionId()); |
+ if (sync_id < 0) { |
+ sync_id = tab_pool_.GetFreeTabNode(); |
+ } |
+ if (tab.GetSyncSessionId() != sync_id) { |
+ tab.SetSyncSessionId(sync_id); |
+ NotifySyncIdGenerated(tab); |
Nicolas Zea
2013/05/16 22:59:03
would it be better to have the equivalency check a
shashi
2013/05/17 00:29:16
On 2013/05/16 22:59:03, Nicolas Zea wrote:
> would
shashi
2013/05/17 00:29:16
Yes, I can replace it with an equivalency check, a
|
+ } |
+ |
if (sync_id == syncer::kInvalidId) { |
if (error) { |
*error = error_handler_->CreateAndUploadError( |
@@ -363,7 +411,7 @@ bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab, |
DCHECK_NE(tab_link->sync_id(), syncer::kInvalidId); |
DVLOG(1) << "Reloading tab " << tab_id << " from window " |
- << tab.GetWindowId(); |
+ << tab.GetWindowId().id(); |
return WriteTabContentsToSyncModel(tab_link, error); |
} |
@@ -397,21 +445,21 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
TabLink* tab_link, |
syncer::SyncError* error) { |
DCHECK(CalledOnValidThread()); |
+ DCHECK(tab_link->tab()); |
const SyncedTabDelegate& tab_delegate = *(tab_link->tab()); |
int64 sync_id = tab_link->sync_id(); |
GURL old_tab_url = tab_link->url(); |
// 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. |
- SessionTab* session_tab = |
- synced_session_tracker_.GetTab(GetCurrentMachineTag(), |
- tab_delegate.GetSessionId()); |
+ SessionTab* session_tab = synced_session_tracker_.GetTab( |
+ GetCurrentMachineTag(), tab_delegate.GetSessionId().id()); |
SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); |
const GURL new_url = GetCurrentVirtualURL(tab_delegate); |
- DVLOG(1) << "Local tab " << tab_delegate.GetSessionId() |
- << " now has URL " << new_url.spec(); |
+ VLOG(1) << "Local tab " << tab_delegate.GetSessionId().id() << " now has URL " |
+ << new_url.spec(); |
// Trigger the favicon load if needed. We do this before opening the write |
// transaction to avoid jank. |
@@ -424,7 +472,6 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
// Update our last modified time. |
synced_session_tracker_.GetSession(GetCurrentMachineTag())->modified_time = |
base::Time::Now(); |
- |
syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
syncer::WriteNode tab_node(&trans); |
if (tab_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { |
@@ -436,7 +483,6 @@ 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) { |
@@ -449,7 +495,6 @@ bool SessionModelAssociator::WriteTabContentsToSyncModel( |
// Retain the base SessionSpecifics data (tag, tab_node_id, etc.), and just |
// write the new SessionTabSpecifics. |
specifics.mutable_tab()->CopyFrom(tab_s); |
- |
// Write into the actual sync model. |
tab_node.SetSessionSpecifics(specifics); |
@@ -462,12 +507,13 @@ void SessionModelAssociator::SetSessionTabFromDelegate( |
base::Time mtime, |
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->window_id.set_id(tab_delegate.GetWindowId().id()); |
+ session_tab->tab_id.set_id(tab_delegate.GetSessionId().id()); |
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->sync_session_id = tab_delegate.GetSyncSessionId(); |
session_tab->user_agent_override.clear(); |
session_tab->timestamp = mtime; |
const int current_index = tab_delegate.GetCurrentEntryIndex(); |
@@ -757,7 +803,8 @@ bool SessionModelAssociator::UpdateAssociationsFromSyncModel( |
// TODO(zea): fix this once we add support for reassociating |
// pre-existing tabs with pre-existing tab nodes. We'll need to load |
// the tab_node_id and ensure the tab_pool_ keeps track of them. |
- sync_node.Tombstone(); |
+ if (specifics.has_tab()) |
+ tab_pool_.AddTabNode(id, specifics.tab_node_id()); |
Nicolas Zea
2013/05/16 22:59:03
else tombstone? (it would be the above error case
shashi
2013/05/17 00:29:16
Good point, I should handle the case for multiple
|
} |
} |
id = next_id; |
@@ -1098,7 +1145,7 @@ bool SessionModelAssociator::IsValidTab(const SyncedTabDelegate& tab) const { |
} |
const SyncedWindowDelegate* window = |
SyncedWindowDelegate::FindSyncedWindowDelegateWithId( |
- tab.GetWindowId()); |
+ tab.GetWindowId().id()); |
if (!window && !setup_for_test_) |
return false; |
return true; |