// Copyright 2018 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 "components/sync_sessions/test_synced_window_delegates_getter.h" #include #include "base/bind.h" #include "base/containers/cxx20_erase.h" #include "components/sessions/core/serialized_navigation_entry_test_helper.h" #include "components/sync_sessions/synced_session.h" #include "components/sync_sessions/tab_node_pool.h" namespace sync_sessions { namespace { const char kTitle[] = "title"; } // namespace TestSyncedTabDelegate::TestSyncedTabDelegate( SessionID window_id, SessionID tab_id, const base::RepeatingCallback& notify_cb) : window_id_(window_id), tab_id_(tab_id), notify_cb_(notify_cb) {} TestSyncedTabDelegate::~TestSyncedTabDelegate() = default; void TestSyncedTabDelegate::Navigate(const std::string& url, base::Time time, ui::PageTransition transition) { sync_pb::TabNavigation tab_navigation; tab_navigation.set_virtual_url(url); tab_navigation.set_title(kTitle); tab_navigation.set_global_id(time.ToInternalValue()); tab_navigation.set_unique_id(time.ToInternalValue()); tab_navigation.set_http_status_code(200); auto entry = std::make_unique( SessionNavigationFromSyncData(0, tab_navigation)); sessions::SerializedNavigationEntryTestHelper::SetTimestamp(time, entry.get()); sessions::SerializedNavigationEntryTestHelper::SetTransitionType(transition, entry.get()); entries_.push_back(std::move(entry)); page_language_per_index_.emplace_back(); set_current_entry_index(GetCurrentEntryIndex() + 1); notify_cb_.Run(this); } void TestSyncedTabDelegate::set_current_entry_index(int i) { current_entry_index_ = i; } void TestSyncedTabDelegate::set_blocked_navigations( const std::vector>& navs) { for (auto& entry : navs) { blocked_navigations_.push_back( std::make_unique(*entry)); } } void TestSyncedTabDelegate::SetPageLanguageAtIndex( int i, const std::string& language) { page_language_per_index_[i] = language; } bool TestSyncedTabDelegate::IsInitialBlankNavigation() const { // This differs from NavigationControllerImpl, which has an initial blank // NavigationEntry. return GetEntryCount() == 0; } int TestSyncedTabDelegate::GetCurrentEntryIndex() const { return current_entry_index_; } GURL TestSyncedTabDelegate::GetVirtualURLAtIndex(int i) const { if (static_cast(i) >= entries_.size()) { return GURL(); } return entries_[i]->virtual_url(); } std::string TestSyncedTabDelegate::GetPageLanguageAtIndex(int i) const { DCHECK(static_cast(i) < page_language_per_index_.size()); return page_language_per_index_[i]; } void TestSyncedTabDelegate::GetSerializedNavigationAtIndex( int i, sessions::SerializedNavigationEntry* serialized_entry) const { if (static_cast(i) >= entries_.size()) { return; } *serialized_entry = *entries_[i]; } int TestSyncedTabDelegate::GetEntryCount() const { return entries_.size(); } SessionID TestSyncedTabDelegate::GetWindowId() const { return window_id_; } SessionID TestSyncedTabDelegate::GetSessionId() const { return tab_id_; } bool TestSyncedTabDelegate::IsBeingDestroyed() const { return false; } std::string TestSyncedTabDelegate::GetExtensionAppId() const { return std::string(); } bool TestSyncedTabDelegate::ProfileHasChildAccount() const { return has_child_account_; } void TestSyncedTabDelegate::set_has_child_account(bool has_child_account) { has_child_account_ = has_child_account; } const std::vector>* TestSyncedTabDelegate::GetBlockedNavigations() const { return &blocked_navigations_; } bool TestSyncedTabDelegate::IsPlaceholderTab() const { return false; } bool TestSyncedTabDelegate::ShouldSync(SyncSessionsClient* sessions_client) { // This is just a simple filter that isn't meant to fully reproduce // the TabContentsTabDelegate's ShouldSync logic. // Verify all URL's are valid (which will ignore an initial blank page) and // that there is at least one http:// url. int http_count = 0; for (auto& entry : entries_) { if (!entry->virtual_url().is_valid()) { return false; } if (entry->virtual_url().SchemeIsHTTPOrHTTPS()) { http_count++; } } return http_count > 0; } int64_t TestSyncedTabDelegate::GetTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. return -1; } int64_t TestSyncedTabDelegate::GetParentTaskIdForNavigationId( int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. return -1; } int64_t TestSyncedTabDelegate::GetRootTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. return -1; } PlaceholderTabDelegate::PlaceholderTabDelegate(SessionID tab_id) : tab_id_(tab_id) {} PlaceholderTabDelegate::~PlaceholderTabDelegate() = default; SessionID PlaceholderTabDelegate::GetSessionId() const { return tab_id_; } bool PlaceholderTabDelegate::IsPlaceholderTab() const { return true; } SessionID PlaceholderTabDelegate::GetWindowId() const { NOTREACHED(); return SessionID::InvalidValue(); } bool PlaceholderTabDelegate::IsBeingDestroyed() const { NOTREACHED(); return false; } std::string PlaceholderTabDelegate::GetExtensionAppId() const { NOTREACHED(); return ""; } bool PlaceholderTabDelegate::IsInitialBlankNavigation() const { NOTREACHED(); return false; } int PlaceholderTabDelegate::GetCurrentEntryIndex() const { NOTREACHED(); return 0; } int PlaceholderTabDelegate::GetEntryCount() const { NOTREACHED(); return 0; } GURL PlaceholderTabDelegate::GetVirtualURLAtIndex(int i) const { NOTREACHED(); return GURL(); } std::string PlaceholderTabDelegate::GetPageLanguageAtIndex(int i) const { NOTREACHED(); return std::string(); } void PlaceholderTabDelegate::GetSerializedNavigationAtIndex( int i, sessions::SerializedNavigationEntry* serialized_entry) const { NOTREACHED(); } bool PlaceholderTabDelegate::ProfileHasChildAccount() const { NOTREACHED(); return false; } const std::vector>* PlaceholderTabDelegate::GetBlockedNavigations() const { NOTREACHED(); return nullptr; } bool PlaceholderTabDelegate::ShouldSync(SyncSessionsClient* sessions_client) { NOTREACHED(); return false; } int64_t PlaceholderTabDelegate::GetTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. NOTREACHED() << "Task IDs are not used for Placeholder Tabs"; return -1; } int64_t PlaceholderTabDelegate::GetParentTaskIdForNavigationId( int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. NOTREACHED() << "Task IDs are not used for Placeholder Tabs"; return -1; } int64_t PlaceholderTabDelegate::GetRootTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. NOTREACHED() << "Task IDs are not used for Placeholder Tabs"; return -1; } TestSyncedWindowDelegate::TestSyncedWindowDelegate( SessionID window_id, sync_pb::SyncEnums_BrowserType type) : window_id_(window_id), window_type_(type), is_session_restore_in_progress_(false) {} TestSyncedWindowDelegate::~TestSyncedWindowDelegate() = default; void TestSyncedWindowDelegate::OverrideTabAt(int index, SyncedTabDelegate* delegate) { if (index >= static_cast(tab_delegates_.size())) { tab_delegates_.resize(index + 1, nullptr); } tab_delegates_[index] = delegate; } void TestSyncedWindowDelegate::CloseTab(SessionID tab_id) { base::EraseIf(tab_delegates_, [tab_id](SyncedTabDelegate* tab) { return tab->GetSessionId() == tab_id; }); } void TestSyncedWindowDelegate::SetIsSessionRestoreInProgress(bool value) { is_session_restore_in_progress_ = value; } bool TestSyncedWindowDelegate::HasWindow() const { return true; } SessionID TestSyncedWindowDelegate::GetSessionId() const { return window_id_; } int TestSyncedWindowDelegate::GetTabCount() const { return tab_delegates_.size(); } int TestSyncedWindowDelegate::GetActiveIndex() const { return 0; } bool TestSyncedWindowDelegate::IsTypeNormal() const { return window_type_ == sync_pb::SyncEnums_BrowserType_TYPE_TABBED; } bool TestSyncedWindowDelegate::IsTypePopup() const { return window_type_ == sync_pb::SyncEnums_BrowserType_TYPE_POPUP; } bool TestSyncedWindowDelegate::IsTabPinned(const SyncedTabDelegate* tab) const { return false; } SyncedTabDelegate* TestSyncedWindowDelegate::GetTabAt(int index) const { if (index >= static_cast(tab_delegates_.size())) { return nullptr; } return tab_delegates_[index]; } SessionID TestSyncedWindowDelegate::GetTabIdAt(int index) const { SyncedTabDelegate* delegate = GetTabAt(index); if (!delegate) { return SessionID::InvalidValue(); } return delegate->GetSessionId(); } bool TestSyncedWindowDelegate::IsSessionRestoreInProgress() const { return is_session_restore_in_progress_; } bool TestSyncedWindowDelegate::ShouldSync() const { return true; } TestSyncedWindowDelegatesGetter::TestSyncedWindowDelegatesGetter() = default; TestSyncedWindowDelegatesGetter::~TestSyncedWindowDelegatesGetter() = default; void TestSyncedWindowDelegatesGetter::ResetWindows() { delegates_.clear(); windows_.clear(); } TestSyncedWindowDelegate* TestSyncedWindowDelegatesGetter::AddWindow( sync_pb::SyncEnums_BrowserType type, SessionID window_id) { windows_.push_back( std::make_unique(window_id, type)); CHECK_EQ(window_id, windows_.back()->GetSessionId()); delegates_[window_id] = windows_.back().get(); return windows_.back().get(); } TestSyncedTabDelegate* TestSyncedWindowDelegatesGetter::AddTab( SessionID window_id, SessionID tab_id) { tabs_.push_back(std::make_unique( window_id, tab_id, base::BindRepeating(&DummyRouter::NotifyNav, base::Unretained(&router_)))); for (auto& window : windows_) { if (window->GetSessionId() == window_id) { int tab_index = window->GetTabCount(); window->OverrideTabAt(tab_index, tabs_.back().get()); } } // Simulate the browser firing a tab parented notification, ahead of actual // navigations. router_.NotifyNav(tabs_.back().get()); return tabs_.back().get(); } void TestSyncedWindowDelegatesGetter::CloseTab(SessionID tab_id) { for (auto& window : windows_) { // CloseTab() will only take effect with the belonging window, the rest will // simply ignore the call. window->CloseTab(tab_id); } } void TestSyncedWindowDelegatesGetter::SessionRestoreComplete() { for (auto& window : windows_) { window->SetIsSessionRestoreInProgress(false); } router_.NotifySessionRestoreComplete(); } LocalSessionEventRouter* TestSyncedWindowDelegatesGetter::router() { return &router_; } SyncedWindowDelegatesGetter::SyncedWindowDelegateMap TestSyncedWindowDelegatesGetter::GetSyncedWindowDelegates() { return delegates_; } const SyncedWindowDelegate* TestSyncedWindowDelegatesGetter::FindById( SessionID session_id) { for (const auto& [window_id, delegate] : delegates_) { if (delegate->GetSessionId() == session_id) { return delegate; } } return nullptr; } TestSyncedWindowDelegatesGetter::DummyRouter::DummyRouter() = default; TestSyncedWindowDelegatesGetter::DummyRouter::~DummyRouter() = default; void TestSyncedWindowDelegatesGetter::DummyRouter::StartRoutingTo( LocalSessionEventHandler* handler) { handler_ = handler; } void TestSyncedWindowDelegatesGetter::DummyRouter::Stop() { handler_ = nullptr; } void TestSyncedWindowDelegatesGetter::DummyRouter::NotifyNav( SyncedTabDelegate* tab) { if (handler_) { handler_->OnLocalTabModified(tab); } } void TestSyncedWindowDelegatesGetter::DummyRouter:: NotifySessionRestoreComplete() { if (handler_) { handler_->OnSessionRestoreComplete(); } } } // namespace sync_sessions