[ SavedTabGroups ] Tab Restore implementation for SavedTabGroups
Initial implementation for restoring SavedTabGroups and their tabs. List of Changes: - Ungrouped tabs will restore normally - Restored tabs which are grouped will be restored normally then saved - Restored groups will be restored normally and saved - Restore saved groups will open the saved group and add any tabs that are not in the list of tabs already - The first index of restored windows will be activated instead of the last index - The first index of restored groups will be activated instead of the last index Change-Id: I15c6a2f22b20cd2a01704d31286e253af05de16d Bug: 335270082 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5460410 Commit-Queue: Darryl James <dljames@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Eshwar Stalin <estalin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1291461}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
2961448b62
commit
ae5419e0b2
chrome/browser
performance_manager
sessions
ui
components/sessions/core
@ -41,6 +41,7 @@
|
||||
#include "components/sessions/core/tab_restore_types.h"
|
||||
#include "components/tab_groups/tab_group_id.h"
|
||||
#include "components/tab_groups/tab_group_visual_data.h"
|
||||
|
||||
namespace sessions {
|
||||
namespace {
|
||||
|
||||
@ -514,53 +515,24 @@ std::vector<LiveTab*> TabRestoreServiceHelper::RestoreEntryById(
|
||||
window.show_state, window.workspace, window.user_title,
|
||||
window.extra_data);
|
||||
|
||||
base::flat_map<tab_groups::TabGroupId, tab_groups::TabGroupId>
|
||||
new_group_ids;
|
||||
|
||||
for (size_t tab_i = 0; tab_i < window.tabs.size(); ++tab_i) {
|
||||
Tab& tab = *window.tabs[tab_i];
|
||||
|
||||
// Relabel group IDs to prevent duplicating groups, e.g. if the same
|
||||
// window is restored twice or a tab of the same ID is restored
|
||||
// elsewhere. See crbug.com/1202102.
|
||||
std::optional<tab_groups::TabGroupId> new_group;
|
||||
if (tab.group) {
|
||||
auto it = new_group_ids.find(*tab.group);
|
||||
if (it == new_group_ids.end()) {
|
||||
auto new_id = tab_groups::TabGroupId::GenerateNew();
|
||||
// Ensure the new ID does not collide with an existing group,
|
||||
// failing silently if it does. This is extremely unlikely,
|
||||
// given group IDs are 128 bit randomly generated numbers.
|
||||
if (client_->FindLiveTabContextWithGroup(new_id)) {
|
||||
return std::vector<LiveTab*>();
|
||||
}
|
||||
it = new_group_ids.emplace(*tab.group, new_id).first;
|
||||
}
|
||||
|
||||
new_group = it->second;
|
||||
tab.group = new_group;
|
||||
}
|
||||
|
||||
for (const auto& tab : window.tabs) {
|
||||
const bool first_tab = window.tabs[0]->id == tab->id;
|
||||
LiveTab* restored_tab = context->AddRestoredTab(
|
||||
tab, /*tab_index=*/context->GetTabCount(),
|
||||
/*select=*/static_cast<int>(tab_i) == window.selected_tab_index);
|
||||
*tab.get(), context->GetTabCount(), first_tab);
|
||||
|
||||
if (restored_tab) {
|
||||
client_->OnTabRestored(
|
||||
tab.navigations.at(tab.current_navigation_index).virtual_url());
|
||||
tab->navigations.at(tab->current_navigation_index)
|
||||
.virtual_url());
|
||||
live_tabs.push_back(restored_tab);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& tab_group : window.tab_groups) {
|
||||
context->SetVisualDataForGroup(new_group_ids.at(tab_group.first),
|
||||
tab_group.second);
|
||||
}
|
||||
|
||||
// All the window's tabs had the same former browser_id.
|
||||
// Update all tabs to point to the correct context.
|
||||
if (auto browser_id = window.tabs[0]->browser_id) {
|
||||
UpdateTabBrowserIDs(browser_id, context->GetSessionID());
|
||||
}
|
||||
|
||||
} else {
|
||||
// Restore a single tab from the window. Find the tab that matches the
|
||||
// ID in the window and restore it.
|
||||
@ -636,20 +608,9 @@ std::vector<LiveTab*> TabRestoreServiceHelper::RestoreEntryById(
|
||||
// single tab within it. If the entry's ID matches the one to restore,
|
||||
// then the entire group will be restored.
|
||||
if (entry_id_matches_restore_id) {
|
||||
// Restore the first tab in the group with the given disposition and
|
||||
// context. After that, subsequent tabs will automatically be restored
|
||||
// into the existing group.
|
||||
LiveTab* restored_tab = nullptr;
|
||||
context =
|
||||
RestoreTab(*group.tabs[0], context, disposition, &restored_tab);
|
||||
live_tabs.push_back(restored_tab);
|
||||
|
||||
for (size_t i = 1; i < group.tabs.size(); ++i) {
|
||||
// Restore the remaining tabs as background tabs, to keep the first
|
||||
// tab in the group active.
|
||||
context = RestoreTab(*group.tabs[i], context,
|
||||
WindowOpenDisposition::NEW_BACKGROUND_TAB,
|
||||
&restored_tab);
|
||||
for (const auto& tab : group.tabs) {
|
||||
LiveTab* restored_tab = context->AddRestoredTab(
|
||||
*tab.get(), context->GetTabCount(), group.tabs[0]->id == tab->id);
|
||||
live_tabs.push_back(restored_tab);
|
||||
}
|
||||
} else {
|
||||
@ -661,12 +622,7 @@ std::vector<LiveTab*> TabRestoreServiceHelper::RestoreEntryById(
|
||||
LiveTab* restored_tab = nullptr;
|
||||
context = RestoreTab(tab, context, disposition, &restored_tab);
|
||||
live_tabs.push_back(restored_tab);
|
||||
|
||||
DCHECK(ValidateGroup(group));
|
||||
group.tabs.erase(group.tabs.begin() + i);
|
||||
if (group.tabs.empty())
|
||||
entries_.erase(entry_iterator);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user