| Index: ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm
|
| diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm b/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..78f877284c3717eb2077ba1e651a894780c05d7c
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm
|
| @@ -0,0 +1,176 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h"
|
| +
|
| +#include <functional>
|
| +#include <memory>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/metrics/field_trial.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "components/sync/driver/sync_service.h"
|
| +#include "components/sync_sessions/open_tabs_ui_delegate.h"
|
| +#include "ios/chrome/browser/sync/sync_setup_service.h"
|
| +
|
| +namespace {
|
| +
|
| +// Comparator function for sorting the sessions_ vector so that the most
|
| +// recently used sessions are at the beginning.
|
| +bool SortSessionsByTime(
|
| + std::unique_ptr<const synced_sessions::DistantSession>& a,
|
| + std::unique_ptr<const synced_sessions::DistantSession>& b) {
|
| + return a->modified_time > b->modified_time;
|
| +}
|
| +
|
| +// Helper to extract the relevant content from a SessionTab and add it to a
|
| +// DistantSession.
|
| +void AddTabToDistantSession(const sessions::SessionTab& session_tab,
|
| + const std::string& session_tag,
|
| + synced_sessions::DistantSession* distant_session) {
|
| + if (session_tab.navigations.size() > 0) {
|
| + distant_session->tabs.push_back(
|
| + base::MakeUnique<synced_sessions::DistantTab>());
|
| + synced_sessions::DistantTab& distant_tab = *distant_session->tabs.back();
|
| + distant_tab.session_tag = session_tag;
|
| + distant_tab.tab_id = session_tab.tab_id.id();
|
| + int index = session_tab.current_navigation_index;
|
| + if (index < 0)
|
| + index = 0;
|
| + if (index > (int)session_tab.navigations.size() - 1)
|
| + index = session_tab.navigations.size() - 1;
|
| + const sessions::SerializedNavigationEntry* navigation =
|
| + &session_tab.navigations[index];
|
| + distant_tab.title = navigation->title();
|
| + distant_tab.virtual_url = navigation->virtual_url();
|
| + if (distant_tab.title.empty()) {
|
| + std::string url = navigation->virtual_url().spec();
|
| + distant_tab.title = base::UTF8ToUTF16(url);
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace synced_sessions {
|
| +
|
| +DistantTab::DistantTab() {}
|
| +
|
| +size_t DistantTab::hashOfUserVisibleProperties() {
|
| + std::stringstream ss;
|
| + ss << title << std::endl << virtual_url.spec();
|
| + return std::hash<std::string>()(ss.str());
|
| +}
|
| +
|
| +DistantSession::DistantSession() {}
|
| +
|
| +DistantSession::DistantSession(syncer::SyncService* sync_service,
|
| + const std::string& tag) {
|
| + if (sync_service->CanSyncStart() && sync_service->GetOpenTabsUIDelegate()) {
|
| + sync_sessions::OpenTabsUIDelegate* open_tabs =
|
| + sync_service->GetOpenTabsUIDelegate();
|
| +
|
| + std::vector<const sync_sessions::SyncedSession*> sessions;
|
| + open_tabs->GetAllForeignSessions(&sessions);
|
| + for (const auto& session : sessions) {
|
| + if (tag == session->session_tag) {
|
| + this->InitWithSyncedSession(session, open_tabs);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +DistantSession::~DistantSession() {}
|
| +
|
| +void DistantSession::InitWithSyncedSession(
|
| + const sync_sessions::SyncedSession* synced_session,
|
| + sync_sessions::OpenTabsUIDelegate* open_tabs) {
|
| + tag = synced_session->session_tag;
|
| + name = synced_session->session_name;
|
| + modified_time = synced_session->modified_time;
|
| + device_type = synced_session->device_type;
|
| +
|
| + const std::string group_name =
|
| + base::FieldTrialList::FindFullName("TabSyncByRecency");
|
| + if (group_name == "Enabled") {
|
| + // Order tabs by recency.
|
| + std::vector<const sessions::SessionTab*> session_tabs;
|
| + open_tabs->GetForeignSessionTabs(synced_session->session_tag,
|
| + &session_tabs);
|
| + for (const auto& session_tab : session_tabs) {
|
| + AddTabToDistantSession(*session_tab, synced_session->session_tag, this);
|
| + }
|
| + } else {
|
| + // Order tabs by their visual position within window.
|
| + for (const auto& kv : synced_session->windows) {
|
| + for (const auto& session_tab : kv.second->tabs) {
|
| + AddTabToDistantSession(*session_tab, synced_session->session_tag, this);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +SyncedSessions::SyncedSessions() {}
|
| +
|
| +SyncedSessions::SyncedSessions(syncer::SyncService* sync_service) {
|
| + DCHECK(sync_service);
|
| + // Reload Sync open tab sesions.
|
| + if (sync_service->CanSyncStart() && sync_service->GetOpenTabsUIDelegate()) {
|
| + sync_sessions::OpenTabsUIDelegate* open_tabs =
|
| + sync_service->GetOpenTabsUIDelegate();
|
| +
|
| + // Iterating through all remote sessions, then all remote windows, then all
|
| + // remote tabs to retrieve the tabs to display to the user. This will
|
| + // flatten all of those data into a sequential vector of tabs.
|
| +
|
| + std::vector<const sync_sessions::SyncedSession*> sessions;
|
| + open_tabs->GetAllForeignSessions(&sessions);
|
| + for (const auto& session : sessions) {
|
| + std::unique_ptr<DistantSession> distant_session(new DistantSession());
|
| + distant_session->InitWithSyncedSession(session, open_tabs);
|
| + // Don't display sessions with no tabs.
|
| + if (distant_session->tabs.size() > 0)
|
| + sessions_.push_back(std::move(distant_session));
|
| + }
|
| + }
|
| + std::sort(sessions_.begin(), sessions_.end(), SortSessionsByTime);
|
| +}
|
| +
|
| +SyncedSessions::~SyncedSessions() {}
|
| +
|
| +// Returns the session at index |index|.
|
| +DistantSession const* SyncedSessions::GetSession(size_t index) const {
|
| + DCHECK_LE(index, GetSessionCount());
|
| + return sessions_[index].get();
|
| +}
|
| +
|
| +const DistantSession* SyncedSessions::GetSessionWithTag(
|
| + const std::string& tag) const {
|
| + for (auto const& distant_session : sessions_) {
|
| + if (distant_session->tag == tag) {
|
| + return distant_session.get();
|
| + }
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +// Returns the number of distant sessions.
|
| +size_t SyncedSessions::GetSessionCount() const {
|
| + return sessions_.size();
|
| +}
|
| +
|
| +// Deletes the session at index |index|.
|
| +void SyncedSessions::EraseSession(size_t index) {
|
| + DCHECK_LE(index, GetSessionCount());
|
| + sessions_.erase(sessions_.begin() + index);
|
| +}
|
| +
|
| +void SyncedSessions::AddDistantSessionForTest(
|
| + std::unique_ptr<const DistantSession> distant_session) {
|
| + sessions_.push_back(std::move(distant_session));
|
| +}
|
| +
|
| +} // synced_sessions namespace
|
|
|