Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/sync_sessions/sessions_sync_manager.h" | 5 #include "components/sync_sessions/sessions_sync_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 merge_result.set_error(error_handler_->CreateAndUploadError( | 149 merge_result.set_error(error_handler_->CreateAndUploadError( |
| 150 FROM_HERE, "Failed to get local device info.")); | 150 FROM_HERE, "Failed to get local device info.")); |
| 151 return merge_result; | 151 return merge_result; |
| 152 } | 152 } |
| 153 | 153 |
| 154 session_tracker_.SetLocalSessionTag(current_machine_tag_); | 154 session_tracker_.SetLocalSessionTag(current_machine_tag_); |
| 155 | 155 |
| 156 syncer::SyncChangeList new_changes; | 156 syncer::SyncChangeList new_changes; |
| 157 | 157 |
| 158 // First, we iterate over sync data to update our session_tracker_. | 158 // First, we iterate over sync data to update our session_tracker_. |
| 159 syncer::SyncDataList restored_tabs; | 159 if (!InitFromSyncModel(initial_sync_data, &new_changes)) { |
| 160 if (!InitFromSyncModel(initial_sync_data, &restored_tabs, &new_changes)) { | |
| 161 // The sync db didn't have a header node for us. Create one. | 160 // The sync db didn't have a header node for us. Create one. |
| 162 sync_pb::EntitySpecifics specifics; | 161 sync_pb::EntitySpecifics specifics; |
| 163 sync_pb::SessionSpecifics* base_specifics = specifics.mutable_session(); | 162 sync_pb::SessionSpecifics* base_specifics = specifics.mutable_session(); |
| 164 base_specifics->set_session_tag(current_machine_tag()); | 163 base_specifics->set_session_tag(current_machine_tag()); |
| 165 sync_pb::SessionHeader* header_s = base_specifics->mutable_header(); | 164 sync_pb::SessionHeader* header_s = base_specifics->mutable_header(); |
| 166 header_s->set_client_name(current_session_name_); | 165 header_s->set_client_name(current_session_name_); |
| 167 header_s->set_device_type(local_device_info->device_type()); | 166 header_s->set_device_type(local_device_info->device_type()); |
| 168 syncer::SyncData data = syncer::SyncData::CreateLocalData( | 167 syncer::SyncData data = syncer::SyncData::CreateLocalData( |
| 169 current_machine_tag(), current_session_name_, specifics); | 168 current_machine_tag(), current_session_name_, specifics); |
| 170 new_changes.push_back( | 169 new_changes.push_back( |
| 171 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | 170 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); |
| 172 } | 171 } |
| 173 | 172 |
| 174 #if defined(OS_ANDROID) | 173 #if defined(OS_ANDROID) |
| 175 std::string sync_machine_tag( | 174 std::string sync_machine_tag( |
| 176 BuildMachineTag(local_device_->GetLocalSyncCacheGUID())); | 175 BuildMachineTag(local_device_->GetLocalSyncCacheGUID())); |
| 177 if (current_machine_tag_.compare(sync_machine_tag) != 0) | 176 if (current_machine_tag_.compare(sync_machine_tag) != 0) |
| 178 DeleteForeignSessionInternal(sync_machine_tag, &new_changes); | 177 DeleteForeignSessionInternal(sync_machine_tag, &new_changes); |
| 179 #endif | 178 #endif |
| 180 | 179 |
| 181 // Check if anything has changed on the local client side. | 180 // Check if anything has changed on the local client side. |
| 182 AssociateWindows(RELOAD_TABS, restored_tabs, &new_changes); | 181 AssociateWindows(RELOAD_TABS, &new_changes); |
| 183 local_tab_pool_out_of_sync_ = false; | 182 local_tab_pool_out_of_sync_ = false; |
| 184 | 183 |
| 185 merge_result.set_error( | 184 merge_result.set_error( |
| 186 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 185 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); |
| 187 | 186 |
| 188 local_event_router_->StartRoutingTo(this); | 187 local_event_router_->StartRoutingTo(this); |
| 189 return merge_result; | 188 return merge_result; |
| 190 } | 189 } |
| 191 | 190 |
| 192 void SessionsSyncManager::AssociateWindows( | 191 void SessionsSyncManager::AssociateWindows( |
| 193 ReloadTabsOption option, | 192 ReloadTabsOption option, |
| 194 const syncer::SyncDataList& restored_tabs, | |
| 195 syncer::SyncChangeList* change_output) { | 193 syncer::SyncChangeList* change_output) { |
| 196 const std::string local_tag = current_machine_tag(); | 194 const std::string local_tag = current_machine_tag(); |
| 197 sync_pb::SessionSpecifics specifics; | 195 sync_pb::SessionSpecifics specifics; |
| 198 specifics.set_session_tag(local_tag); | 196 specifics.set_session_tag(local_tag); |
| 199 sync_pb::SessionHeader* header_s = specifics.mutable_header(); | 197 sync_pb::SessionHeader* header_s = specifics.mutable_header(); |
| 200 SyncedSession* current_session = session_tracker_.GetSession(local_tag); | 198 SyncedSession* current_session = session_tracker_.GetSession(local_tag); |
| 201 current_session->modified_time = base::Time::Now(); | 199 current_session->modified_time = base::Time::Now(); |
| 202 header_s->set_client_name(current_session_name_); | 200 header_s->set_client_name(current_session_name_); |
| 203 // SessionDataTypeController ensures that the local device info | 201 // SessionDataTypeController ensures that the local device info |
| 204 // is available before activating this datatype. | 202 // is available before activating this datatype. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 | 264 |
| 267 if (synced_tab->IsPlaceholderTab()) { | 265 if (synced_tab->IsPlaceholderTab()) { |
| 268 // For tabs without WebContents update the |tab_id| and |window_id|, | 266 // For tabs without WebContents update the |tab_id| and |window_id|, |
| 269 // as it could have changed after a session restore. | 267 // as it could have changed after a session restore. |
| 270 // Note: We cannot check if a tab is valid if it has no WebContents. | 268 // Note: We cannot check if a tab is valid if it has no WebContents. |
| 271 // We assume any such tab is valid and leave the contents of | 269 // We assume any such tab is valid and leave the contents of |
| 272 // corresponding sync node unchanged. | 270 // corresponding sync node unchanged. |
| 273 if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID && | 271 if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID && |
| 274 tab_id > TabNodePool::kInvalidTabID) { | 272 tab_id > TabNodePool::kInvalidTabID) { |
| 275 AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id, | 273 AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id, |
| 276 restored_tabs, change_output); | 274 change_output); |
| 277 found_tabs = true; | 275 found_tabs = true; |
| 278 window_s.add_tab(tab_id); | 276 window_s.add_tab(tab_id); |
| 279 } | 277 } |
| 280 continue; | 278 continue; |
| 281 } | 279 } |
| 282 | 280 |
| 283 if (RELOAD_TABS == option) | 281 if (RELOAD_TABS == option) |
| 284 AssociateTab(synced_tab, change_output); | 282 AssociateTab(synced_tab, change_output); |
| 285 | 283 |
| 286 // If the tab is valid, it would have been added to the tracker either | 284 // If the tab is valid, it would have been added to the tracker either |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 | 343 |
| 346 if (local_tab_map_iter == local_tab_map_.end()) { | 344 if (local_tab_map_iter == local_tab_map_.end()) { |
| 347 int tab_node_id = tab->GetSyncId(); | 345 int tab_node_id = tab->GetSyncId(); |
| 348 // If there is an old sync node for the tab, reuse it. If this is a new | 346 // If there is an old sync node for the tab, reuse it. If this is a new |
| 349 // tab, get a sync node for it. | 347 // tab, get a sync node for it. |
| 350 if (!local_tab_pool_.IsUnassociatedTabNode(tab_node_id)) { | 348 if (!local_tab_pool_.IsUnassociatedTabNode(tab_node_id)) { |
| 351 tab_node_id = local_tab_pool_.GetFreeTabNode(change_output); | 349 tab_node_id = local_tab_pool_.GetFreeTabNode(change_output); |
| 352 tab->SetSyncId(tab_node_id); | 350 tab->SetSyncId(tab_node_id); |
| 353 } | 351 } |
| 354 local_tab_pool_.AssociateTabNode(tab_node_id, tab_id); | 352 local_tab_pool_.AssociateTabNode(tab_node_id, tab_id); |
| 355 tab_link = new TabLink(tab_node_id, tab); | 353 tab_link = new TabLink(tab_node_id); |
| 356 local_tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link); | 354 local_tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link); |
| 357 } else { | 355 } else { |
| 358 // This tab is already associated with a sync node, reuse it. | 356 // This tab is already associated with a sync node, reuse it. |
| 359 // Note: on some platforms the tab object may have changed, so we ensure | 357 // Note: on some platforms the tab object may have changed, so we ensure |
|
maxbogue
2016/11/10 06:43:25
This note is now obsolete.
Nicolas Zea
2016/11/10 18:25:36
Done.
| |
| 360 // the tab link is up to date. | 358 // the tab link is up to date. |
| 361 tab_link = local_tab_map_iter->second.get(); | 359 tab_link = local_tab_map_iter->second.get(); |
| 362 local_tab_map_iter->second->set_tab(tab); | |
| 363 } | 360 } |
| 364 DCHECK(tab_link); | 361 DCHECK(tab_link); |
| 365 DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID); | 362 DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID); |
| 366 DVLOG(1) << "Reloading tab " << tab_id << " from window " | 363 DVLOG(1) << "Reloading tab " << tab_id << " from window " |
| 367 << tab->GetWindowId(); | 364 << tab->GetWindowId(); |
| 368 | 365 |
| 369 // Write to sync model. | 366 // Write to sync model. |
| 370 sync_pb::EntitySpecifics specifics; | 367 sync_pb::EntitySpecifics specifics; |
| 371 LocalTabDelegateToSpecifics(*tab, specifics.mutable_session()); | 368 LocalTabDelegateToSpecifics(*tab, specifics.mutable_session()); |
| 372 syncer::SyncData data = syncer::SyncData::CreateLocalData( | 369 syncer::SyncData data = syncer::SyncData::CreateLocalData( |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 DCHECK(!local_tab_pool_out_of_sync_); | 435 DCHECK(!local_tab_pool_out_of_sync_); |
| 439 return; | 436 return; |
| 440 } | 437 } |
| 441 | 438 |
| 442 syncer::SyncChangeList changes; | 439 syncer::SyncChangeList changes; |
| 443 AssociateTab(modified_tab, &changes); | 440 AssociateTab(modified_tab, &changes); |
| 444 // Note, we always associate windows because it's possible a tab became | 441 // Note, we always associate windows because it's possible a tab became |
| 445 // "interesting" by going to a valid URL, in which case it needs to be added | 442 // "interesting" by going to a valid URL, in which case it needs to be added |
| 446 // to the window's tab information. Similarly, if a tab became | 443 // to the window's tab information. Similarly, if a tab became |
| 447 // "uninteresting", we remove it from the window's tab information. | 444 // "uninteresting", we remove it from the window's tab information. |
| 448 AssociateWindows(DONT_RELOAD_TABS, syncer::SyncDataList(), &changes); | 445 AssociateWindows(DONT_RELOAD_TABS, &changes); |
| 449 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 446 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 450 } | 447 } |
| 451 | 448 |
| 452 void SessionsSyncManager::OnFaviconsChanged(const std::set<GURL>& page_urls, | 449 void SessionsSyncManager::OnFaviconsChanged(const std::set<GURL>& page_urls, |
| 453 const GURL& /* icon_url */) { | 450 const GURL& /* icon_url */) { |
| 454 // TODO(zea): consider a separate container for tabs with outstanding favicon | 451 // TODO(zea): consider a separate container for tabs with outstanding favicon |
| 455 // loads so we don't have to iterate through all tabs comparing urls. | 452 // loads so we don't have to iterate through all tabs comparing urls. |
| 456 for (const GURL& page_url : page_urls) { | 453 for (const GURL& page_url : page_urls) { |
| 457 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); | 454 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); |
| 458 tab_iter != local_tab_map_.end(); ++tab_iter) { | 455 tab_iter != local_tab_map_.end(); ++tab_iter) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 break; | 570 break; |
| 574 case syncer::SyncChange::ACTION_ADD: | 571 case syncer::SyncChange::ACTION_ADD: |
| 575 case syncer::SyncChange::ACTION_UPDATE: | 572 case syncer::SyncChange::ACTION_UPDATE: |
| 576 if (current_machine_tag() == session.session_tag()) { | 573 if (current_machine_tag() == session.session_tag()) { |
| 577 // We should only ever receive a change to our own machine's session | 574 // We should only ever receive a change to our own machine's session |
| 578 // info if encryption was turned on. In that case, the data is still | 575 // info if encryption was turned on. In that case, the data is still |
| 579 // the same, so we can ignore. | 576 // the same, so we can ignore. |
| 580 LOG(WARNING) << "Dropping modification to local session."; | 577 LOG(WARNING) << "Dropping modification to local session."; |
| 581 return syncer::SyncError(); | 578 return syncer::SyncError(); |
| 582 } | 579 } |
| 583 UpdateTrackerWithForeignSession( | 580 UpdateTrackerWithSpecifics( |
| 584 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); | 581 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); |
| 585 break; | 582 break; |
| 586 default: | 583 default: |
| 587 NOTREACHED() << "Processing sync changes failed, unknown change type."; | 584 NOTREACHED() << "Processing sync changes failed, unknown change type."; |
| 588 } | 585 } |
| 589 } | 586 } |
| 590 | 587 |
| 591 if (!sessions_updated_callback_.is_null()) | 588 if (!sessions_updated_callback_.is_null()) |
| 592 sessions_updated_callback_.Run(); | 589 sessions_updated_callback_.Run(); |
| 593 return syncer::SyncError(); | 590 return syncer::SyncError(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 611 std::vector<const SyncedSession*>* sessions) { | 608 std::vector<const SyncedSession*>* sessions) { |
| 612 if (!session_tracker_.LookupAllForeignSessions( | 609 if (!session_tracker_.LookupAllForeignSessions( |
| 613 sessions, SyncedSessionTracker::PRESENTABLE)) | 610 sessions, SyncedSessionTracker::PRESENTABLE)) |
| 614 return false; | 611 return false; |
| 615 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); | 612 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); |
| 616 return true; | 613 return true; |
| 617 } | 614 } |
| 618 | 615 |
| 619 bool SessionsSyncManager::InitFromSyncModel( | 616 bool SessionsSyncManager::InitFromSyncModel( |
| 620 const syncer::SyncDataList& sync_data, | 617 const syncer::SyncDataList& sync_data, |
| 621 syncer::SyncDataList* restored_tabs, | |
| 622 syncer::SyncChangeList* new_changes) { | 618 syncer::SyncChangeList* new_changes) { |
| 623 bool found_current_header = false; | 619 bool found_current_header = false; |
| 624 int bad_foreign_hash_count = 0; | 620 int bad_foreign_hash_count = 0; |
| 625 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | 621 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); |
| 626 it != sync_data.end(); ++it) { | 622 it != sync_data.end(); ++it) { |
| 627 const syncer::SyncData& data = *it; | 623 const syncer::SyncData& data = *it; |
| 628 DCHECK(data.GetSpecifics().has_session()); | 624 DCHECK(data.GetSpecifics().has_session()); |
| 629 syncer::SyncDataRemote remote(data); | 625 syncer::SyncDataRemote remote(data); |
| 630 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); | 626 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); |
| 631 if (specifics.session_tag().empty() || | 627 if (specifics.session_tag().empty() || |
| 632 (specifics.has_tab() && | 628 (specifics.has_tab() && |
| 633 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { | 629 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { |
| 634 syncer::SyncChange tombstone(TombstoneTab(specifics)); | 630 syncer::SyncChange tombstone(TombstoneTab(specifics)); |
| 635 if (tombstone.IsValid()) | 631 if (tombstone.IsValid()) |
| 636 new_changes->push_back(tombstone); | 632 new_changes->push_back(tombstone); |
| 637 } else if (specifics.session_tag() != current_machine_tag()) { | 633 } else if (specifics.session_tag() != current_machine_tag()) { |
| 638 if (TagHashFromSpecifics(specifics) == remote.GetClientTagHash()) { | 634 if (TagHashFromSpecifics(specifics) == remote.GetClientTagHash()) { |
| 639 UpdateTrackerWithForeignSession(specifics, remote.GetModifiedTime()); | 635 UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime()); |
| 640 } else { | 636 } else { |
| 641 // In the past, like years ago, we believe that some session data was | 637 // In the past, like years ago, we believe that some session data was |
| 642 // created with bad tag hashes. This causes any change this client makes | 638 // created with bad tag hashes. This causes any change this client makes |
| 643 // to that foreign data (like deletion through garbage collection) to | 639 // to that foreign data (like deletion through garbage collection) to |
| 644 // trigger a data type error because the tag looking mechanism fails. So | 640 // trigger a data type error because the tag looking mechanism fails. So |
| 645 // look for these and delete via remote SyncData, which uses a server id | 641 // look for these and delete via remote SyncData, which uses a server id |
| 646 // lookup mechanism instead, see crbug.com/604657. | 642 // lookup mechanism instead, see crbug.com/604657. |
| 647 bad_foreign_hash_count++; | 643 bad_foreign_hash_count++; |
| 648 new_changes->push_back( | 644 new_changes->push_back( |
| 649 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, remote)); | 645 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, remote)); |
| 650 } | 646 } |
| 651 } else { | 647 } else { |
| 652 // This is previously stored local session information. | 648 // This is previously stored local session information. |
| 653 if (specifics.has_header() && !found_current_header) { | 649 if (specifics.has_header() && !found_current_header) { |
| 654 // This is our previous header node, reuse it. | 650 // This is our previous header node, reuse it. |
| 655 found_current_header = true; | 651 found_current_header = true; |
| 656 if (specifics.header().has_client_name()) | 652 if (specifics.header().has_client_name()) |
| 657 current_session_name_ = specifics.header().client_name(); | 653 current_session_name_ = specifics.header().client_name(); |
| 654 | |
| 655 // TODO(zea): crbug.com/639009 update the tracker with the specifics | |
| 656 // from the header node as well. This will be necessary to preserve | |
| 657 // the set of open tabs when a custom tab is opened. | |
| 658 } else { | 658 } else { |
| 659 if (specifics.has_header() || !specifics.has_tab()) { | 659 if (specifics.has_header() || !specifics.has_tab()) { |
| 660 LOG(WARNING) << "Found more than one session header node with local " | 660 LOG(WARNING) << "Found more than one session header node with local " |
| 661 << "tag."; | 661 << "tag."; |
| 662 syncer::SyncChange tombstone(TombstoneTab(specifics)); | 662 syncer::SyncChange tombstone(TombstoneTab(specifics)); |
| 663 if (tombstone.IsValid()) | 663 if (tombstone.IsValid()) |
| 664 new_changes->push_back(tombstone); | 664 new_changes->push_back(tombstone); |
| 665 } else { | 665 } else { |
| 666 // This is a valid old tab node, add it to the pool so it can be | 666 // This is a valid old tab node, reassociate it and add it to the |
| 667 // reused for reassociation. | 667 // tracker. |
| 668 local_tab_map_[specifics.tab().tab_id()] = | |
| 669 make_linked_ptr<TabLink>(new TabLink(specifics.tab_node_id())); | |
| 668 local_tab_pool_.AddTabNode(specifics.tab_node_id()); | 670 local_tab_pool_.AddTabNode(specifics.tab_node_id()); |
| 669 restored_tabs->push_back(*it); | 671 local_tab_pool_.AssociateTabNode(specifics.tab_node_id(), |
| 672 specifics.tab().tab_id()); | |
| 673 UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime()); | |
| 670 } | 674 } |
| 671 } | 675 } |
| 672 } | 676 } |
| 673 } | 677 } |
| 674 | 678 |
| 675 // Cleanup all foreign sessions, since orphaned tabs may have been added after | 679 // Cleanup all foreign sessions, since orphaned tabs may have been added after |
| 676 // the header. | 680 // the header. |
| 677 std::vector<const SyncedSession*> sessions; | 681 std::vector<const SyncedSession*> sessions; |
| 678 session_tracker_.LookupAllForeignSessions(&sessions, | 682 session_tracker_.LookupAllForeignSessions(&sessions, |
| 679 SyncedSessionTracker::RAW); | 683 SyncedSessionTracker::RAW); |
| 680 for (const auto* session : sessions) { | 684 for (const auto* session : sessions) { |
| 681 session_tracker_.CleanupSession(session->session_tag); | 685 session_tracker_.CleanupSession(session->session_tag); |
| 682 } | 686 } |
| 683 | 687 |
| 684 UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount", | 688 UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount", |
| 685 bad_foreign_hash_count); | 689 bad_foreign_hash_count); |
| 686 | 690 |
| 687 return found_current_header; | 691 return found_current_header; |
| 688 } | 692 } |
| 689 | 693 |
| 690 void SessionsSyncManager::UpdateTrackerWithForeignSession( | 694 void SessionsSyncManager::UpdateTrackerWithSpecifics( |
| 691 const sync_pb::SessionSpecifics& specifics, | 695 const sync_pb::SessionSpecifics& specifics, |
| 692 const base::Time& modification_time) { | 696 const base::Time& modification_time) { |
| 693 std::string foreign_session_tag = specifics.session_tag(); | 697 std::string session_tag = specifics.session_tag(); |
| 694 DCHECK_NE(foreign_session_tag, current_machine_tag()); | 698 SyncedSession* session = session_tracker_.GetSession(session_tag); |
| 695 | |
| 696 SyncedSession* foreign_session = | |
| 697 session_tracker_.GetSession(foreign_session_tag); | |
| 698 if (specifics.has_header()) { | 699 if (specifics.has_header()) { |
| 699 // Read in the header data for this foreign session. Header data is | 700 // Read in the header data for this session. Header data is |
| 700 // essentially a collection of windows, each of which has an ordered id list | 701 // essentially a collection of windows, each of which has an ordered id list |
| 701 // for their tabs. | 702 // for their tabs. |
| 702 | 703 |
| 703 if (!IsValidSessionHeader(specifics.header())) { | 704 if (!IsValidSessionHeader(specifics.header())) { |
| 704 LOG(WARNING) << "Ignoring foreign session node with invalid header " | 705 LOG(WARNING) << "Ignoring session node with invalid header " |
| 705 << "and tag " << foreign_session_tag << "."; | 706 << "and tag " << session_tag << "."; |
| 706 return; | 707 return; |
| 707 } | 708 } |
| 708 | 709 |
| 709 // Load (or create) the SyncedSession object for this client. | 710 // Load (or create) the SyncedSession object for this client. |
| 710 const sync_pb::SessionHeader& header = specifics.header(); | 711 const sync_pb::SessionHeader& header = specifics.header(); |
| 711 PopulateSessionHeaderFromSpecifics(header, modification_time, | 712 PopulateSessionHeaderFromSpecifics(header, modification_time, session); |
| 712 foreign_session); | |
| 713 | 713 |
| 714 // Reset the tab/window tracking for this session (must do this before | 714 // Reset the tab/window tracking for this session (must do this before |
| 715 // we start calling PutWindowInSession and PutTabInWindow so that all | 715 // we start calling PutWindowInSession and PutTabInWindow so that all |
| 716 // unused tabs/windows get cleared by the CleanupSession(...) call). | 716 // unused tabs/windows get cleared by the CleanupSession(...) call). |
| 717 session_tracker_.ResetSessionTracking(foreign_session_tag); | 717 session_tracker_.ResetSessionTracking(session_tag); |
| 718 | 718 |
| 719 // Process all the windows and their tab information. | 719 // Process all the windows and their tab information. |
| 720 int num_windows = header.window_size(); | 720 int num_windows = header.window_size(); |
| 721 DVLOG(1) << "Associating " << foreign_session_tag << " with " << num_windows | 721 DVLOG(1) << "Associating " << session_tag << " with " << num_windows |
| 722 << " windows."; | 722 << " windows."; |
| 723 | 723 |
| 724 for (int i = 0; i < num_windows; ++i) { | 724 for (int i = 0; i < num_windows; ++i) { |
| 725 const sync_pb::SessionWindow& window_s = header.window(i); | 725 const sync_pb::SessionWindow& window_s = header.window(i); |
| 726 SessionID::id_type window_id = window_s.window_id(); | 726 SessionID::id_type window_id = window_s.window_id(); |
| 727 session_tracker_.PutWindowInSession(foreign_session_tag, window_id); | 727 session_tracker_.PutWindowInSession(session_tag, window_id); |
| 728 BuildSyncedSessionFromSpecifics( | 728 BuildSyncedSessionFromSpecifics(session_tag, window_s, modification_time, |
| 729 foreign_session_tag, window_s, modification_time, | 729 session->windows[window_id].get()); |
| 730 foreign_session->windows[window_id].get()); | |
| 731 } | 730 } |
| 732 // Delete any closed windows and unused tabs as necessary. | 731 // Delete any closed windows and unused tabs as necessary. |
| 733 session_tracker_.CleanupSession(foreign_session_tag); | 732 session_tracker_.CleanupSession(session_tag); |
| 734 } else if (specifics.has_tab()) { | 733 } else if (specifics.has_tab()) { |
| 735 const sync_pb::SessionTab& tab_s = specifics.tab(); | 734 const sync_pb::SessionTab& tab_s = specifics.tab(); |
| 736 SessionID::id_type tab_id = tab_s.tab_id(); | 735 SessionID::id_type tab_id = tab_s.tab_id(); |
| 737 | 736 |
| 738 const sessions::SessionTab* existing_tab; | 737 const sessions::SessionTab* existing_tab; |
| 739 if (session_tracker_.LookupSessionTab(foreign_session_tag, tab_id, | 738 if (session_tracker_.LookupSessionTab(session_tag, tab_id, &existing_tab) && |
| 740 &existing_tab) && | |
| 741 existing_tab->timestamp > modification_time) { | 739 existing_tab->timestamp > modification_time) { |
| 742 // Force the tracker to remember this tab node id, even if it isn't | 740 // Force the tracker to remember this tab node id, even if it isn't |
| 743 // currently being used. | 741 // currently being used. |
| 744 session_tracker_.GetTab(foreign_session_tag, tab_id, | 742 session_tracker_.GetTab(session_tag, tab_id, specifics.tab_node_id()); |
| 745 specifics.tab_node_id()); | 743 DVLOG(1) << "Ignoring " << session_tag << "'s session tab " << tab_id |
| 746 DVLOG(1) << "Ignoring " << foreign_session_tag << "'s session tab " | 744 << " with earlier modification time"; |
| 747 << tab_id << " with earlier modification time"; | |
| 748 return; | 745 return; |
| 749 } | 746 } |
| 750 | 747 |
| 751 sessions::SessionTab* tab = session_tracker_.GetTab( | 748 DVLOG(1) << "Associating tab " << tab_id << " with node " |
| 752 foreign_session_tag, tab_id, specifics.tab_node_id()); | 749 << specifics.tab_node_id(); |
| 750 sessions::SessionTab* tab = | |
| 751 session_tracker_.GetTab(session_tag, tab_id, specifics.tab_node_id()); | |
| 753 | 752 |
| 754 // Update SessionTab based on protobuf. | 753 // Update SessionTab based on protobuf. |
| 755 tab->SetFromSyncData(tab_s, modification_time); | 754 tab->SetFromSyncData(tab_s, modification_time); |
| 756 | 755 |
| 757 // If a favicon or favicon urls are present, load the URLs and visit | 756 // If a favicon or favicon urls are present, load the URLs and visit |
| 758 // times into the in-memory favicon cache. | 757 // times into the in-memory favicon cache. |
| 759 RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time); | 758 RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time); |
| 760 | 759 |
| 761 // Update the last modified time. | 760 // Update the last modified time. |
| 762 if (foreign_session->modified_time < modification_time) | 761 if (session->modified_time < modification_time) |
| 763 foreign_session->modified_time = modification_time; | 762 session->modified_time = modification_time; |
| 764 } else { | 763 } else { |
| 765 LOG(WARNING) << "Ignoring foreign session node with missing header/tab " | 764 LOG(WARNING) << "Ignoring session node with missing header/tab " |
| 766 << "fields and tag " << foreign_session_tag << "."; | 765 << "fields and tag " << session_tag << "."; |
| 767 } | 766 } |
| 768 } | 767 } |
| 769 | 768 |
| 770 void SessionsSyncManager::InitializeCurrentMachineTag() { | 769 void SessionsSyncManager::InitializeCurrentMachineTag() { |
| 771 DCHECK(current_machine_tag_.empty()); | 770 DCHECK(current_machine_tag_.empty()); |
| 772 std::string persisted_guid; | 771 std::string persisted_guid; |
| 773 persisted_guid = sync_prefs_->GetSyncSessionsGUID(); | 772 persisted_guid = sync_prefs_->GetSyncSessionsGUID(); |
| 774 if (!persisted_guid.empty()) { | 773 if (!persisted_guid.empty()) { |
| 775 current_machine_tag_ = persisted_guid; | 774 current_machine_tag_ = persisted_guid; |
| 776 DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid; | 775 DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 957 const sessions::SessionTab* synced_tab = nullptr; | 956 const sessions::SessionTab* synced_tab = nullptr; |
| 958 bool success = session_tracker_.LookupSessionTab(tag, tab_id, &synced_tab); | 957 bool success = session_tracker_.LookupSessionTab(tag, tab_id, &synced_tab); |
| 959 if (success) | 958 if (success) |
| 960 *tab = synced_tab; | 959 *tab = synced_tab; |
| 961 return success; | 960 return success; |
| 962 } | 961 } |
| 963 | 962 |
| 964 void SessionsSyncManager::LocalTabDelegateToSpecifics( | 963 void SessionsSyncManager::LocalTabDelegateToSpecifics( |
| 965 const SyncedTabDelegate& tab_delegate, | 964 const SyncedTabDelegate& tab_delegate, |
| 966 sync_pb::SessionSpecifics* specifics) { | 965 sync_pb::SessionSpecifics* specifics) { |
| 967 sessions::SessionTab* session_tab = nullptr; | 966 sessions::SessionTab* session_tab = nullptr; |
|
maxbogue
2016/11/10 06:43:25
Is there any particular reason this is a separate
Nicolas Zea
2016/11/10 18:25:36
Done.
| |
| 968 session_tab = session_tracker_.GetTab(current_machine_tag(), | 967 |
| 969 tab_delegate.GetSessionId(), | 968 SessionID::id_type tab_id = tab_delegate.GetSessionId(); |
| 969 session_tab = session_tracker_.GetTab(current_machine_tag(), tab_id, | |
| 970 tab_delegate.GetSyncId()); | 970 tab_delegate.GetSyncId()); |
| 971 SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); | 971 SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); |
| 972 SetVariationIds(session_tab); | 972 SetVariationIds(session_tab); |
| 973 sync_pb::SessionTab tab_s = session_tab->ToSyncData(); | 973 sync_pb::SessionTab tab_s = session_tab->ToSyncData(); |
| 974 specifics->set_session_tag(current_machine_tag_); | 974 specifics->set_session_tag(current_machine_tag_); |
| 975 specifics->set_tab_node_id(tab_delegate.GetSyncId()); | 975 specifics->set_tab_node_id(tab_delegate.GetSyncId()); |
| 976 specifics->mutable_tab()->CopyFrom(tab_s); | 976 specifics->mutable_tab()->CopyFrom(tab_s); |
| 977 } | 977 } |
| 978 | 978 |
| 979 void SessionsSyncManager::AssociateRestoredPlaceholderTab( | 979 void SessionsSyncManager::AssociateRestoredPlaceholderTab( |
| 980 const SyncedTabDelegate& tab_delegate, | 980 const SyncedTabDelegate& tab_delegate, |
| 981 SessionID::id_type new_tab_id, | 981 SessionID::id_type new_tab_id, |
| 982 SessionID::id_type new_window_id, | 982 SessionID::id_type new_window_id, |
| 983 const syncer::SyncDataList& restored_tabs, | |
| 984 syncer::SyncChangeList* change_output) { | 983 syncer::SyncChangeList* change_output) { |
| 985 DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); | 984 DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); |
| 986 // Rewrite the tab using |restored_tabs| to retrieve the specifics. | 985 |
| 987 if (restored_tabs.empty()) { | 986 SessionID::id_type old_tab_id = |
| 988 DLOG(WARNING) << "Can't Update tab ID."; | 987 local_tab_pool_.GetTabIdFromTabNodeId(tab_delegate.GetSyncId()); |
| 988 DVLOG(1) << "Restoring tab id " << new_tab_id << " from sync node " | |
| 989 << tab_delegate.GetSyncId() << " (old tab id was " << old_tab_id | |
| 990 << ")."; | |
| 991 | |
| 992 // Update tab node pool and tracker with the new association (note that | |
| 993 // reassociating the tracker depends on the old tab pool data, so it must be | |
| 994 // reassociated first). | |
| 995 if (!session_tracker_.ReassociateTab(current_machine_tag(), old_tab_id, | |
| 996 new_tab_id)) { | |
| 997 LOG(ERROR) << "Failed to restore tab " << new_tab_id; | |
|
maxbogue
2016/11/10 06:43:26
Maybe "Failed to reassociate tab "?
Nicolas Zea
2016/11/10 18:25:36
Done.
| |
| 989 return; | 998 return; |
| 990 } | 999 } |
| 1000 local_tab_pool_.ReassociateTabNode(tab_delegate.GetSyncId(), new_tab_id); | |
| 991 | 1001 |
| 992 for (syncer::SyncDataList::const_iterator it = restored_tabs.begin(); | 1002 // If the tab id hasn't changed, the tab map doesn't need to be updated. But |
| 993 it != restored_tabs.end(); ++it) { | 1003 // the window id may have changed, so the specifics still need to be |
| 994 if (it->GetSpecifics().session().tab_node_id() != | 1004 // rewritten. |
| 995 tab_delegate.GetSyncId()) { | 1005 if (old_tab_id != new_tab_id) { |
| 996 continue; | 1006 auto iter = local_tab_map_.find(old_tab_id); |
| 1007 if (iter == local_tab_map_.end()) { | |
| 1008 LOG(ERROR) << "Failed to restore tab " << new_tab_id; | |
|
maxbogue
2016/11/10 06:43:25
Maybe "Failed to update local tab map for "?
Nicolas Zea
2016/11/10 18:25:36
Done.
| |
| 1009 return; | |
| 997 } | 1010 } |
| 1011 local_tab_map_[new_tab_id] = iter->second; | |
| 1012 local_tab_map_.erase(iter); | |
| 1013 } | |
| 998 | 1014 |
| 999 sync_pb::EntitySpecifics entity; | 1015 sync_pb::EntitySpecifics entity; |
| 1000 sync_pb::SessionSpecifics* specifics = entity.mutable_session(); | 1016 sync_pb::SessionSpecifics* specifics = entity.mutable_session(); |
| 1001 specifics->CopyFrom(it->GetSpecifics().session()); | |
| 1002 DCHECK(specifics->has_tab()); | |
| 1003 | 1017 |
| 1004 // Update tab node pool with the new association. | 1018 // This will rewrite the tab id and window id based on the delegate. Note |
| 1005 local_tab_pool_.ReassociateTabNode(tab_delegate.GetSyncId(), new_tab_id); | 1019 // that it won't update the SessionWindow that holds the tab (which happens |
| 1006 TabLink* tab_link = new TabLink(tab_delegate.GetSyncId(), &tab_delegate); | 1020 // separately when the header node is associated). |
| 1007 local_tab_map_[new_tab_id] = make_linked_ptr<TabLink>(tab_link); | 1021 LocalTabDelegateToSpecifics(tab_delegate, specifics); |
| 1022 DCHECK(specifics->has_tab()); | |
| 1008 | 1023 |
| 1009 if (specifics->tab().tab_id() == new_tab_id && | 1024 syncer::SyncData data = syncer::SyncData::CreateLocalData( |
| 1010 specifics->tab().window_id() == new_window_id) | 1025 TabNodePool::TabIdToTag(current_machine_tag_, specifics->tab_node_id()), |
| 1011 return; | 1026 current_session_name_, entity); |
| 1012 | 1027 change_output->push_back( |
| 1013 // Either the tab_id or window_id changed (e.g due to session restore), so | 1028 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data)); |
| 1014 // update the sync node. | |
| 1015 specifics->mutable_tab()->set_tab_id(new_tab_id); | |
| 1016 specifics->mutable_tab()->set_window_id(new_window_id); | |
| 1017 syncer::SyncData data = syncer::SyncData::CreateLocalData( | |
| 1018 TabNodePool::TabIdToTag(current_machine_tag_, specifics->tab_node_id()), | |
| 1019 current_session_name_, entity); | |
| 1020 change_output->push_back( | |
| 1021 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data)); | |
| 1022 return; | |
| 1023 } | |
| 1024 } | 1029 } |
| 1025 | 1030 |
| 1026 // static | 1031 // static |
| 1027 void SessionsSyncManager::SetSessionTabFromDelegate( | 1032 void SessionsSyncManager::SetSessionTabFromDelegate( |
| 1028 const SyncedTabDelegate& tab_delegate, | 1033 const SyncedTabDelegate& tab_delegate, |
| 1029 base::Time mtime, | 1034 base::Time mtime, |
| 1030 sessions::SessionTab* session_tab) { | 1035 sessions::SessionTab* session_tab) { |
| 1031 DCHECK(session_tab); | 1036 DCHECK(session_tab); |
| 1032 session_tab->window_id.set_id(tab_delegate.GetWindowId()); | 1037 session_tab->window_id.set_id(tab_delegate.GetWindowId()); |
| 1033 session_tab->tab_id.set_id(tab_delegate.GetSessionId()); | 1038 session_tab->tab_id.set_id(tab_delegate.GetSessionId()); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1132 } | 1137 } |
| 1133 | 1138 |
| 1134 // static | 1139 // static |
| 1135 std::string SessionsSyncManager::TagHashFromSpecifics( | 1140 std::string SessionsSyncManager::TagHashFromSpecifics( |
| 1136 const sync_pb::SessionSpecifics& specifics) { | 1141 const sync_pb::SessionSpecifics& specifics) { |
| 1137 return syncer::syncable::GenerateSyncableHash(syncer::SESSIONS, | 1142 return syncer::syncable::GenerateSyncableHash(syncer::SESSIONS, |
| 1138 TagFromSpecifics(specifics)); | 1143 TagFromSpecifics(specifics)); |
| 1139 } | 1144 } |
| 1140 | 1145 |
| 1141 }; // namespace sync_sessions | 1146 }; // namespace sync_sessions |
| OLD | NEW |