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

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 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. 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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698