0

wayland: xdg-session-management: Add command for platform_session_id

Some platforms support window-related session management at display
server side. Such as, Linux/Wayland with xdg-session-management protocol
extension. In that case, 1 new piece of data must be requested and
persisted by the client application in order to be able to ask the
windowing system to restore window states when needed:

- platform_session_id: a string that identifies a platform session,
  generated by the display server (eg: the Wayland compositor
  implementing the xdg-session-management protocol), stored by chromium
  in the session commands backing storage, and sent back to the display
  server when restoring a browser session.

Further design notes available at
https://notes.nickdiego.dev/chromium/wayland-session-management

The upcoming CLs will add the remaining bits, including:

- UI/Views framework API required additions.
- Ozone/Wayland implementation based on xdg-toplevel-drag-v1 protocol.
- Chrome required plumbing and required changes.

Bug: 352081012
Change-Id: I5d2d7c5755c1cf5848bffd6231cc75f3fda2def3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6329136
Reviewed-by: Darryl James <dljames@chromium.org>
Commit-Queue: Nick Yamane <nickdiego@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1437661}
This commit is contained in:
Nick Diego Yamane
2025-03-25 12:14:54 -07:00
committed by Chromium LUCI CQ
parent 46b457cf14
commit d0faf7d8b4
10 changed files with 140 additions and 44 deletions

@ -165,6 +165,19 @@ std::unique_ptr<SessionCommand> CreateAddExtraDataCommand(
return std::make_unique<SessionCommand>(command, pickle);
}
std::unique_ptr<SessionCommand> CreateSetPlatformSessionIdCommand(
SessionCommand::id_type command_id,
const std::string& platform_session_id) {
base::Pickle pickle;
static const SessionCommand::size_type max_id_size =
std::numeric_limits<SessionCommand::size_type>::max() - 1024;
int bytes_written = 0;
WriteStringToPickle(pickle, &bytes_written, max_id_size, platform_session_id);
return std::make_unique<SessionCommand>(command_id, pickle);
}
bool RestoreUpdateTabNavigationCommand(
const SessionCommand& command,
sessions::SerializedNavigationEntry* navigation,
@ -260,4 +273,12 @@ bool RestoreAddExtraDataCommand(const SessionCommand& command,
it.ReadString(data);
}
bool RestoreSetPlatformSessionIdCommand(const SessionCommand& command,
std::string* platform_session_id) {
base::Pickle pickle = command.PayloadAsPickle();
base::PickleIterator iterator(pickle);
return iterator.ReadString(platform_session_id);
}
} // namespace sessions

@ -59,6 +59,11 @@ std::unique_ptr<SessionCommand> CreateAddExtraDataCommand(
const std::string& key,
const std::string& data);
// Creates a SessionCommand storing the platform session id.
std::unique_ptr<SessionCommand> CreateSetPlatformSessionIdCommand(
SessionCommand::id_type command_id,
const std::string& platform_session_id);
// Converts a SessionCommand previously created by
// CreateUpdateTabNavigationCommand into a
// SerializedNavigationEntry. Returns true on success. If
@ -109,6 +114,11 @@ bool RestoreAddExtraDataCommand(const SessionCommand& command,
std::string* key,
std::string* data);
// Extracts a SessionCommand as previously created by
// CreateSetPlatformSessionIdCommand into platform_session_id.
bool RestoreSetPlatformSessionIdCommand(const SessionCommand& command,
std::string* platform_session_id);
} // namespace sessions
#endif // COMPONENTS_SESSIONS_CORE_BASE_SESSION_SERVICE_COMMANDS_H_

@ -80,6 +80,7 @@ static const SessionCommand::id_type kCommandSetWindowVisibleOnAllWorkspaces =
32;
static const SessionCommand::id_type kCommandAddTabExtraData = 33;
static const SessionCommand::id_type kCommandAddWindowExtraData = 34;
static const SessionCommand::id_type kCommandSetPlatformSessionId = 35;
// ID 255 is used by CommandStorageBackend.
namespace {
@ -452,7 +453,8 @@ void CreateTabsAndWindows(
IdToSessionTab* tabs,
GroupIdToSessionTabGroup* tab_groups,
IdToSessionWindow* windows,
SessionID* active_window_id) {
SessionID* active_window_id,
std::string* platform_session_id) {
// If the file is corrupt (command with wrong size, or unknown command), we
// still return true and attempt to restore what we we can.
DVLOG(1) << "CreateTabsAndWindows";
@ -905,6 +907,17 @@ void CreateTabsAndWindows(
break;
}
case kCommandSetPlatformSessionId: {
std::string id;
if (!RestoreSetPlatformSessionIdCommand(*command, &id)) {
DVLOG(1) << "Failed reading command " << command->id();
return;
}
DVLOG(1) << " restored platform_session_id=" << id;
*platform_session_id = id;
break;
}
default:
DVLOG(1) << "Failed reading an unknown command " << command->id();
return;
@ -1174,6 +1187,12 @@ std::unique_ptr<SessionCommand> CreateAddWindowExtraDataCommand(
data);
}
std::unique_ptr<SessionCommand> CreateSetPlatformSessionIdCommand(
const std::string& platform_session_id) {
return CreateSetPlatformSessionIdCommand(kCommandSetPlatformSessionId,
platform_session_id);
}
bool ReplacePendingCommand(CommandStorageManager* command_storage_manager,
std::unique_ptr<SessionCommand>* command) {
// We optimize page navigations, which can happen quite frequently and
@ -1237,14 +1256,15 @@ bool IsClosingCommand(SessionCommand* command) {
void RestoreSessionFromCommands(
const std::vector<std::unique_ptr<SessionCommand>>& commands,
std::vector<std::unique_ptr<SessionWindow>>* valid_windows,
SessionID* active_window_id) {
SessionID* active_window_id,
std::string* platform_session_id) {
IdToSessionTab tabs;
GroupIdToSessionTabGroup tab_groups;
IdToSessionWindow windows;
DVLOG(1) << "RestoreSessionFromCommands " << commands.size();
CreateTabsAndWindows(commands, &tabs, &tab_groups, &windows,
active_window_id);
CreateTabsAndWindows(commands, &tabs, &tab_groups, &windows, active_window_id,
platform_session_id);
AddTabsToWindows(&tabs, &tab_groups, &windows);
SortTabsBasedOnVisualOrderAndClear(&windows, valid_windows);
UpdateSelectedTabIndex(valid_windows);

@ -111,6 +111,9 @@ SESSIONS_EXPORT std::unique_ptr<SessionCommand> CreateAddWindowExtraDataCommand(
const std::string& key,
const std::string& data);
SESSIONS_EXPORT std::unique_ptr<SessionCommand>
CreateSetPlatformSessionIdCommand(const std::string& platform_session_id);
// Searches for a pending command using |command_storage_manager| that can be
// replaced with |command|. If one is found, pending command is removed, the
// command is added to the pending commands (taken ownership) and true is
@ -129,7 +132,8 @@ SESSIONS_EXPORT bool IsClosingCommand(SessionCommand* command);
SESSIONS_EXPORT void RestoreSessionFromCommands(
const std::vector<std::unique_ptr<SessionCommand>>& commands,
std::vector<std::unique_ptr<SessionWindow>>* valid_windows,
SessionID* active_window_id);
SessionID* active_window_id,
std::string* platform_session_id);
} // namespace sessions