From 2e65f78874477a2f595304f3d1e283ecde9d02ea Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 13 Nov 2020 14:51:40 -0800 Subject: [PATCH] browser(firefox): close browser when pipe disconnects (#4437) --- browser_patches/firefox/BUILD_NUMBER | 4 ++-- .../firefox/juggler/components/juggler.js | 22 ++++++++++++++----- .../juggler/pipe/nsIRemoteDebuggingPipe.idl | 1 + .../juggler/pipe/nsRemoteDebuggingPipe.cpp | 13 ++++++++++- .../juggler/pipe/nsRemoteDebuggingPipe.h | 1 + 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 4bdcbffe9e..20368e38d4 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1206 -Changed: yurys@chromium.org Thu 12 Nov 2020 10:23:24 AM PST +1207 +Changed: dgozman@gmail.com Fri Nov 13 14:41:15 PST 2020 diff --git a/browser_patches/firefox/juggler/components/juggler.js b/browser_patches/firefox/juggler/components/juggler.js index bba1f9d491..7fd1ca3ad6 100644 --- a/browser_patches/firefox/juggler/components/juggler.js +++ b/browser_patches/firefox/juggler/components/juggler.js @@ -79,6 +79,8 @@ CommandLineHandler.prototype = { loadFrameScript(); dump(`Juggler listening on ws://127.0.0.1:${this._server.port}/${token}\n`); } else if (jugglerPipeFlag) { + let browserHandler; + let pipeStopped = false; const pipe = Cc['@mozilla.org/juggler/remotedebuggingpipe;1'].getService(Ci.nsIRemoteDebuggingPipe); const connection = { QueryInterface: ChromeUtils.generateQI([Ci.nsIRemoteDebuggingPipeClient]), @@ -86,20 +88,28 @@ CommandLineHandler.prototype = { if (this.onmessage) this.onmessage({ data: message }); }, + disconnected() { + if (browserHandler) + browserHandler['Browser.close'](); + }, send(message) { + if (pipeStopped) { + // We are missing the response to Browser.close, + // but everything works fine. Once we actually need it, + // we have to stop the pipe after the response is sent. + return; + } pipe.sendMessage(message); }, }; pipe.init(connection); const dispatcher = new Dispatcher(connection); - const browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => { + browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => { if (silent) Services.startup.exitLastWindowClosingSurvivalArea(); - // Send response to the Browser.close, and then stop in the next microtask. - Promise.resolve().then(() => { - connection.onclose(); - pipe.stop(); - }); + connection.onclose(); + pipe.stop(); + pipeStopped = true; }); dispatcher.rootSession().setHandler(browserHandler); loadFrameScript(); diff --git a/browser_patches/firefox/juggler/pipe/nsIRemoteDebuggingPipe.idl b/browser_patches/firefox/juggler/pipe/nsIRemoteDebuggingPipe.idl index ab28b21674..ac91b63615 100644 --- a/browser_patches/firefox/juggler/pipe/nsIRemoteDebuggingPipe.idl +++ b/browser_patches/firefox/juggler/pipe/nsIRemoteDebuggingPipe.idl @@ -8,6 +8,7 @@ interface nsIRemoteDebuggingPipeClient : nsISupports { void receiveMessage(in AString message); + void disconnected(); }; [scriptable, uuid(b7bfb66b-fd46-4aa2-b4ad-396177186d94)] diff --git a/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.cpp b/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.cpp index cd6b501e4e..0602a1c3b3 100644 --- a/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.cpp +++ b/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.cpp @@ -151,8 +151,13 @@ void nsRemoteDebuggingPipe::ReaderLoop() { std::vector line; while (!m_terminated) { size_t size = ReadBytes(buffer.data(), bufSize, false); - if (!size) + if (!size) { + nsCOMPtr runnable = NewRunnableMethod<>( + "nsRemoteDebuggingPipe::Disconnected", + this, &nsRemoteDebuggingPipe::Disconnected); + NS_DispatchToMainThread(runnable.forget()); break; + } size_t start = 0; size_t end = line.size(); line.insert(line.end(), buffer.begin(), buffer.begin() + size); @@ -191,6 +196,12 @@ void nsRemoteDebuggingPipe::ReceiveMessage(const nsCString& aMessage) { } } +void nsRemoteDebuggingPipe::Disconnected() { + MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Remote debugging pipe must be used on the Main thread."); + if (mClient) + mClient->Disconnected(); +} + nsresult nsRemoteDebuggingPipe::SendMessage(const nsAString& aMessage) { MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Remote debugging pipe must be used on the Main thread."); if (!mClient) { diff --git a/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.h b/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.h index 422758cdc7..be4cb2675e 100644 --- a/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.h +++ b/browser_patches/firefox/juggler/pipe/nsRemoteDebuggingPipe.h @@ -22,6 +22,7 @@ class nsRemoteDebuggingPipe final : public nsIRemoteDebuggingPipe { private: void ReaderLoop(); void ReceiveMessage(const nsCString& aMessage); + void Disconnected(); ~nsRemoteDebuggingPipe(); RefPtr mClient;