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. | |
359 // Note: on some platforms the tab object may have changed, so we ensure | |
360 // the tab link is up to date. | |
361 tab_link = local_tab_map_iter->second.get(); | 356 tab_link = local_tab_map_iter->second.get(); |
362 local_tab_map_iter->second->set_tab(tab); | |
363 } | 357 } |
364 DCHECK(tab_link); | 358 DCHECK(tab_link); |
365 DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID); | 359 DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID); |
366 DVLOG(1) << "Reloading tab " << tab_id << " from window " | 360 DVLOG(1) << "Reloading tab " << tab_id << " from window " |
367 << tab->GetWindowId(); | 361 << tab->GetWindowId(); |
368 | 362 |
369 // Write to sync model. | 363 // Write to sync model. |
370 sync_pb::EntitySpecifics specifics; | 364 sync_pb::EntitySpecifics specifics; |
371 LocalTabDelegateToSpecifics(*tab, specifics.mutable_session()); | 365 LocalTabDelegateToSpecifics(*tab, specifics.mutable_session()); |
372 syncer::SyncData data = syncer::SyncData::CreateLocalData( | 366 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_); | 432 DCHECK(!local_tab_pool_out_of_sync_); |
439 return; | 433 return; |
440 } | 434 } |
441 | 435 |
442 syncer::SyncChangeList changes; | 436 syncer::SyncChangeList changes; |
443 AssociateTab(modified_tab, &changes); | 437 AssociateTab(modified_tab, &changes); |
444 // Note, we always associate windows because it's possible a tab became | 438 // 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 | 439 // "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 | 440 // to the window's tab information. Similarly, if a tab became |
447 // "uninteresting", we remove it from the window's tab information. | 441 // "uninteresting", we remove it from the window's tab information. |
448 AssociateWindows(DONT_RELOAD_TABS, syncer::SyncDataList(), &changes); | 442 AssociateWindows(DONT_RELOAD_TABS, &changes); |
449 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 443 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
450 } | 444 } |
451 | 445 |
452 void SessionsSyncManager::OnFaviconsChanged(const std::set<GURL>& page_urls, | 446 void SessionsSyncManager::OnFaviconsChanged(const std::set<GURL>& page_urls, |
453 const GURL& /* icon_url */) { | 447 const GURL& /* icon_url */) { |
454 // TODO(zea): consider a separate container for tabs with outstanding favicon | 448 // 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. | 449 // loads so we don't have to iterate through all tabs comparing urls. |
456 for (const GURL& page_url : page_urls) { | 450 for (const GURL& page_url : page_urls) { |
457 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); | 451 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); |
458 tab_iter != local_tab_map_.end(); ++tab_iter) { | 452 tab_iter != local_tab_map_.end(); ++tab_iter) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
573 break; | 567 break; |
574 case syncer::SyncChange::ACTION_ADD: | 568 case syncer::SyncChange::ACTION_ADD: |
575 case syncer::SyncChange::ACTION_UPDATE: | 569 case syncer::SyncChange::ACTION_UPDATE: |
576 if (current_machine_tag() == session.session_tag()) { | 570 if (current_machine_tag() == session.session_tag()) { |
577 // We should only ever receive a change to our own machine's session | 571 // 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 | 572 // info if encryption was turned on. In that case, the data is still |
579 // the same, so we can ignore. | 573 // the same, so we can ignore. |
580 LOG(WARNING) << "Dropping modification to local session."; | 574 LOG(WARNING) << "Dropping modification to local session."; |
581 return syncer::SyncError(); | 575 return syncer::SyncError(); |
582 } | 576 } |
583 UpdateTrackerWithForeignSession( | 577 UpdateTrackerWithSpecifics( |
584 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); | 578 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); |
585 break; | 579 break; |
586 default: | 580 default: |
587 NOTREACHED() << "Processing sync changes failed, unknown change type."; | 581 NOTREACHED() << "Processing sync changes failed, unknown change type."; |
588 } | 582 } |
589 } | 583 } |
590 | 584 |
591 if (!sessions_updated_callback_.is_null()) | 585 if (!sessions_updated_callback_.is_null()) |
592 sessions_updated_callback_.Run(); | 586 sessions_updated_callback_.Run(); |
593 return syncer::SyncError(); | 587 return syncer::SyncError(); |
(...skipping 17 matching lines...) Expand all Loading... | |
611 std::vector<const SyncedSession*>* sessions) { | 605 std::vector<const SyncedSession*>* sessions) { |
612 if (!session_tracker_.LookupAllForeignSessions( | 606 if (!session_tracker_.LookupAllForeignSessions( |
613 sessions, SyncedSessionTracker::PRESENTABLE)) | 607 sessions, SyncedSessionTracker::PRESENTABLE)) |
614 return false; | 608 return false; |
615 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); | 609 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); |
616 return true; | 610 return true; |
617 } | 611 } |
618 | 612 |
619 bool SessionsSyncManager::InitFromSyncModel( | 613 bool SessionsSyncManager::InitFromSyncModel( |
620 const syncer::SyncDataList& sync_data, | 614 const syncer::SyncDataList& sync_data, |
621 syncer::SyncDataList* restored_tabs, | |
622 syncer::SyncChangeList* new_changes) { | 615 syncer::SyncChangeList* new_changes) { |
623 bool found_current_header = false; | 616 bool found_current_header = false; |
624 int bad_foreign_hash_count = 0; | 617 int bad_foreign_hash_count = 0; |
625 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | 618 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); |
626 it != sync_data.end(); ++it) { | 619 it != sync_data.end(); ++it) { |
627 const syncer::SyncData& data = *it; | 620 const syncer::SyncData& data = *it; |
628 DCHECK(data.GetSpecifics().has_session()); | 621 DCHECK(data.GetSpecifics().has_session()); |
629 syncer::SyncDataRemote remote(data); | 622 syncer::SyncDataRemote remote(data); |
630 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); | 623 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); |
631 if (specifics.session_tag().empty() || | 624 if (specifics.session_tag().empty() || |
632 (specifics.has_tab() && | 625 (specifics.has_tab() && |
633 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { | 626 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { |
634 syncer::SyncChange tombstone(TombstoneTab(specifics)); | 627 syncer::SyncChange tombstone(TombstoneTab(specifics)); |
635 if (tombstone.IsValid()) | 628 if (tombstone.IsValid()) |
636 new_changes->push_back(tombstone); | 629 new_changes->push_back(tombstone); |
637 } else if (specifics.session_tag() != current_machine_tag()) { | 630 } else if (specifics.session_tag() != current_machine_tag()) { |
638 if (TagHashFromSpecifics(specifics) == remote.GetClientTagHash()) { | 631 if (TagHashFromSpecifics(specifics) == remote.GetClientTagHash()) { |
639 UpdateTrackerWithForeignSession(specifics, remote.GetModifiedTime()); | 632 UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime()); |
640 } else { | 633 } else { |
641 // In the past, like years ago, we believe that some session data was | 634 // 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 | 635 // created with bad tag hashes. This causes any change this client makes |
643 // to that foreign data (like deletion through garbage collection) to | 636 // to that foreign data (like deletion through garbage collection) to |
644 // trigger a data type error because the tag looking mechanism fails. So | 637 // 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 | 638 // look for these and delete via remote SyncData, which uses a server id |
646 // lookup mechanism instead, see crbug.com/604657. | 639 // lookup mechanism instead, see crbug.com/604657. |
647 bad_foreign_hash_count++; | 640 bad_foreign_hash_count++; |
648 new_changes->push_back( | 641 new_changes->push_back( |
649 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, remote)); | 642 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, remote)); |
650 } | 643 } |
651 } else { | 644 } else { |
652 // This is previously stored local session information. | 645 // This is previously stored local session information. |
653 if (specifics.has_header() && !found_current_header) { | 646 if (specifics.has_header() && !found_current_header) { |
654 // This is our previous header node, reuse it. | 647 // This is our previous header node, reuse it. |
655 found_current_header = true; | 648 found_current_header = true; |
656 if (specifics.header().has_client_name()) | 649 if (specifics.header().has_client_name()) |
657 current_session_name_ = specifics.header().client_name(); | 650 current_session_name_ = specifics.header().client_name(); |
651 | |
652 // TODO(zea): crbug.com/639009 update the tracker with the specifics | |
653 // from the header node as well. This will be necessary to preserve | |
654 // the set of open tabs when a custom tab is opened. | |
658 } else { | 655 } else { |
659 if (specifics.has_header() || !specifics.has_tab()) { | 656 if (specifics.has_header() || !specifics.has_tab()) { |
660 LOG(WARNING) << "Found more than one session header node with local " | 657 LOG(WARNING) << "Found more than one session header node with local " |
661 << "tag."; | 658 << "tag."; |
662 syncer::SyncChange tombstone(TombstoneTab(specifics)); | 659 syncer::SyncChange tombstone(TombstoneTab(specifics)); |
663 if (tombstone.IsValid()) | 660 if (tombstone.IsValid()) |
664 new_changes->push_back(tombstone); | 661 new_changes->push_back(tombstone); |
665 } else { | 662 } else { |
666 // This is a valid old tab node, add it to the pool so it can be | 663 // This is a valid old tab node, reassociate it and add it to the |
667 // reused for reassociation. | 664 // tracker. |
665 local_tab_map_[specifics.tab().tab_id()] = | |
666 make_linked_ptr<TabLink>(new TabLink(specifics.tab_node_id())); | |
maxbogue
2016/11/11 17:05:31
Seems like we should probably move this class to u
Nicolas Zea
2016/11/11 18:25:03
Yeah, the main reason to use linked ptr here was w
| |
668 local_tab_pool_.AddTabNode(specifics.tab_node_id()); | 667 local_tab_pool_.AddTabNode(specifics.tab_node_id()); |
669 restored_tabs->push_back(*it); | 668 local_tab_pool_.AssociateTabNode(specifics.tab_node_id(), |
669 specifics.tab().tab_id()); | |
670 UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime()); | |
670 } | 671 } |
671 } | 672 } |
672 } | 673 } |
673 } | 674 } |
674 | 675 |
675 // Cleanup all foreign sessions, since orphaned tabs may have been added after | 676 // Cleanup all foreign sessions, since orphaned tabs may have been added after |
676 // the header. | 677 // the header. |
677 std::vector<const SyncedSession*> sessions; | 678 std::vector<const SyncedSession*> sessions; |
678 session_tracker_.LookupAllForeignSessions(&sessions, | 679 session_tracker_.LookupAllForeignSessions(&sessions, |
679 SyncedSessionTracker::RAW); | 680 SyncedSessionTracker::RAW); |
680 for (const auto* session : sessions) { | 681 for (const auto* session : sessions) { |
681 session_tracker_.CleanupSession(session->session_tag); | 682 session_tracker_.CleanupSession(session->session_tag); |
682 } | 683 } |
683 | 684 |
684 UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount", | 685 UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount", |
685 bad_foreign_hash_count); | 686 bad_foreign_hash_count); |
686 | 687 |
687 return found_current_header; | 688 return found_current_header; |
688 } | 689 } |
689 | 690 |
690 void SessionsSyncManager::UpdateTrackerWithForeignSession( | 691 void SessionsSyncManager::UpdateTrackerWithSpecifics( |
691 const sync_pb::SessionSpecifics& specifics, | 692 const sync_pb::SessionSpecifics& specifics, |
692 const base::Time& modification_time) { | 693 const base::Time& modification_time) { |
693 std::string foreign_session_tag = specifics.session_tag(); | 694 std::string session_tag = specifics.session_tag(); |
694 DCHECK_NE(foreign_session_tag, current_machine_tag()); | 695 SyncedSession* session = session_tracker_.GetSession(session_tag); |
695 | |
696 SyncedSession* foreign_session = | |
697 session_tracker_.GetSession(foreign_session_tag); | |
698 if (specifics.has_header()) { | 696 if (specifics.has_header()) { |
699 // Read in the header data for this foreign session. Header data is | 697 // 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 | 698 // essentially a collection of windows, each of which has an ordered id list |
701 // for their tabs. | 699 // for their tabs. |
702 | 700 |
703 if (!IsValidSessionHeader(specifics.header())) { | 701 if (!IsValidSessionHeader(specifics.header())) { |
704 LOG(WARNING) << "Ignoring foreign session node with invalid header " | 702 LOG(WARNING) << "Ignoring session node with invalid header " |
705 << "and tag " << foreign_session_tag << "."; | 703 << "and tag " << session_tag << "."; |
706 return; | 704 return; |
707 } | 705 } |
708 | 706 |
709 // Load (or create) the SyncedSession object for this client. | 707 // Load (or create) the SyncedSession object for this client. |
710 const sync_pb::SessionHeader& header = specifics.header(); | 708 const sync_pb::SessionHeader& header = specifics.header(); |
711 PopulateSessionHeaderFromSpecifics(header, modification_time, | 709 PopulateSessionHeaderFromSpecifics(header, modification_time, session); |
712 foreign_session); | |
713 | 710 |
714 // Reset the tab/window tracking for this session (must do this before | 711 // Reset the tab/window tracking for this session (must do this before |
715 // we start calling PutWindowInSession and PutTabInWindow so that all | 712 // we start calling PutWindowInSession and PutTabInWindow so that all |
716 // unused tabs/windows get cleared by the CleanupSession(...) call). | 713 // unused tabs/windows get cleared by the CleanupSession(...) call). |
717 session_tracker_.ResetSessionTracking(foreign_session_tag); | 714 session_tracker_.ResetSessionTracking(session_tag); |
718 | 715 |
719 // Process all the windows and their tab information. | 716 // Process all the windows and their tab information. |
720 int num_windows = header.window_size(); | 717 int num_windows = header.window_size(); |
721 DVLOG(1) << "Associating " << foreign_session_tag << " with " << num_windows | 718 DVLOG(1) << "Associating " << session_tag << " with " << num_windows |
722 << " windows."; | 719 << " windows."; |
723 | 720 |
724 for (int i = 0; i < num_windows; ++i) { | 721 for (int i = 0; i < num_windows; ++i) { |
725 const sync_pb::SessionWindow& window_s = header.window(i); | 722 const sync_pb::SessionWindow& window_s = header.window(i); |
726 SessionID::id_type window_id = window_s.window_id(); | 723 SessionID::id_type window_id = window_s.window_id(); |
727 session_tracker_.PutWindowInSession(foreign_session_tag, window_id); | 724 session_tracker_.PutWindowInSession(session_tag, window_id); |
728 BuildSyncedSessionFromSpecifics( | 725 BuildSyncedSessionFromSpecifics(session_tag, window_s, modification_time, |
729 foreign_session_tag, window_s, modification_time, | 726 session->windows[window_id].get()); |
730 foreign_session->windows[window_id].get()); | |
731 } | 727 } |
732 // Delete any closed windows and unused tabs as necessary. | 728 // Delete any closed windows and unused tabs as necessary. |
733 session_tracker_.CleanupSession(foreign_session_tag); | 729 session_tracker_.CleanupSession(session_tag); |
734 } else if (specifics.has_tab()) { | 730 } else if (specifics.has_tab()) { |
735 const sync_pb::SessionTab& tab_s = specifics.tab(); | 731 const sync_pb::SessionTab& tab_s = specifics.tab(); |
736 SessionID::id_type tab_id = tab_s.tab_id(); | 732 SessionID::id_type tab_id = tab_s.tab_id(); |
737 | 733 |
738 const sessions::SessionTab* existing_tab; | 734 const sessions::SessionTab* existing_tab; |
739 if (session_tracker_.LookupSessionTab(foreign_session_tag, tab_id, | 735 if (session_tracker_.LookupSessionTab(session_tag, tab_id, &existing_tab) && |
740 &existing_tab) && | |
741 existing_tab->timestamp > modification_time) { | 736 existing_tab->timestamp > modification_time) { |
742 // Force the tracker to remember this tab node id, even if it isn't | 737 // Force the tracker to remember this tab node id, even if it isn't |
743 // currently being used. | 738 // currently being used. |
744 session_tracker_.GetTab(foreign_session_tag, tab_id, | 739 session_tracker_.GetTab(session_tag, tab_id, specifics.tab_node_id()); |
745 specifics.tab_node_id()); | 740 DVLOG(1) << "Ignoring " << session_tag << "'s session tab " << tab_id |
746 DVLOG(1) << "Ignoring " << foreign_session_tag << "'s session tab " | 741 << " with earlier modification time"; |
747 << tab_id << " with earlier modification time"; | |
748 return; | 742 return; |
749 } | 743 } |
750 | 744 |
751 sessions::SessionTab* tab = session_tracker_.GetTab( | 745 DVLOG(1) << "Associating tab " << tab_id << " with node " |
752 foreign_session_tag, tab_id, specifics.tab_node_id()); | 746 << specifics.tab_node_id(); |
747 sessions::SessionTab* tab = | |
748 session_tracker_.GetTab(session_tag, tab_id, specifics.tab_node_id()); | |
753 | 749 |
754 // Update SessionTab based on protobuf. | 750 // Update SessionTab based on protobuf. |
755 tab->SetFromSyncData(tab_s, modification_time); | 751 tab->SetFromSyncData(tab_s, modification_time); |
756 | 752 |
757 // If a favicon or favicon urls are present, load the URLs and visit | 753 // If a favicon or favicon urls are present, load the URLs and visit |
758 // times into the in-memory favicon cache. | 754 // times into the in-memory favicon cache. |
759 RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time); | 755 RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time); |
760 | 756 |
761 // Update the last modified time. | 757 // Update the last modified time. |
762 if (foreign_session->modified_time < modification_time) | 758 if (session->modified_time < modification_time) |
763 foreign_session->modified_time = modification_time; | 759 session->modified_time = modification_time; |
764 } else { | 760 } else { |
765 LOG(WARNING) << "Ignoring foreign session node with missing header/tab " | 761 LOG(WARNING) << "Ignoring session node with missing header/tab " |
766 << "fields and tag " << foreign_session_tag << "."; | 762 << "fields and tag " << session_tag << "."; |
767 } | 763 } |
768 } | 764 } |
769 | 765 |
770 void SessionsSyncManager::InitializeCurrentMachineTag() { | 766 void SessionsSyncManager::InitializeCurrentMachineTag() { |
771 DCHECK(current_machine_tag_.empty()); | 767 DCHECK(current_machine_tag_.empty()); |
772 std::string persisted_guid; | 768 std::string persisted_guid; |
773 persisted_guid = sync_prefs_->GetSyncSessionsGUID(); | 769 persisted_guid = sync_prefs_->GetSyncSessionsGUID(); |
774 if (!persisted_guid.empty()) { | 770 if (!persisted_guid.empty()) { |
775 current_machine_tag_ = persisted_guid; | 771 current_machine_tag_ = persisted_guid; |
776 DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid; | 772 DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
958 bool success = session_tracker_.LookupSessionTab(tag, tab_id, &synced_tab); | 954 bool success = session_tracker_.LookupSessionTab(tag, tab_id, &synced_tab); |
959 if (success) | 955 if (success) |
960 *tab = synced_tab; | 956 *tab = synced_tab; |
961 return success; | 957 return success; |
962 } | 958 } |
963 | 959 |
964 void SessionsSyncManager::LocalTabDelegateToSpecifics( | 960 void SessionsSyncManager::LocalTabDelegateToSpecifics( |
965 const SyncedTabDelegate& tab_delegate, | 961 const SyncedTabDelegate& tab_delegate, |
966 sync_pb::SessionSpecifics* specifics) { | 962 sync_pb::SessionSpecifics* specifics) { |
967 sessions::SessionTab* session_tab = nullptr; | 963 sessions::SessionTab* session_tab = nullptr; |
968 session_tab = session_tracker_.GetTab(current_machine_tag(), | 964 SessionID::id_type tab_id = tab_delegate.GetSessionId(); |
969 tab_delegate.GetSessionId(), | 965 session_tab = session_tracker_.GetTab(current_machine_tag(), tab_id, |
970 tab_delegate.GetSyncId()); | 966 tab_delegate.GetSyncId()); |
971 SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); | 967 SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); |
972 SetVariationIds(session_tab); | 968 SetVariationIds(session_tab); |
973 sync_pb::SessionTab tab_s = session_tab->ToSyncData(); | 969 sync_pb::SessionTab tab_s = session_tab->ToSyncData(); |
974 specifics->set_session_tag(current_machine_tag_); | 970 specifics->set_session_tag(current_machine_tag_); |
975 specifics->set_tab_node_id(tab_delegate.GetSyncId()); | 971 specifics->set_tab_node_id(tab_delegate.GetSyncId()); |
976 specifics->mutable_tab()->CopyFrom(tab_s); | 972 specifics->mutable_tab()->CopyFrom(tab_s); |
977 } | 973 } |
978 | 974 |
979 void SessionsSyncManager::AssociateRestoredPlaceholderTab( | 975 void SessionsSyncManager::AssociateRestoredPlaceholderTab( |
980 const SyncedTabDelegate& tab_delegate, | 976 const SyncedTabDelegate& tab_delegate, |
981 SessionID::id_type new_tab_id, | 977 SessionID::id_type new_tab_id, |
982 SessionID::id_type new_window_id, | 978 SessionID::id_type new_window_id, |
983 const syncer::SyncDataList& restored_tabs, | |
984 syncer::SyncChangeList* change_output) { | 979 syncer::SyncChangeList* change_output) { |
985 DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); | 980 DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); |
986 // Rewrite the tab using |restored_tabs| to retrieve the specifics. | 981 |
987 if (restored_tabs.empty()) { | 982 SessionID::id_type old_tab_id = |
988 DLOG(WARNING) << "Can't Update tab ID."; | 983 local_tab_pool_.GetTabIdFromTabNodeId(tab_delegate.GetSyncId()); |
984 DVLOG(1) << "Restoring tab id " << new_tab_id << " from sync node " | |
985 << tab_delegate.GetSyncId() << " (old tab id was " << old_tab_id | |
986 << ")."; | |
987 | |
988 // Update tab node pool and tracker with the new association (note that | |
989 // reassociating the tracker depends on the old tab pool data, so it must be | |
990 // reassociated first). | |
991 if (!session_tracker_.ReassociateTab(current_machine_tag(), old_tab_id, | |
992 new_tab_id)) { | |
993 LOG(ERROR) << "Failed to reassociate tab " << new_tab_id; | |
989 return; | 994 return; |
990 } | 995 } |
996 local_tab_pool_.ReassociateTabNode(tab_delegate.GetSyncId(), new_tab_id); | |
991 | 997 |
992 for (syncer::SyncDataList::const_iterator it = restored_tabs.begin(); | 998 // If the tab id hasn't changed, the tab map doesn't need to be updated. But |
993 it != restored_tabs.end(); ++it) { | 999 // the window id may have changed, so the specifics still need to be |
994 if (it->GetSpecifics().session().tab_node_id() != | 1000 // rewritten. |
995 tab_delegate.GetSyncId()) { | 1001 if (old_tab_id != new_tab_id) { |
996 continue; | 1002 auto iter = local_tab_map_.find(old_tab_id); |
1003 if (iter == local_tab_map_.end()) { | |
1004 LOG(ERROR) << "Failed to update local tab map for " << new_tab_id; | |
1005 return; | |
997 } | 1006 } |
1007 local_tab_map_[new_tab_id] = iter->second; | |
1008 local_tab_map_.erase(iter); | |
1009 } | |
998 | 1010 |
999 sync_pb::EntitySpecifics entity; | 1011 sync_pb::EntitySpecifics entity; |
1000 sync_pb::SessionSpecifics* specifics = entity.mutable_session(); | 1012 sync_pb::SessionSpecifics* specifics = entity.mutable_session(); |
1001 specifics->CopyFrom(it->GetSpecifics().session()); | |
1002 DCHECK(specifics->has_tab()); | |
1003 | 1013 |
1004 // Update tab node pool with the new association. | 1014 // 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); | 1015 // that it won't update the SessionWindow that holds the tab (which happens |
1006 TabLink* tab_link = new TabLink(tab_delegate.GetSyncId(), &tab_delegate); | 1016 // separately when the header node is associated). |
1007 local_tab_map_[new_tab_id] = make_linked_ptr<TabLink>(tab_link); | 1017 LocalTabDelegateToSpecifics(tab_delegate, specifics); |
1018 DCHECK(specifics->has_tab()); | |
1008 | 1019 |
1009 if (specifics->tab().tab_id() == new_tab_id && | 1020 syncer::SyncData data = syncer::SyncData::CreateLocalData( |
1010 specifics->tab().window_id() == new_window_id) | 1021 TabNodePool::TabIdToTag(current_machine_tag_, specifics->tab_node_id()), |
1011 return; | 1022 current_session_name_, entity); |
1012 | 1023 change_output->push_back( |
1013 // Either the tab_id or window_id changed (e.g due to session restore), so | 1024 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 } | 1025 } |
1025 | 1026 |
1026 // static | 1027 // static |
1027 void SessionsSyncManager::SetSessionTabFromDelegate( | 1028 void SessionsSyncManager::SetSessionTabFromDelegate( |
1028 const SyncedTabDelegate& tab_delegate, | 1029 const SyncedTabDelegate& tab_delegate, |
1029 base::Time mtime, | 1030 base::Time mtime, |
1030 sessions::SessionTab* session_tab) { | 1031 sessions::SessionTab* session_tab) { |
1031 DCHECK(session_tab); | 1032 DCHECK(session_tab); |
1032 session_tab->window_id.set_id(tab_delegate.GetWindowId()); | 1033 session_tab->window_id.set_id(tab_delegate.GetWindowId()); |
1033 session_tab->tab_id.set_id(tab_delegate.GetSessionId()); | 1034 session_tab->tab_id.set_id(tab_delegate.GetSessionId()); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 } | 1133 } |
1133 | 1134 |
1134 // static | 1135 // static |
1135 std::string SessionsSyncManager::TagHashFromSpecifics( | 1136 std::string SessionsSyncManager::TagHashFromSpecifics( |
1136 const sync_pb::SessionSpecifics& specifics) { | 1137 const sync_pb::SessionSpecifics& specifics) { |
1137 return syncer::syncable::GenerateSyncableHash(syncer::SESSIONS, | 1138 return syncer::syncable::GenerateSyncableHash(syncer::SESSIONS, |
1138 TagFromSpecifics(specifics)); | 1139 TagFromSpecifics(specifics)); |
1139 } | 1140 } |
1140 | 1141 |
1141 }; // namespace sync_sessions | 1142 }; // namespace sync_sessions |
OLD | NEW |