Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/sync_sessions/sessions_sync_manager.h" | 5 #include "components/sync_sessions/sessions_sync_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 | 36 |
| 37 // The maximum number of navigations in each direction we care to sync. | 37 // The maximum number of navigations in each direction we care to sync. |
| 38 const int kMaxSyncNavigationCount = 6; | 38 const int kMaxSyncNavigationCount = 6; |
| 39 | 39 |
| 40 // The URL at which the set of synced tabs is displayed. We treat it differently | 40 // The URL at which the set of synced tabs is displayed. We treat it differently |
| 41 // from all other URL's as accessing it triggers a sync refresh of Sessions. | 41 // from all other URL's as accessing it triggers a sync refresh of Sessions. |
| 42 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; | 42 const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; |
| 43 | 43 |
| 44 // Default number of days without activity after which a session is considered | 44 // Default number of days without activity after which a session is considered |
| 45 // stale and becomes a candidate for garbage collection. | 45 // stale and becomes a candidate for garbage collection. |
| 46 const size_t kDefaultStaleSessionThresholdDays = 14; // 2 weeks. | 46 const int kDefaultStaleSessionThresholdDays = 14; // 2 weeks. |
| 47 | 47 |
| 48 // Comparator function for use with std::sort that will sort tabs by | 48 // Comparator function for use with std::sort that will sort tabs by |
| 49 // descending timestamp (i.e., most recent first). | 49 // descending timestamp (i.e., most recent first). |
| 50 bool TabsRecencyComparator(const sessions::SessionTab* t1, | 50 bool TabsRecencyComparator(const sessions::SessionTab* t1, |
| 51 const sessions::SessionTab* t2) { | 51 const sessions::SessionTab* t2) { |
| 52 return t1->timestamp > t2->timestamp; | 52 return t1->timestamp > t2->timestamp; |
| 53 } | 53 } |
| 54 | 54 |
| 55 // Comparator function for use with std::sort that will sort sessions by | 55 // Comparator function for use with std::sort that will sort sessions by |
| 56 // descending modified_time (i.e., most recent first). | 56 // descending modified_time (i.e., most recent first). |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 // to avoid any possible ping-pong delete/reassociate sequence, but | 508 // to avoid any possible ping-pong delete/reassociate sequence, but |
| 509 // remember that this happened as our TabNodePool is inconsistent. | 509 // remember that this happened as our TabNodePool is inconsistent. |
| 510 local_tab_pool_out_of_sync_ = true; | 510 local_tab_pool_out_of_sync_ = true; |
| 511 LOG(WARNING) << "Local session data deleted. Ignoring until next " | 511 LOG(WARNING) << "Local session data deleted. Ignoring until next " |
| 512 << "local navigation event."; | 512 << "local navigation event."; |
| 513 } else if (session.has_header()) { | 513 } else if (session.has_header()) { |
| 514 // Disassociate only when header node is deleted. For tab node | 514 // Disassociate only when header node is deleted. For tab node |
| 515 // deletions, the header node will be updated and foreign tab will | 515 // deletions, the header node will be updated and foreign tab will |
| 516 // get deleted. | 516 // get deleted. |
| 517 DisassociateForeignSession(session.session_tag()); | 517 DisassociateForeignSession(session.session_tag()); |
| 518 } else if (session.has_tab() && | |
| 519 current_machine_tag() != session.session_tag()) { | |
|
Nicolas Zea
2016/04/12 20:38:03
the current_machine_tag condition isn't necessary
skym
2016/04/12 22:12:14
Done.
| |
| 520 // The challenge here is that we don't know if this tab deletion is | |
| 521 // being processes before or after the parent was updated to no longer | |
|
Nicolas Zea
2016/04/12 20:38:03
being processes -> being processed
skym
2016/04/12 22:12:14
Done.
| |
| 522 // reference us, or even more extreme, the parent has been deleted as | |
|
Nicolas Zea
2016/04/12 20:38:03
"reference us, or even" -> "reference the tab. Or,
skym
2016/04/12 22:12:13
Done.
| |
| 523 // well. Tell the tracker to do what it can. The header's update will | |
| 524 // mostly get us into the correct state, the only thing this deletion | |
| 525 // needs to accomplish is make sure we never tell sync to delete this | |
| 526 // tab later during garbage collection. | |
| 527 session_tracker_.TryDeleteTab(session.session_tag(), | |
| 528 session.tab().tab_id(), | |
| 529 session.tab_node_id()); | |
| 518 } | 530 } |
| 519 break; | 531 break; |
| 520 case syncer::SyncChange::ACTION_ADD: | 532 case syncer::SyncChange::ACTION_ADD: |
| 521 case syncer::SyncChange::ACTION_UPDATE: | 533 case syncer::SyncChange::ACTION_UPDATE: |
| 522 if (current_machine_tag() == session.session_tag()) { | 534 if (current_machine_tag() == session.session_tag()) { |
| 523 // We should only ever receive a change to our own machine's session | 535 // We should only ever receive a change to our own machine's session |
| 524 // info if encryption was turned on. In that case, the data is still | 536 // info if encryption was turned on. In that case, the data is still |
| 525 // the same, so we can ignore. | 537 // the same, so we can ignore. |
| 526 // TODO(skym): Is it really safe to return here? Why not continue? | |
| 527 // Couldn't there be multiple SessionSpecifics in the SyncChangeList | |
| 528 // that contain different session tags? | |
| 529 LOG(WARNING) << "Dropping modification to local session."; | 538 LOG(WARNING) << "Dropping modification to local session."; |
| 530 return syncer::SyncError(); | 539 return syncer::SyncError(); |
| 531 } | 540 } |
| 532 UpdateTrackerWithForeignSession( | 541 UpdateTrackerWithForeignSession( |
| 533 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); | 542 session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); |
| 534 break; | 543 break; |
| 535 default: | 544 default: |
| 536 NOTREACHED() << "Processing sync changes failed, unknown change type."; | 545 NOTREACHED() << "Processing sync changes failed, unknown change type."; |
| 537 } | 546 } |
| 538 } | 547 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 551 return syncer::SyncChange( | 560 return syncer::SyncChange( |
| 552 FROM_HERE, SyncChange::ACTION_DELETE, | 561 FROM_HERE, SyncChange::ACTION_DELETE, |
| 553 SyncData::CreateLocalDelete( | 562 SyncData::CreateLocalDelete( |
| 554 TabNodePool::TabIdToTag(current_machine_tag(), tab.tab_node_id()), | 563 TabNodePool::TabIdToTag(current_machine_tag(), tab.tab_node_id()), |
| 555 syncer::SESSIONS)); | 564 syncer::SESSIONS)); |
| 556 } | 565 } |
| 557 } | 566 } |
| 558 | 567 |
| 559 bool SessionsSyncManager::GetAllForeignSessions( | 568 bool SessionsSyncManager::GetAllForeignSessions( |
| 560 std::vector<const sync_driver::SyncedSession*>* sessions) { | 569 std::vector<const sync_driver::SyncedSession*>* sessions) { |
| 561 if (!session_tracker_.LookupAllForeignSessions(sessions)) | 570 if (!session_tracker_.LookupAllForeignSessions(sessions, true)) |
| 562 return false; | 571 return false; |
| 563 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); | 572 std::sort(sessions->begin(), sessions->end(), SessionsRecencyComparator); |
| 564 return true; | 573 return true; |
| 565 } | 574 } |
| 566 | 575 |
| 567 bool SessionsSyncManager::InitFromSyncModel( | 576 bool SessionsSyncManager::InitFromSyncModel( |
| 568 const syncer::SyncDataList& sync_data, | 577 const syncer::SyncDataList& sync_data, |
| 569 syncer::SyncDataList* restored_tabs, | 578 syncer::SyncDataList* restored_tabs, |
| 570 syncer::SyncChangeList* new_changes) { | 579 syncer::SyncChangeList* new_changes) { |
| 571 bool found_current_header = false; | 580 bool found_current_header = false; |
| 572 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | 581 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); |
| 573 it != sync_data.end(); ++it) { | 582 it != sync_data.end(); ++it) { |
| 574 // TODO(skym): Why don't we ever look at data.change_type()? Why is this | |
| 575 // code path so much different from ProcessSyncChanges? | |
| 576 const syncer::SyncData& data = *it; | 583 const syncer::SyncData& data = *it; |
| 577 DCHECK(data.GetSpecifics().has_session()); | 584 DCHECK(data.GetSpecifics().has_session()); |
| 578 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); | 585 const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); |
| 579 if (specifics.session_tag().empty() || | 586 if (specifics.session_tag().empty() || |
| 580 (specifics.has_tab() && | 587 (specifics.has_tab() && |
| 581 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { | 588 (!specifics.has_tab_node_id() || !specifics.tab().has_tab_id()))) { |
| 582 syncer::SyncChange tombstone(TombstoneTab(specifics)); | 589 syncer::SyncChange tombstone(TombstoneTab(specifics)); |
| 583 if (tombstone.IsValid()) | 590 if (tombstone.IsValid()) |
| 584 new_changes->push_back(tombstone); | 591 new_changes->push_back(tombstone); |
| 585 } else if (specifics.session_tag() != current_machine_tag()) { | 592 } else if (specifics.session_tag() != current_machine_tag()) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 612 } | 619 } |
| 613 | 620 |
| 614 void SessionsSyncManager::UpdateTrackerWithForeignSession( | 621 void SessionsSyncManager::UpdateTrackerWithForeignSession( |
| 615 const sync_pb::SessionSpecifics& specifics, | 622 const sync_pb::SessionSpecifics& specifics, |
| 616 const base::Time& modification_time) { | 623 const base::Time& modification_time) { |
| 617 std::string foreign_session_tag = specifics.session_tag(); | 624 std::string foreign_session_tag = specifics.session_tag(); |
| 618 DCHECK_NE(foreign_session_tag, current_machine_tag()); | 625 DCHECK_NE(foreign_session_tag, current_machine_tag()); |
| 619 | 626 |
| 620 sync_driver::SyncedSession* foreign_session = | 627 sync_driver::SyncedSession* foreign_session = |
| 621 session_tracker_.GetSession(foreign_session_tag); | 628 session_tracker_.GetSession(foreign_session_tag); |
| 629 | |
| 622 if (specifics.has_header()) { | 630 if (specifics.has_header()) { |
| 623 // Read in the header data for this foreign session. Header data is | 631 // Read in the header data for this foreign session. Header data is |
| 624 // essentially a collection of windows, each of which has an ordered id list | 632 // essentially a collection of windows, each of which has an ordered id list |
| 625 // for their tabs. | 633 // for their tabs. |
| 626 | 634 |
| 627 if (!IsValidSessionHeader(specifics.header())) { | 635 if (!IsValidSessionHeader(specifics.header())) { |
| 628 LOG(WARNING) << "Ignoring foreign session node with invalid header " | 636 LOG(WARNING) << "Ignoring foreign session node with invalid header " |
| 629 << "and tag " << foreign_session_tag << "."; | 637 << "and tag " << foreign_session_tag << "."; |
| 630 return; | 638 return; |
| 631 } | 639 } |
| 632 | 640 |
| 633 // Load (or create) the SyncedSession object for this client. | 641 // Load (or create) the SyncedSession object for this client. |
| 634 const sync_pb::SessionHeader& header = specifics.header(); | 642 const sync_pb::SessionHeader& header = specifics.header(); |
| 635 PopulateSessionHeaderFromSpecifics(header, modification_time, | 643 PopulateSessionHeaderFromSpecifics(header, modification_time, |
| 636 foreign_session); | 644 foreign_session); |
| 637 | 645 |
| 638 // Reset the tab/window tracking for this session (must do this before | 646 // Reset the tab/window tracking for this session before adding them all |
| 639 // we start calling PutWindowInSession and PutTabInWindow so that all | 647 // back. This allows us to avoid a two way diff. |
| 640 // unused tabs/windows get cleared by the CleanupSession(...) call). | |
| 641 session_tracker_.ResetSessionTracking(foreign_session_tag); | 648 session_tracker_.ResetSessionTracking(foreign_session_tag); |
| 642 | 649 |
| 643 // Process all the windows and their tab information. | 650 // Process all the windows and their tab information. |
| 644 int num_windows = header.window_size(); | 651 int num_windows = header.window_size(); |
| 645 DVLOG(1) << "Associating " << foreign_session_tag << " with " << num_windows | 652 DVLOG(1) << "Associating " << foreign_session_tag << " with " << num_windows |
| 646 << " windows."; | 653 << " windows."; |
| 647 | 654 |
| 648 for (int i = 0; i < num_windows; ++i) { | 655 for (int i = 0; i < num_windows; ++i) { |
| 649 const sync_pb::SessionWindow& window_s = header.window(i); | 656 const sync_pb::SessionWindow& window_s = header.window(i); |
| 650 SessionID::id_type window_id = window_s.window_id(); | 657 SessionID::id_type window_id = window_s.window_id(); |
| 651 session_tracker_.PutWindowInSession(foreign_session_tag, window_id); | 658 session_tracker_.PutWindowInSession(foreign_session_tag, window_id); |
| 652 BuildSyncedSessionFromSpecifics(foreign_session_tag, window_s, | 659 BuildSyncedSessionFromSpecifics(foreign_session_tag, window_s, |
| 653 modification_time, | 660 modification_time, |
| 654 foreign_session->windows[window_id]); | 661 foreign_session->windows[window_id]); |
| 655 } | 662 } |
| 656 // Delete any closed windows and unused tabs as necessary. | |
| 657 session_tracker_.CleanupSession(foreign_session_tag); | |
| 658 } else if (specifics.has_tab()) { | 663 } else if (specifics.has_tab()) { |
| 659 const sync_pb::SessionTab& tab_s = specifics.tab(); | 664 const sync_pb::SessionTab& tab_s = specifics.tab(); |
| 660 SessionID::id_type tab_id = tab_s.tab_id(); | 665 SessionID::id_type tab_id = tab_s.tab_id(); |
| 661 | 666 |
| 662 const sessions::SessionTab* existing_tab; | 667 const sessions::SessionTab* existing_tab; |
| 663 if (session_tracker_.LookupSessionTab(foreign_session_tag, tab_id, | 668 if (session_tracker_.LookupSessionTab(foreign_session_tag, tab_id, |
| 664 &existing_tab) && | 669 &existing_tab) && |
| 665 existing_tab->timestamp > modification_time) { | 670 existing_tab->timestamp > modification_time) { |
| 671 // Remember that there is more sync data behind this tab_id if we decide | |
| 672 // to garbage collection this session. We never do granular garbage | |
|
Nicolas Zea
2016/04/12 20:38:03
to garbage collection -> to garbage collect (or to
skym
2016/04/12 22:12:14
Comment is different now.
| |
| 673 // collection because we don't want to fight with the owning device. | |
| 674 session_tracker_.GetTab(foreign_session_tag, tab_id, | |
| 675 specifics.tab_node_id()); | |
| 666 DVLOG(1) << "Ignoring " << foreign_session_tag << "'s session tab " | 676 DVLOG(1) << "Ignoring " << foreign_session_tag << "'s session tab " |
| 667 << tab_id << " with earlier modification time"; | 677 << tab_id << " with earlier modification time"; |
| 668 return; | 678 return; |
| 669 } | 679 } |
| 670 | 680 |
| 671 sessions::SessionTab* tab = session_tracker_.GetTab( | 681 sessions::SessionTab* tab = session_tracker_.GetTab( |
| 672 foreign_session_tag, tab_id, specifics.tab_node_id()); | 682 foreign_session_tag, tab_id, specifics.tab_node_id()); |
| 673 | 683 |
| 674 // Update SessionTab based on protobuf. | 684 // Update SessionTab based on protobuf. |
| 675 tab->SetFromSyncData(tab_s, modification_time); | 685 tab->SetFromSyncData(tab_s, modification_time); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: | 743 case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: |
| 734 session_header->device_type = sync_driver::SyncedSession::TYPE_TABLET; | 744 session_header->device_type = sync_driver::SyncedSession::TYPE_TABLET; |
| 735 break; | 745 break; |
| 736 case sync_pb::SyncEnums_DeviceType_TYPE_OTHER: | 746 case sync_pb::SyncEnums_DeviceType_TYPE_OTHER: |
| 737 // Intentionally fall-through | 747 // Intentionally fall-through |
| 738 default: | 748 default: |
| 739 session_header->device_type = sync_driver::SyncedSession::TYPE_OTHER; | 749 session_header->device_type = sync_driver::SyncedSession::TYPE_OTHER; |
| 740 break; | 750 break; |
| 741 } | 751 } |
| 742 } | 752 } |
| 743 session_header->modified_time = mtime; | 753 session_header->modified_time = |
| 754 std::max(mtime, session_header->modified_time); | |
| 744 } | 755 } |
| 745 | 756 |
| 746 // static | 757 // static |
| 747 void SessionsSyncManager::BuildSyncedSessionFromSpecifics( | 758 void SessionsSyncManager::BuildSyncedSessionFromSpecifics( |
| 748 const std::string& session_tag, | 759 const std::string& session_tag, |
| 749 const sync_pb::SessionWindow& specifics, | 760 const sync_pb::SessionWindow& specifics, |
| 750 base::Time mtime, | 761 base::Time mtime, |
| 751 sessions::SessionWindow* session_window) { | 762 sessions::SessionWindow* session_window) { |
| 752 if (specifics.has_window_id()) | 763 if (specifics.has_window_id()) |
| 753 session_window->window_id.set_id(specifics.window_id()); | 764 session_window->window_id.set_id(specifics.window_id()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 const std::string& tag, | 815 const std::string& tag, |
| 805 syncer::SyncChangeList* change_output) { | 816 syncer::SyncChangeList* change_output) { |
| 806 if (tag == current_machine_tag()) { | 817 if (tag == current_machine_tag()) { |
| 807 LOG(ERROR) << "Attempting to delete local session. This is not currently " | 818 LOG(ERROR) << "Attempting to delete local session. This is not currently " |
| 808 << "supported."; | 819 << "supported."; |
| 809 return; | 820 return; |
| 810 } | 821 } |
| 811 | 822 |
| 812 std::set<int> tab_node_ids_to_delete; | 823 std::set<int> tab_node_ids_to_delete; |
| 813 session_tracker_.LookupTabNodeIds(tag, &tab_node_ids_to_delete); | 824 session_tracker_.LookupTabNodeIds(tag, &tab_node_ids_to_delete); |
| 814 if (!DisassociateForeignSession(tag)) { | 825 if (DisassociateForeignSession(tag)) { |
| 815 // We don't have any data for this session, our work here is done! | 826 // Only tell sync to delete the header if there was one. |
| 816 return; | 827 change_output->push_back( |
| 828 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, | |
| 829 SyncData::CreateLocalDelete(tag, syncer::SESSIONS))); | |
| 817 } | 830 } |
| 818 | 831 |
| 819 // Prepare deletes for the meta-node as well as individual tab nodes. | |
| 820 change_output->push_back( | |
| 821 syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, | |
| 822 SyncData::CreateLocalDelete(tag, syncer::SESSIONS))); | |
| 823 | |
| 824 for (std::set<int>::const_iterator it = tab_node_ids_to_delete.begin(); | 832 for (std::set<int>::const_iterator it = tab_node_ids_to_delete.begin(); |
| 825 it != tab_node_ids_to_delete.end(); ++it) { | 833 it != tab_node_ids_to_delete.end(); ++it) { |
| 826 change_output->push_back(syncer::SyncChange( | 834 change_output->push_back(syncer::SyncChange( |
| 827 FROM_HERE, SyncChange::ACTION_DELETE, | 835 FROM_HERE, SyncChange::ACTION_DELETE, |
| 828 SyncData::CreateLocalDelete(TabNodePool::TabIdToTag(tag, *it), | 836 SyncData::CreateLocalDelete(TabNodePool::TabIdToTag(tag, *it), |
| 829 syncer::SESSIONS))); | 837 syncer::SESSIONS))); |
| 830 } | 838 } |
| 831 if (!sessions_updated_callback_.is_null()) | 839 if (!sessions_updated_callback_.is_null()) |
| 832 sessions_updated_callback_.Run(); | 840 sessions_updated_callback_.Run(); |
| 833 } | 841 } |
| 834 | 842 |
| 835 bool SessionsSyncManager::DisassociateForeignSession( | 843 bool SessionsSyncManager::DisassociateForeignSession( |
| 836 const std::string& foreign_session_tag) { | 844 const std::string& foreign_session_tag) { |
| 837 if (foreign_session_tag == current_machine_tag()) { | 845 DCHECK_NE(foreign_session_tag, current_machine_tag()); |
| 838 DVLOG(1) << "Local session deleted! Doing nothing until a navigation is " | |
| 839 << "triggered."; | |
| 840 return false; | |
| 841 } | |
| 842 DVLOG(1) << "Disassociating session " << foreign_session_tag; | 846 DVLOG(1) << "Disassociating session " << foreign_session_tag; |
| 843 return session_tracker_.DeleteSession(foreign_session_tag); | 847 return session_tracker_.DeleteSession(foreign_session_tag); |
| 844 } | 848 } |
| 845 | 849 |
| 846 bool SessionsSyncManager::GetForeignSession( | 850 bool SessionsSyncManager::GetForeignSession( |
| 847 const std::string& tag, | 851 const std::string& tag, |
| 848 std::vector<const sessions::SessionWindow*>* windows) { | 852 std::vector<const sessions::SessionWindow*>* windows) { |
| 849 return session_tracker_.LookupSessionWindows(tag, windows); | 853 return session_tracker_.LookupSessionWindows(tag, windows); |
| 850 } | 854 } |
| 851 | 855 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1023 return &favicon_cache_; | 1027 return &favicon_cache_; |
| 1024 } | 1028 } |
| 1025 | 1029 |
| 1026 SyncedWindowDelegatesGetter* | 1030 SyncedWindowDelegatesGetter* |
| 1027 SessionsSyncManager::synced_window_delegates_getter() const { | 1031 SessionsSyncManager::synced_window_delegates_getter() const { |
| 1028 return sessions_client_->GetSyncedWindowDelegatesGetter(); | 1032 return sessions_client_->GetSyncedWindowDelegatesGetter(); |
| 1029 } | 1033 } |
| 1030 | 1034 |
| 1031 void SessionsSyncManager::DoGarbageCollection() { | 1035 void SessionsSyncManager::DoGarbageCollection() { |
| 1032 std::vector<const sync_driver::SyncedSession*> sessions; | 1036 std::vector<const sync_driver::SyncedSession*> sessions; |
| 1033 if (!GetAllForeignSessions(&sessions)) | 1037 session_tracker_.LookupAllForeignSessions(&sessions, false); |
| 1034 return; // No foreign sessions. | |
| 1035 | |
| 1036 // Iterate through all the sessions and delete any with age older than | |
| 1037 // |stale_session_threshold_days_|. | |
| 1038 syncer::SyncChangeList changes; | 1038 syncer::SyncChangeList changes; |
| 1039 for (std::vector<const sync_driver::SyncedSession*>::const_iterator iter = | 1039 for (const auto* session : sessions) { |
| 1040 sessions.begin(); | |
| 1041 iter != sessions.end(); ++iter) { | |
| 1042 const sync_driver::SyncedSession* session = *iter; | |
| 1043 int session_age_in_days = | 1040 int session_age_in_days = |
| 1044 (base::Time::Now() - session->modified_time).InDays(); | 1041 (base::Time::Now() - session->modified_time).InDays(); |
| 1045 std::string session_tag = session->session_tag; | 1042 if (session_age_in_days > stale_session_threshold_days_) { |
| 1046 if (session_age_in_days > 0 && // If false, local clock is not trustworty. | 1043 std::string session_tag = session->session_tag; |
| 1047 static_cast<size_t>(session_age_in_days) > | |
| 1048 stale_session_threshold_days_) { | |
| 1049 DVLOG(1) << "Found stale session " << session_tag << " with age " | 1044 DVLOG(1) << "Found stale session " << session_tag << " with age " |
| 1050 << session_age_in_days << ", deleting."; | 1045 << session_age_in_days << ", deleting."; |
| 1051 DeleteForeignSessionInternal(session_tag, &changes); | 1046 DeleteForeignSessionInternal(session_tag, &changes); |
| 1052 } | 1047 } |
| 1053 } | 1048 } |
| 1054 | 1049 |
| 1055 if (!changes.empty()) | 1050 if (!changes.empty()) { |
|
Nicolas Zea
2016/04/12 20:38:03
nit: rest of file has (I think) been leaving curly
skym
2016/04/12 22:12:14
Done.
| |
| 1056 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 1051 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 1052 } | |
| 1057 } | 1053 } |
| 1058 | 1054 |
| 1059 }; // namespace browser_sync | 1055 }; // namespace browser_sync |
| OLD | NEW |