Files
electron/patches/chromium/feat_add_data_parameter_to_processsingleton.patch
electron-roller[bot] 9daf416097 chore: bump chromium to 122.0.6261.6 (29-x-y) (#40959)
* chore: bump chromium in DEPS to 122.0.6240.1

* chore: bump chromium in DEPS to 122.0.6241.6

* chore: bump chromium in DEPS to 122.0.6245.1

* chore: bump chromium in DEPS to 122.0.6247.1

* chore: bump chromium in DEPS to 122.0.6249.1

* chore: bump chromium in DEPS to 122.0.6251.1

* chore: bump chromium in DEPS to 122.0.6253.1

* chore: bump chromium in DEPS to 122.0.6255.1

* chore: bump chromium in DEPS to 122.0.6257.1

* chore: bump chromium in DEPS to 122.0.6259.1

* chore: bump chromium in DEPS to 122.0.6259.3

* chore: bump chromium in DEPS to 122.0.6259.5

* chore: bump chromium in DEPS to 122.0.6260.0

* chore: bump chromium in DEPS to 122.0.6261.1

* chore: bump chromium in DEPS to 122.0.6261.6

* chore: update patches

(cherry picked from commit dde66c3589)

* refactor: extensions replaced StringPiece with string_view

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/5171926
(cherry picked from commit c7031d5c05)

* chore: update patches

(cherry picked from commit 95b04b1fca)

* 5192010: Rename {absl => std}::optional in //chrome/

https://chromium-review.googlesource.com/c/chromium/src/+/5192010
(cherry picked from commit 55e5867614)

* 5109767: CodeHealth: Fix leaked raw_ptr in Linux ProcessSingleton

https://chromium-review.googlesource.com/c/chromium/src/+/5109767
(cherry picked from commit 7b2efc7586)

* 5105227: [media_preview] Show requested device in permission bubble

https://chromium-review.googlesource.com/c/chromium/src/+/5105227
(cherry picked from commit 10d61636c6)

* chore: update patches

(cherry picked from commit d04ebc7b07)

* 5180720: Polish tiled browser window UI on Linux | https://chromium-review.googlesource.com/c/chromium/src/+/5180720

(cherry picked from commit 3dbbb67dbc)

* chore: update patches

(cherry picked from commit 18a5961e4e)

* chore: update patches

(cherry picked from commit 69e0bfefcc)

* 5186276: [autopip] Make "allow once" per navigation | https://chromium-review.googlesource.com/c/chromium/src/+/5186276

(cherry picked from commit 412f70681a)

* chore: update patches

(cherry picked from commit e4d2a2ded0)

* 5190661: Automated T* -> raw_ptr<T> rewrite "refresh" | https://chromium-review.googlesource.com/c/chromium/src/+/5190661

(cherry picked from commit 6b41b72130)

* 5206106: Make sure RenderFrameHosts are active when printing | https://chromium-review.googlesource.com/c/chromium/src/+/5206106

(cherry picked from commit 9a788c0c60)

* 5202674: Reland "Automated T* -> raw_ptr<T> rewrite 'refresh'"

https://chromium-review.googlesource.com/c/chromium/src/+/5202674
(cherry picked from commit 55daca952d)

* fixup CodeHealth: Fix leaked raw_ptr in Linux ProcessSingleton

https://chromium-review.googlesource.com/c/chromium/src/+/5109767
(cherry picked from commit 047898ba92)

* fixup 5206106: Make sure RenderFrameHosts are active when printing

(cherry picked from commit 715c534cd8)

* Make legacy ToV8() helpers private to ScriptPromiseResolver, their only user

https://chromium-review.googlesource.com/c/chromium/src/+/5207474
(cherry picked from commit 9a10062d8c)

* fixup CodeHealth: Fix leaked raw_ptr in Linux ProcessSingleton

(cherry picked from commit a1f643b25e)

* fixup 5186276: [autopip] Make "allow once" per navigation

https://chromium-review.googlesource.com/c/chromium/src/+/5186276
(cherry picked from commit e3c40ed923)

* 5191363: Mark LOG(FATAL) [[noreturn]]

https://chromium-review.googlesource.com/c/chromium/src/+/5191363
(cherry picked from commit 8037cef988)

* fixup 5186276: [autopip] Make "allow once" per navigation

https://chromium-review.googlesource.com/c/chromium/src/+/5186276
(cherry picked from commit e60c31dd4f)

* fixup Make legacy ToV8() helpers private to ScriptPromiseResolver

 https://chromium-review.googlesource.com/c/chromium/src/+/5207474

(cherry picked from commit b02108e0c0)

* chore: update patches

(cherry picked from commit 96e8574115)

* chore: update patches

(cherry picked from commit e0f51957be)

* chore: restore patch that was mistakenly removed

(cherry picked from commit 4057b5439c)

* 5181931: Improve LoginHandler (Part 9 / N)

https://chromium-review.googlesource.com/c/chromium/src/+/5181931
(cherry picked from commit 6ad8028fe8)

* Dispatch SiteInstanceGotProcess() only when both process and site are set.

https://chromium-review.googlesource.com/c/chromium/src/+/5142354
(cherry picked from commit a871198a23)

* 5171446: [AsyncSB] Pass navigation_id into CreateURLLoaderThrottles

https://chromium-review.googlesource.com/c/chromium/src/+/5171446
(cherry picked from commit ebf2efcedd)

* 5213708: Move DownloadTargetInfo into components/download

https://chromium-review.googlesource.com/c/chromium/src/+/5213708
(cherry picked from commit c361ded147)

* extensions: Add a loader for Controlled Frame embedder scripts

https://chromium-review.googlesource.com/c/chromium/src/+/5202765
(cherry picked from commit 63d2773d15)

* [CSC][Zoom] Add initial_zoom_level to DisplayMediaInformation

https://chromium-review.googlesource.com/c/chromium/src/+/5168626
(cherry picked from commit a4b5c9ce31)

* fix: suppress clang -Wimplicit-const-int-float-conversion

(cherry picked from commit 979bde6683)

* fixup 5191363: Mark LOG(FATAL) [[noreturn]] for Windows

 https://chromium-review.googlesource.com/c/chromium/src/+/5191363

(cherry picked from commit 759f1740a8)

* 5167921: Remove Widget::IsTranslucentWindowOpacitySupported

https://chromium-review.googlesource.com/c/chromium/src/+/5167921

Also
5148392: PinnedState: Support pinned state in PlatformWindowState | https://chromium-review.googlesource.com/c/chromium/src/+/5148392

(cherry picked from commit 53d9c82a57)

* fixup: 5180720: Polish tiled browser window UI on Linux

https://chromium-review.googlesource.com/c/chromium/src/+/5180720
(cherry picked from commit e565db5095)

* 5170669: clipboard: Migrate DOMException constructors to RejectWith-

https://chromium-review.googlesource.com/c/chromium/src/+/5170669
(cherry picked from commit 5409118134)

* 5178824: [Fullscreen] Record UKM data

https://chromium-review.googlesource.com/c/chromium/src/+/5178824
(cherry picked from commit 3d53a6ec01)

* chore: update patches after rebase

(cherry picked from commit 3a6a335a05)

* chore: update patches after cherry picks

* chore: update patches after rebase

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-01-25 15:19:31 -05:00

347 lines
16 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Zhao <raymondzhao@microsoft.com>
Date: Tue, 7 Sep 2021 14:54:25 -0700
Subject: feat: Add data parameter to ProcessSingleton
This patch adds an additional_data parameter to the constructor of
ProcessSingleton, so that the second instance can send additional
data over to the first instance while requesting the ProcessSingleton
lock.
On the Electron side, we then expose an extra parameter to the
app.requestSingleInstanceLock API so that users can pass in a JSON
object for the second instance to send to the first instance.
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index 02d9eabfef9521722340739bf86df3dfc30018d7..af8639ebcc61d8081a12334f652a551d542cd758 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -18,6 +18,7 @@
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
+#include "base/containers/span.h"
#include "ui/gfx/native_widget_types.h"
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
@@ -99,22 +100,25 @@ class ProcessSingleton {
// handled within the current browser instance or false if the remote process
// should handle it (i.e., because the current process is shutting down).
using NotificationCallback =
- base::RepeatingCallback<bool(const base::CommandLine& command_line,
- const base::FilePath& current_directory)>;
+ base::RepeatingCallback<bool(const base::CommandLine& command_line,
+ const base::FilePath& current_directory,
+ const std::vector<const uint8_t> additional_data)>;
#if BUILDFLAG(IS_WIN)
ProcessSingleton(const std::string& program_name,
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
bool is_sandboxed,
const NotificationCallback& notification_callback);
#else
ProcessSingleton(const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
const NotificationCallback& notification_callback);
+#endif
ProcessSingleton(const ProcessSingleton&) = delete;
ProcessSingleton& operator=(const ProcessSingleton&) = delete;
-#endif
~ProcessSingleton();
// Notify another process, if available. Otherwise sets ourselves as the
@@ -178,7 +182,10 @@ class ProcessSingleton {
#endif
private:
+ // A callback to run when the first instance receives data from the second.
NotificationCallback notification_callback_; // Handler for notifications.
+ // Custom data to pass to the other instance during notify.
+ base::span<const uint8_t> additional_data_;
#if BUILDFLAG(IS_WIN)
bool EscapeVirtualization(const base::FilePath& user_data_dir);
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index 298c9c81fa110ad7900d0bd6822136bb57f0382e..da7aaed23e4e0cdc037490bbe8beaea705b48df5 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -610,6 +610,7 @@ class ProcessSingleton::LinuxWatcher
// |reader| is for sending back ACK message.
void HandleMessage(const std::string& current_dir,
const std::vector<std::string>& argv,
+ const std::vector<const uint8_t> additional_data,
SocketReader* reader);
// Called when the ProcessSingleton that owns this class is about to be
@@ -669,13 +670,17 @@ void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
}
void ProcessSingleton::LinuxWatcher::HandleMessage(
- const std::string& current_dir, const std::vector<std::string>& argv,
+ const std::string& current_dir,
+ const std::vector<std::string>& argv,
+ const std::vector<const uint8_t> additional_data,
SocketReader* reader) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(reader);
if (parent_ && parent_->notification_callback_.Run(
- base::CommandLine(argv), base::FilePath(current_dir))) {
+ base::CommandLine(argv),
+ base::FilePath(current_dir),
+ std::move(additional_data))) {
// Send back "ACK" message to prevent the client process from starting up.
reader->FinishWithACK(kACKToken, std::size(kACKToken) - 1);
} else {
@@ -723,7 +728,8 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
}
}
- // Validate the message. The shortest message is kStartToken\0x\0x
+ // Validate the message. The shortest message kStartToken\0\00
+ // The shortest message with additional data is kStartToken\0\00\00\0.
const size_t kMinMessageLength = std::size(kStartToken) + 4;
if (bytes_read_ < kMinMessageLength) {
buf_[bytes_read_] = 0;
@@ -753,10 +759,28 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
tokens.erase(tokens.begin());
tokens.erase(tokens.begin());
+ size_t num_args;
+ base::StringToSizeT(tokens[0], &num_args);
+ std::vector<std::string> command_line(tokens.begin() + 1, tokens.begin() + 1 + num_args);
+
+ std::vector<const uint8_t> additional_data;
+ if (tokens.size() >= 3 + num_args) {
+ size_t additional_data_size;
+ base::StringToSizeT(tokens[1 + num_args], &additional_data_size);
+ std::string remaining_args = base::JoinString(
+ base::make_span(tokens.begin() + 2 + num_args, tokens.end()),
+ std::string(1, kTokenDelimiter));
+ const uint8_t* additional_data_bits =
+ reinterpret_cast<const uint8_t*>(remaining_args.c_str());
+ additional_data = std::vector<const uint8_t>(
+ additional_data_bits, additional_data_bits + additional_data_size);
+ }
+
// Return to the UI thread to handle opening a new browser tab.
ui_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ProcessSingleton::LinuxWatcher::HandleMessage,
- parent_, current_dir, tokens, this));
+ parent_, current_dir, command_line,
+ std::move(additional_data), this));
fd_watch_controller_.reset();
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
@@ -785,8 +809,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
//
ProcessSingleton::ProcessSingleton(
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ additional_data_(additional_data),
current_pid_(base::GetCurrentProcId()) {
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
@@ -907,7 +933,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
sizeof(socket_timeout));
// Found another process, prepare our command line
- // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>".
+ // format is "START\0<current-dir>\0<n-args>\0<argv[0]>\0...\0<argv[n]>
+ // \0<additional-data-length>\0<additional-data>".
std::string to_send(kStartToken);
to_send.push_back(kTokenDelimiter);
@@ -917,11 +944,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = cmd_line.argv();
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(base::NumberToString(argv.size()));
for (auto it = argv.begin(); it != argv.end(); ++it) {
to_send.push_back(kTokenDelimiter);
to_send.append(*it);
}
+ size_t data_to_send_size = additional_data_.size_bytes();
+ if (data_to_send_size) {
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(base::NumberToString(data_to_send_size));
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(reinterpret_cast<const char*>(additional_data_.data()), data_to_send_size);
+ }
+
// Send the message
if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
// Try to kill the other process, because it might have been dead.
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index 11f35769cc53b4aa111a319d155a3916f0040fa7..8e3e870eaac14ce6886878b027c7cf2eba19a759 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -80,10 +80,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line,
- base::FilePath* current_directory) {
+ base::FilePath* current_directory,
+ std::vector<const uint8_t>* parsed_additional_data) {
// We should have enough room for the shortest command (min_message_size)
// and also be a multiple of wchar_t bytes. The shortest command
- // possible is L"START\0\0" (empty current directory and command line).
+ // possible is L"START\0\0" (empty command line, current directory,
+ // and additional data).
static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) {
@@ -133,6 +135,37 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line);
+
+ const std::wstring::size_type fourth_null =
+ msg.find_first_of(L'\0', third_null + 1);
+ if (fourth_null == std::wstring::npos ||
+ fourth_null == msg.length()) {
+ // No additional data was provided.
+ return true;
+ }
+
+ // Get length of the additional data.
+ const std::wstring additional_data_length_string =
+ msg.substr(third_null + 1, fourth_null - third_null);
+ size_t additional_data_length;
+ base::StringToSizeT(additional_data_length_string, &additional_data_length);
+
+ const std::wstring::size_type fifth_null =
+ msg.find_first_of(L'\0', fourth_null + 1);
+ if (fifth_null == std::wstring::npos ||
+ fifth_null == msg.length()) {
+ LOG(WARNING) << "Invalid format for start command, we need a string in 6 "
+ "parts separated by NULLs";
+ }
+
+ // Get the actual additional data.
+ const std::wstring additional_data =
+ msg.substr(fourth_null + 1, fifth_null - fourth_null);
+ const uint8_t* additional_data_bytes =
+ reinterpret_cast<const uint8_t*>(additional_data.c_str());
+ *parsed_additional_data = std::vector<const uint8_t>(additional_data_bytes,
+ additional_data_bytes + additional_data_length);
+
return true;
}
return false;
@@ -154,13 +187,14 @@ bool ProcessLaunchNotification(
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
base::FilePath current_directory;
- if (!ParseCommandLine(cds, &parsed_command_line, &current_directory)) {
+ std::vector<const uint8_t> additional_data;
+ if (!ParseCommandLine(cds, &parsed_command_line, &current_directory, &additional_data)) {
*result = TRUE;
return true;
}
- *result = notification_callback.Run(parsed_command_line, current_directory) ?
- TRUE : FALSE;
+ *result = notification_callback.Run(parsed_command_line,
+ current_directory, std::move(additional_data)) ? TRUE : FALSE;
return true;
}
@@ -264,9 +298,11 @@ bool ProcessSingleton::EscapeVirtualization(
ProcessSingleton::ProcessSingleton(
const std::string& program_name,
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
bool is_app_sandboxed,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ additional_data_(additional_data),
program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
@@ -293,7 +329,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE;
}
- switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) {
+ switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) {
case chrome::NOTIFY_SUCCESS:
return PROCESS_NOTIFIED;
case chrome::NOTIFY_FAILED:
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
index fb3590431bd7986a6966bcebabfc244080870542..0c9150043279f77bcdf9f6e5bf90b97998c80e00 100644
--- a/chrome/browser/win/chrome_process_finder.cc
+++ b/chrome/browser/win/chrome_process_finder.cc
@@ -40,7 +40,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
return base::win::MessageWindow::FindWindow(user_data_dir.value());
}
-NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
+NotifyChromeResult AttemptToNotifyRunningChrome(
+ HWND remote_window,
+ const base::span<const uint8_t> additional_data) {
TRACE_EVENT0("startup", "AttemptToNotifyRunningChrome");
DCHECK(remote_window);
@@ -69,12 +71,29 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
new_command_line.AppendSwitchNative(switches::kSourceShortcut, si.lpTitle);
// Send the command line to the remote chrome window.
- // Format is "START\0<<<current directory>>>\0<<<commandline>>>".
+ // Format is
+ // "START\0<current-directory>\0<command-line>\0<additional-data-length>\0<additional-data>".
std::wstring to_send = base::StrCat(
{std::wstring_view{L"START\0", 6}, cur_dir.value(),
std::wstring_view{L"\0", 1}, new_command_line.GetCommandLineString(),
std::wstring_view{L"\0", 1}});
+ size_t additional_data_size = additional_data.size_bytes();
+ if (additional_data_size) {
+ // Send over the size, because the reinterpret cast to wchar_t could
+ // add padding.
+ to_send.append(base::UTF8ToWide(base::NumberToString(additional_data_size)));
+ to_send.append(L"\0", 1); // Null separator.
+
+ size_t padded_size = additional_data_size / sizeof(wchar_t);
+ if (additional_data_size % sizeof(wchar_t) != 0) {
+ padded_size++;
+ }
+ to_send.append(reinterpret_cast<const wchar_t*>(additional_data.data()),
+ padded_size);
+ to_send.append(L"\0", 1); // Null separator.
+ }
+
// Allow the current running browser window to make itself the foreground
// window (otherwise it will just flash in the taskbar).
::AllowSetForegroundWindow(process_id);
diff --git a/chrome/browser/win/chrome_process_finder.h b/chrome/browser/win/chrome_process_finder.h
index ddea93de709db5967a353bb73d433737c6aac40c..43c6896923032ffa16a0df4efd48a42f869c15d7 100644
--- a/chrome/browser/win/chrome_process_finder.h
+++ b/chrome/browser/win/chrome_process_finder.h
@@ -7,6 +7,7 @@
#include <windows.h>
+#include "base/containers/span.h"
#include "base/time/time.h"
namespace base {
@@ -27,7 +28,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir);
// Attempts to send the current command line to an already running instance of
// Chrome via a WM_COPYDATA message.
// Returns true if a running Chrome is found and successfully notified.
-NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window);
+NotifyChromeResult AttemptToNotifyRunningChrome(
+ HWND remote_window,
+ const base::span<const uint8_t> additional_data);
// Changes the notification timeout to |new_timeout|, returns the old timeout.
base::TimeDelta SetNotificationTimeoutForTesting(base::TimeDelta new_timeout);