Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: components/sync_sessions/sessions_sync_manager.cc

Issue 2494533002: [Sync] Put session tracker in charge of maintaining local state. (Closed)
Patch Set: Rebase and update comment Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « components/sync_sessions/sessions_sync_manager.h ('k') | components/sync_sessions/synced_session_tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698