| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/glue/session_model_associator.h" | 5 #include "chrome/browser/sync/glue/session_model_associator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 sync_pb::SessionHeader* header_s = specifics.mutable_header(); | 173 sync_pb::SessionHeader* header_s = specifics.mutable_header(); |
| 174 SyncedSession* current_session = | 174 SyncedSession* current_session = |
| 175 synced_session_tracker_.GetSession(local_tag); | 175 synced_session_tracker_.GetSession(local_tag); |
| 176 current_session->modified_time = base::Time::Now(); | 176 current_session->modified_time = base::Time::Now(); |
| 177 header_s->set_client_name(current_session_name_); | 177 header_s->set_client_name(current_session_name_); |
| 178 header_s->set_device_type(DeviceInfo::GetLocalDeviceType()); | 178 header_s->set_device_type(DeviceInfo::GetLocalDeviceType()); |
| 179 | 179 |
| 180 synced_session_tracker_.ResetSessionTracking(local_tag); | 180 synced_session_tracker_.ResetSessionTracking(local_tag); |
| 181 std::set<SyncedWindowDelegate*> windows = | 181 std::set<SyncedWindowDelegate*> windows = |
| 182 SyncedWindowDelegate::GetSyncedWindowDelegates(); | 182 SyncedWindowDelegate::GetSyncedWindowDelegates(); |
| 183 std::set<int64> used_sync_ids; |
| 183 for (std::set<SyncedWindowDelegate*>::const_iterator i = | 184 for (std::set<SyncedWindowDelegate*>::const_iterator i = |
| 184 windows.begin(); i != windows.end(); ++i) { | 185 windows.begin(); i != windows.end(); ++i) { |
| 185 // Make sure the window has tabs and a viewable window. The viewable window | 186 // Make sure the window has tabs and a viewable window. The viewable window |
| 186 // check is necessary because, for example, when a browser is closed the | 187 // check is necessary because, for example, when a browser is closed the |
| 187 // destructor is not necessarily run immediately. This means its possible | 188 // destructor is not necessarily run immediately. This means its possible |
| 188 // for us to get a handle to a browser that is about to be removed. If | 189 // for us to get a handle to a browser that is about to be removed. If |
| 189 // the tab count is 0 or the window is NULL, the browser is about to be | 190 // the tab count is 0 or the window is NULL, the browser is about to be |
| 190 // deleted, so we ignore it. | 191 // deleted, so we ignore it. |
| 191 if (ShouldSyncWindow(*i) && (*i)->GetTabCount() && (*i)->HasWindow()) { | 192 if (ShouldSyncWindow(*i) && (*i)->GetTabCount() && (*i)->HasWindow()) { |
| 192 sync_pb::SessionWindow window_s; | 193 sync_pb::SessionWindow window_s; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 203 sync_pb::SessionWindow_BrowserType_TYPE_TABBED); | 204 sync_pb::SessionWindow_BrowserType_TYPE_TABBED); |
| 204 } else { | 205 } else { |
| 205 window_s.set_browser_type( | 206 window_s.set_browser_type( |
| 206 sync_pb::SessionWindow_BrowserType_TYPE_POPUP); | 207 sync_pb::SessionWindow_BrowserType_TYPE_POPUP); |
| 207 } | 208 } |
| 208 | 209 |
| 209 // Store the order of tabs. | 210 // Store the order of tabs. |
| 210 bool found_tabs = false; | 211 bool found_tabs = false; |
| 211 for (int j = 0; j < (*i)->GetTabCount(); ++j) { | 212 for (int j = 0; j < (*i)->GetTabCount(); ++j) { |
| 212 SessionID::id_type tab_id = (*i)->GetTabIdAt(j); | 213 SessionID::id_type tab_id = (*i)->GetTabIdAt(j); |
| 214 SyncedTabDelegate* synced_tab = (*i)->GetTabAt(j); |
| 215 |
| 216 // GetTabAt can return a null tab; in that case just skip it. |
| 217 if (!synced_tab) |
| 218 continue; |
| 219 |
| 220 if (!synced_tab->HasWebContents()) { |
| 221 // For tabs without WebContents update the |tab_id|, as it could have |
| 222 // changed after a session restore. |
| 223 // Note: We cannot check if a tab is valid if it has no WebContents. |
| 224 // We assume any such tab is valid and leave the contents of |
| 225 // corresponding sync node unchanged. |
| 226 if (synced_tab->GetSyncId() > syncer::kInvalidId && |
| 227 tab_id > TabNodePool::kInvalidTabID) { |
| 228 UpdateTabIdIfNecessary(synced_tab->GetSyncId(), tab_id); |
| 229 found_tabs = true; |
| 230 used_sync_ids.insert(synced_tab->GetSyncId()); |
| 231 window_s.add_tab(tab_id); |
| 232 } |
| 233 continue; |
| 234 } |
| 213 | 235 |
| 214 if (reload_tabs) { | 236 if (reload_tabs) { |
| 215 SyncedTabDelegate* tab = (*i)->GetTabAt(j); | |
| 216 // It's possible for GetTabAt to return a tab which has no web | 237 // It's possible for GetTabAt to return a tab which has no web |
| 217 // contents. We can assume this means the tab already existed but | 238 // contents. We can assume this means the tab already existed but |
| 218 // hasn't changed, so no need to reassociate. | 239 // hasn't changed, so no need to reassociate. |
| 219 if (tab && tab->HasWebContents() && !AssociateTab(*tab, error)) { | 240 if (synced_tab->HasWebContents() && |
| 241 !AssociateTab(synced_tab, error)) { |
| 220 // Association failed. Either we need to re-associate, or this is an | 242 // Association failed. Either we need to re-associate, or this is an |
| 221 // unrecoverable error. | 243 // unrecoverable error. |
| 222 return false; | 244 return false; |
| 223 } | 245 } |
| 224 } | 246 } |
| 225 | 247 |
| 226 // If the tab is valid, it would have been added to the tracker either | 248 // If the tab is valid, it would have been added to the tracker either |
| 227 // by the above AssociateTab call (at association time), or by the | 249 // by the above AssociateTab call (at association time), or by the |
| 228 // change processor calling AssociateTab for all modified tabs. | 250 // change processor calling AssociateTab for all modified tabs. |
| 229 // Therefore, we can key whether this window has valid tabs based on | 251 // Therefore, we can key whether this window has valid tabs based on |
| 230 // the tab's presence in the tracker. | 252 // the tab's presence in the tracker. |
| 231 const SessionTab* tab = NULL; | 253 const SessionTab* tab = NULL; |
| 232 if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { | 254 if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { |
| 233 found_tabs = true; | 255 found_tabs = true; |
| 256 used_sync_ids.insert(synced_tab->GetSyncId()); |
| 234 window_s.add_tab(tab_id); | 257 window_s.add_tab(tab_id); |
| 235 } | 258 } |
| 236 } | 259 } |
| 237 // Only add a window if it contains valid tabs. | 260 // Only add a window if it contains valid tabs. |
| 238 if (found_tabs) { | 261 if (found_tabs) { |
| 239 sync_pb::SessionWindow* header_window = header_s->add_window(); | 262 sync_pb::SessionWindow* header_window = header_s->add_window(); |
| 240 *header_window = window_s; | 263 *header_window = window_s; |
| 241 | 264 |
| 242 // Update this window's representation in the synced session tracker. | 265 // Update this window's representation in the synced session tracker. |
| 243 synced_session_tracker_.PutWindowInSession(local_tag, window_id); | 266 synced_session_tracker_.PutWindowInSession(local_tag, window_id); |
| 244 PopulateSessionWindowFromSpecifics( | 267 PopulateSessionWindowFromSpecifics( |
| 245 local_tag, | 268 local_tag, |
| 246 window_s, | 269 window_s, |
| 247 base::Time::Now(), | 270 base::Time::Now(), |
| 248 current_session->windows[window_id], | 271 current_session->windows[window_id], |
| 249 &synced_session_tracker_); | 272 &synced_session_tracker_); |
| 250 } | 273 } |
| 251 } | 274 } |
| 252 } | 275 } |
| 276 |
| 277 // Free old sync nodes. |
| 278 tab_pool_.FreeUnusedTabNodes(used_sync_ids); |
| 253 // Free memory for closed windows and tabs. | 279 // Free memory for closed windows and tabs. |
| 254 synced_session_tracker_.CleanupSession(local_tag); | 280 synced_session_tracker_.CleanupSession(local_tag); |
| 255 | 281 |
| 256 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 282 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 257 syncer::WriteNode header_node(&trans); | 283 syncer::WriteNode header_node(&trans); |
| 258 if (header_node.InitByIdLookup(local_session_syncid_) != | 284 if (header_node.InitByIdLookup(local_session_syncid_) != |
| 259 syncer::BaseNode::INIT_OK) { | 285 syncer::BaseNode::INIT_OK) { |
| 260 if (error) { | 286 if (error) { |
| 261 *error = error_handler_->CreateAndUploadError( | 287 *error = error_handler_->CreateAndUploadError( |
| 262 FROM_HERE, | 288 FROM_HERE, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 278 return window->IsTypeTabbed() || window->IsTypePopup(); | 304 return window->IsTypeTabbed() || window->IsTypePopup(); |
| 279 } | 305 } |
| 280 | 306 |
| 281 bool SessionModelAssociator::AssociateTabs( | 307 bool SessionModelAssociator::AssociateTabs( |
| 282 const std::vector<SyncedTabDelegate*>& tabs, | 308 const std::vector<SyncedTabDelegate*>& tabs, |
| 283 syncer::SyncError* error) { | 309 syncer::SyncError* error) { |
| 284 DCHECK(CalledOnValidThread()); | 310 DCHECK(CalledOnValidThread()); |
| 285 for (std::vector<SyncedTabDelegate*>::const_iterator i = tabs.begin(); | 311 for (std::vector<SyncedTabDelegate*>::const_iterator i = tabs.begin(); |
| 286 i != tabs.end(); | 312 i != tabs.end(); |
| 287 ++i) { | 313 ++i) { |
| 288 if (!AssociateTab(**i, error)) | 314 if (!AssociateTab(*i, error)) |
| 289 return false; | 315 return false; |
| 290 } | 316 } |
| 291 if (waiting_for_change_) QuitLoopForSubtleTesting(); | 317 if (waiting_for_change_) QuitLoopForSubtleTesting(); |
| 292 return true; | 318 return true; |
| 293 } | 319 } |
| 294 | 320 |
| 295 bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab, | 321 bool SessionModelAssociator::AssociateTab(SyncedTabDelegate* const tab, |
| 296 syncer::SyncError* error) { | 322 syncer::SyncError* error) { |
| 297 DCHECK(CalledOnValidThread()); | 323 DCHECK(CalledOnValidThread()); |
| 324 DCHECK(tab->HasWebContents()); |
| 298 int64 sync_id; | 325 int64 sync_id; |
| 299 SessionID::id_type tab_id = tab.GetSessionId(); | 326 SessionID::id_type tab_id = tab->GetSessionId(); |
| 300 if (tab.IsBeingDestroyed()) { | 327 if (tab->IsBeingDestroyed()) { |
| 301 // This tab is closing. | 328 // This tab is closing. |
| 302 TabLinksMap::iterator tab_iter = tab_map_.find(tab_id); | 329 TabLinksMap::iterator tab_iter = tab_map_.find(tab_id); |
| 303 if (tab_iter == tab_map_.end()) { | 330 if (tab_iter == tab_map_.end()) { |
| 304 // We aren't tracking this tab (for example, sync setting page). | 331 // We aren't tracking this tab (for example, sync setting page). |
| 305 return true; | 332 return true; |
| 306 } | 333 } |
| 307 tab_pool_.FreeTabNode(tab_iter->second->sync_id()); | 334 tab_pool_.FreeTabNode(tab_iter->second->sync_id()); |
| 308 tab_map_.erase(tab_iter); | 335 tab_map_.erase(tab_iter); |
| 309 return true; | 336 return true; |
| 310 } | 337 } |
| 311 | 338 |
| 312 if (!ShouldSyncTab(tab)) | 339 if (!ShouldSyncTab(*tab)) |
| 313 return true; | 340 return true; |
| 314 | 341 |
| 315 TabLinksMap::iterator tab_map_iter = tab_map_.find(tab_id); | 342 TabLinksMap::iterator tab_map_iter = tab_map_.find(tab_id); |
| 316 TabLink* tab_link = NULL; | 343 TabLink* tab_link = NULL; |
| 317 if (tab_map_iter == tab_map_.end()) { | 344 if (tab_map_iter == tab_map_.end()) { |
| 318 // This is a new tab, get a sync node for it. | 345 sync_id = tab->GetSyncId(); |
| 319 sync_id = tab_pool_.GetFreeTabNode(); | 346 // if there is an old sync node for the tab, reuse it. |
| 320 if (sync_id == syncer::kInvalidId) { | 347 if (!tab_pool_.ReassociateTabNode(sync_id, tab_id)) { |
| 321 if (error) { | 348 // This is a new tab, get a sync node for it. |
| 322 *error = error_handler_->CreateAndUploadError( | 349 sync_id = tab_pool_.GetFreeTabNode(); |
| 323 FROM_HERE, | 350 if (sync_id == syncer::kInvalidId) { |
| 324 "Received invalid tab node from tab pool.", | 351 if (error) { |
| 325 model_type()); | 352 *error = error_handler_->CreateAndUploadError( |
| 353 FROM_HERE, |
| 354 "Received invalid tab node from tab pool.", |
| 355 model_type()); |
| 356 } |
| 357 return false; |
| 326 } | 358 } |
| 327 return false; | 359 tab_pool_.AssociateTabNode(sync_id, tab_id); |
| 360 tab->SetSyncId(sync_id); |
| 328 } | 361 } |
| 329 tab_link = new TabLink(sync_id, &tab); | 362 tab_link = new TabLink(sync_id, tab); |
| 330 tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link); | 363 tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link); |
| 331 } else { | 364 } else { |
| 332 // This tab is already associated with a sync node, reuse it. | 365 // This tab is already associated with a sync node, reuse it. |
| 333 // Note: on some platforms the tab object may have changed, so we ensure | 366 // Note: on some platforms the tab object may have changed, so we ensure |
| 334 // the tab link is up to date. | 367 // the tab link is up to date. |
| 335 tab_link = tab_map_iter->second.get(); | 368 tab_link = tab_map_iter->second.get(); |
| 336 tab_map_iter->second->set_tab(&tab); | 369 tab_map_iter->second->set_tab(tab); |
| 337 } | 370 } |
| 338 DCHECK(tab_link); | 371 DCHECK(tab_link); |
| 339 DCHECK_NE(tab_link->sync_id(), syncer::kInvalidId); | 372 DCHECK_NE(tab_link->sync_id(), syncer::kInvalidId); |
| 340 | 373 |
| 341 DVLOG(1) << "Reloading tab " << tab_id << " from window " | 374 DVLOG(1) << "Reloading tab " << tab_id << " from window " |
| 342 << tab.GetWindowId(); | 375 << tab->GetWindowId(); |
| 343 return WriteTabContentsToSyncModel(tab_link, error); | 376 return WriteTabContentsToSyncModel(tab_link, error); |
| 344 } | 377 } |
| 345 | 378 |
| 346 // static | 379 // static |
| 347 GURL SessionModelAssociator::GetCurrentVirtualURL( | 380 GURL SessionModelAssociator::GetCurrentVirtualURL( |
| 348 const SyncedTabDelegate& tab_delegate) { | 381 const SyncedTabDelegate& tab_delegate) { |
| 349 const int current_index = tab_delegate.GetCurrentEntryIndex(); | 382 const int current_index = tab_delegate.GetCurrentEntryIndex(); |
| 350 const int pending_index = tab_delegate.GetPendingEntryIndex(); | 383 const int pending_index = tab_delegate.GetPendingEntryIndex(); |
| 351 const NavigationEntry* current_entry = | 384 const NavigationEntry* current_entry = |
| 352 (current_index == pending_index) ? | 385 (current_index == pending_index) ? |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 } | 579 } |
| 547 | 580 |
| 548 syncer::SyncError SessionModelAssociator::AssociateModels( | 581 syncer::SyncError SessionModelAssociator::AssociateModels( |
| 549 syncer::SyncMergeResult* local_merge_result, | 582 syncer::SyncMergeResult* local_merge_result, |
| 550 syncer::SyncMergeResult* syncer_merge_result) { | 583 syncer::SyncMergeResult* syncer_merge_result) { |
| 551 DCHECK(CalledOnValidThread()); | 584 DCHECK(CalledOnValidThread()); |
| 552 syncer::SyncError error; | 585 syncer::SyncError error; |
| 553 | 586 |
| 554 // Ensure that we disassociated properly, otherwise memory might leak. | 587 // Ensure that we disassociated properly, otherwise memory might leak. |
| 555 DCHECK(synced_session_tracker_.Empty()); | 588 DCHECK(synced_session_tracker_.Empty()); |
| 556 DCHECK_EQ(0U, tab_pool_.capacity()); | 589 DCHECK_EQ(0U, tab_pool_.Capacity()); |
| 557 | 590 |
| 558 local_session_syncid_ = syncer::kInvalidId; | 591 local_session_syncid_ = syncer::kInvalidId; |
| 559 | 592 |
| 560 scoped_ptr<DeviceInfo> local_device_info(sync_service_->GetLocalDeviceInfo()); | 593 scoped_ptr<DeviceInfo> local_device_info(sync_service_->GetLocalDeviceInfo()); |
| 561 | 594 |
| 562 #if defined(OS_ANDROID) | 595 #if defined(OS_ANDROID) |
| 563 std::string transaction_tag; | 596 std::string transaction_tag; |
| 564 #endif | 597 #endif |
| 565 // Read any available foreign sessions and load any session data we may have. | 598 // Read any available foreign sessions and load any session data we may have. |
| 566 // If we don't have any local session data in the db, create a header node. | 599 // If we don't have any local session data in the db, create a header node. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 DCHECK(!error.IsSet()); | 675 DCHECK(!error.IsSet()); |
| 643 return error; | 676 return error; |
| 644 } | 677 } |
| 645 | 678 |
| 646 syncer::SyncError SessionModelAssociator::DisassociateModels() { | 679 syncer::SyncError SessionModelAssociator::DisassociateModels() { |
| 647 DCHECK(CalledOnValidThread()); | 680 DCHECK(CalledOnValidThread()); |
| 648 DVLOG(1) << "Disassociating local session " << GetCurrentMachineTag(); | 681 DVLOG(1) << "Disassociating local session " << GetCurrentMachineTag(); |
| 649 favicon_cache_.RemoveLegacyDelegate(); | 682 favicon_cache_.RemoveLegacyDelegate(); |
| 650 synced_session_tracker_.Clear(); | 683 synced_session_tracker_.Clear(); |
| 651 tab_map_.clear(); | 684 tab_map_.clear(); |
| 652 tab_pool_.clear(); | 685 tab_pool_.Clear(); |
| 653 local_session_syncid_ = syncer::kInvalidId; | 686 local_session_syncid_ = syncer::kInvalidId; |
| 654 current_machine_tag_ = ""; | 687 current_machine_tag_ = ""; |
| 655 current_session_name_ = ""; | 688 current_session_name_ = ""; |
| 656 | 689 |
| 657 // There is no local model stored with which to disassociate, just notify | 690 // There is no local model stored with which to disassociate, just notify |
| 658 // foreign session handlers. | 691 // foreign session handlers. |
| 659 content::NotificationService::current()->Notify( | 692 content::NotificationService::current()->Notify( |
| 660 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, | 693 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, |
| 661 content::Source<Profile>(sync_service_->profile()), | 694 content::Source<Profile>(sync_service_->profile()), |
| 662 content::NotificationService::NoDetails()); | 695 content::NotificationService::NoDetails()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 673 if (!persisted_guid.empty()) { | 706 if (!persisted_guid.empty()) { |
| 674 current_machine_tag_ = persisted_guid; | 707 current_machine_tag_ = persisted_guid; |
| 675 DVLOG(1) << "Restoring persisted session sync guid: " | 708 DVLOG(1) << "Restoring persisted session sync guid: " |
| 676 << persisted_guid; | 709 << persisted_guid; |
| 677 } else { | 710 } else { |
| 678 current_machine_tag_ = GetMachineTagFromTransaction(trans); | 711 current_machine_tag_ = GetMachineTagFromTransaction(trans); |
| 679 DVLOG(1) << "Creating session sync guid: " << current_machine_tag_; | 712 DVLOG(1) << "Creating session sync guid: " << current_machine_tag_; |
| 680 prefs.SetSyncSessionsGUID(current_machine_tag_); | 713 prefs.SetSyncSessionsGUID(current_machine_tag_); |
| 681 } | 714 } |
| 682 | 715 |
| 683 tab_pool_.set_machine_tag(current_machine_tag_); | 716 tab_pool_.SetMachineTag(current_machine_tag_); |
| 684 } | 717 } |
| 685 | 718 |
| 686 bool SessionModelAssociator::GetSyncedFaviconForPageURL( | 719 bool SessionModelAssociator::GetSyncedFaviconForPageURL( |
| 687 const std::string& page_url, | 720 const std::string& page_url, |
| 688 scoped_refptr<base::RefCountedMemory>* favicon_png) const { | 721 scoped_refptr<base::RefCountedMemory>* favicon_png) const { |
| 689 return favicon_cache_.GetSyncedFaviconForPageURL(GURL(page_url), favicon_png); | 722 return favicon_cache_.GetSyncedFaviconForPageURL(GURL(page_url), favicon_png); |
| 690 } | 723 } |
| 691 | 724 |
| 692 bool SessionModelAssociator::UpdateAssociationsFromSyncModel( | 725 bool SessionModelAssociator::UpdateAssociationsFromSyncModel( |
| 693 const syncer::ReadNode& root, | 726 const syncer::ReadNode& root, |
| 694 syncer::WriteTransaction* trans, | 727 syncer::WriteTransaction* trans, |
| 695 syncer::SyncError* error) { | 728 syncer::SyncError* error) { |
| 696 DCHECK(CalledOnValidThread()); | 729 DCHECK(CalledOnValidThread()); |
| 697 DCHECK(tab_pool_.empty()); | 730 DCHECK(tab_pool_.Empty()); |
| 698 DCHECK_EQ(local_session_syncid_, syncer::kInvalidId); | 731 DCHECK_EQ(local_session_syncid_, syncer::kInvalidId); |
| 699 | 732 |
| 700 // Iterate through the nodes and associate any foreign sessions. | 733 // Iterate through the nodes and associate any foreign sessions. |
| 701 int64 id = root.GetFirstChildId(); | 734 int64 id = root.GetFirstChildId(); |
| 702 while (id != syncer::kInvalidId) { | 735 while (id != syncer::kInvalidId) { |
| 703 syncer::WriteNode sync_node(trans); | 736 syncer::WriteNode sync_node(trans); |
| 704 if (sync_node.InitByIdLookup(id) != syncer::BaseNode::INIT_OK) { | 737 if (sync_node.InitByIdLookup(id) != syncer::BaseNode::INIT_OK) { |
| 705 if (error) { | 738 if (error) { |
| 706 *error = error_handler_->CreateAndUploadError( | 739 *error = error_handler_->CreateAndUploadError( |
| 707 FROM_HERE, | 740 FROM_HERE, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 724 } else { | 757 } else { |
| 725 // This is previously stored local session information. | 758 // This is previously stored local session information. |
| 726 if (specifics.has_header() && | 759 if (specifics.has_header() && |
| 727 local_session_syncid_ == syncer::kInvalidId) { | 760 local_session_syncid_ == syncer::kInvalidId) { |
| 728 // This is our previous header node, reuse it. | 761 // This is our previous header node, reuse it. |
| 729 local_session_syncid_ = id; | 762 local_session_syncid_ = id; |
| 730 if (specifics.header().has_client_name()) { | 763 if (specifics.header().has_client_name()) { |
| 731 current_session_name_ = specifics.header().client_name(); | 764 current_session_name_ = specifics.header().client_name(); |
| 732 } | 765 } |
| 733 } else { | 766 } else { |
| 734 if (specifics.has_header()) { | 767 if (specifics.has_header() || !specifics.has_tab() || |
| 735 LOG(WARNING) << "Found more than one session header node with local " | 768 !specifics.has_tab_node_id() || !specifics.tab().has_tab_id()) { |
| 736 << " tag."; | 769 LOG(WARNING) << "Found invalid session node, deleting."; |
| 737 } else if (!specifics.has_tab()) { | 770 sync_node.Tombstone(); |
| 738 LOG(WARNING) << "Found local node with no header or tag field."; | 771 } else { |
| 772 // This is a valid old tab node, add it to the pool so it can be |
| 773 // reused for reassociation. |
| 774 SessionID tab_id; |
| 775 tab_id.set_id(specifics.tab().tab_id()); |
| 776 tab_pool_.AddTabNode(id, tab_id, specifics.tab_node_id()); |
| 739 } | 777 } |
| 740 | |
| 741 // TODO(zea): fix this once we add support for reassociating | |
| 742 // pre-existing tabs with pre-existing tab nodes. We'll need to load | |
| 743 // the tab_node_id and ensure the tab_pool_ keeps track of them. | |
| 744 sync_node.Tombstone(); | |
| 745 } | 778 } |
| 746 } | 779 } |
| 747 id = next_id; | 780 id = next_id; |
| 748 } | 781 } |
| 749 | 782 |
| 750 // After updating from sync model all tabid's should be free. | |
| 751 DCHECK(tab_pool_.full()); | |
| 752 return true; | 783 return true; |
| 753 } | 784 } |
| 754 | 785 |
| 755 void SessionModelAssociator::AssociateForeignSpecifics( | 786 void SessionModelAssociator::AssociateForeignSpecifics( |
| 756 const sync_pb::SessionSpecifics& specifics, | 787 const sync_pb::SessionSpecifics& specifics, |
| 757 const base::Time& modification_time) { | 788 const base::Time& modification_time) { |
| 758 DCHECK(CalledOnValidThread()); | 789 DCHECK(CalledOnValidThread()); |
| 759 std::string foreign_session_tag = specifics.session_tag(); | 790 std::string foreign_session_tag = specifics.session_tag(); |
| 760 if (foreign_session_tag == GetCurrentMachineTag() && !setup_for_test_) | 791 if (foreign_session_tag == GetCurrentMachineTag() && !setup_for_test_) |
| 761 return; | 792 return; |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 } | 1175 } |
| 1145 | 1176 |
| 1146 bool SessionModelAssociator::CryptoReadyIfNecessary() { | 1177 bool SessionModelAssociator::CryptoReadyIfNecessary() { |
| 1147 // We only access the cryptographer while holding a transaction. | 1178 // We only access the cryptographer while holding a transaction. |
| 1148 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 1179 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 1149 const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); | 1180 const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); |
| 1150 return !encrypted_types.Has(SESSIONS) || | 1181 return !encrypted_types.Has(SESSIONS) || |
| 1151 sync_service_->IsCryptographerReady(&trans); | 1182 sync_service_->IsCryptographerReady(&trans); |
| 1152 } | 1183 } |
| 1153 | 1184 |
| 1185 void SessionModelAssociator::UpdateTabIdIfNecessary( |
| 1186 int64 sync_id, |
| 1187 SessionID::id_type new_tab_id) { |
| 1188 DCHECK_NE(sync_id, syncer::kInvalidId); |
| 1189 SessionID::id_type old_tab_id = tab_pool_.GetTabIdFromSyncId(sync_id); |
| 1190 if (old_tab_id != new_tab_id) { |
| 1191 // Rewrite tab id if required. |
| 1192 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 1193 syncer::WriteNode tab_node(&trans); |
| 1194 if (tab_node.InitByIdLookup(sync_id) == syncer::BaseNode::INIT_OK) { |
| 1195 sync_pb::SessionSpecifics session_specifics = |
| 1196 tab_node.GetSessionSpecifics(); |
| 1197 DCHECK(session_specifics.has_tab()); |
| 1198 if (session_specifics.has_tab()) { |
| 1199 sync_pb::SessionTab* tab_s = session_specifics.mutable_tab(); |
| 1200 tab_s->set_tab_id(new_tab_id); |
| 1201 tab_node.SetSessionSpecifics(session_specifics); |
| 1202 // Update tab node pool with the new association. |
| 1203 tab_pool_.ReassociateTabNode(sync_id, new_tab_id); |
| 1204 } |
| 1205 } |
| 1206 } |
| 1207 } |
| 1208 |
| 1154 } // namespace browser_sync | 1209 } // namespace browser_sync |
| OLD | NEW |