commit 1182bee9789a632f374f0a6d3ed90f21af1e37c5 Author: Kathy Brade brade@pearlcrescent.com Date: Tue Apr 25 11:52:26 2017 -0400
fixup! Bug 6253: Add canvas image extraction prompt.
Bug 21778: Canvas prompt not showing in Tor Browser based in ESR52
When running in multiprocess mode, use IPC to relay the canvas-permissions-prompt observer notification to the chrome (parent) process. --- browser/base/content/browser.js | 23 +++++++++++++++++++---- dom/canvas/CanvasUtils.cpp | 17 ++++++++++++++--- dom/ipc/PBrowser.ipdl | 8 ++++++++ dom/ipc/TabParent.cpp | 12 ++++++++++++ dom/ipc/TabParent.h | 1 + 5 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 686805fb..83aca07 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6302,20 +6302,35 @@ var CanvasPermissionPromptHelper = { Services.obs.removeObserver(this, this._permissionsPrompt, false); },
- // aSubject is an nsIDOMWindow. + // aSubject is an nsIBrowser (e10s) or an nsIDOMWindow (non-e10s). // aData is an URL string. observe: function CanvasPermissionPromptHelper_observe(aSubject, aTopic, aData) { if (aTopic != this._permissionsPrompt) { - throw new Error("Unexpected topic"); + throw new Error("Unexpected topic"); } + + let browser; + try { + browser = aSubject.QueryInterface(Ci.nsIBrowser); + } catch (e) {} + + if (!browser) { + try { + let contentWindow = aSubject.QueryInterface(Ci.nsIDOMWindow); + browser = gBrowser.getBrowserForContentWindow(contentWindow); + } catch (e) {} + + if (!browser) { + throw new Error("No browser"); + } + } + if (!aData) { throw new Error("Missing URL"); }
var uri = makeURI(aData); - var contentWindow = aSubject.QueryInterface(Ci.nsIDOMWindow); - var browser = gBrowser.getBrowserForContentWindow(contentWindow); if (gBrowser.selectedBrowser !== browser) { // Must belong to some other window. return; diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp index bd5c44d..dceccfd 100644 --- a/dom/canvas/CanvasUtils.cpp +++ b/dom/canvas/CanvasUtils.cpp @@ -15,6 +15,7 @@ #include "nsICanvasRenderingContextInternal.h" #include "nsIHTMLCollection.h" #include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/dom/TabChild.h" #include "nsIPrincipal.h"
#include "nsGfxCIID.h" @@ -144,9 +145,19 @@ bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx) nsContentUtils::LogMessageToConsole(message.get());
// Prompt the user (asynchronous). - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT, - NS_ConvertUTF8toUTF16(topLevelDocURISpec).get()); + if (XRE_IsContentProcess()) { + TabChild* tabChild = TabChild::GetFrom(win); + if (tabChild) { + tabChild->SendShowCanvasPermissionPrompt(topLevelDocURISpec); + } + } else { + nsCOMPtr<nsIObserverService> obs = + mozilla::services::GetObserverService(); + if (obs) { + obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT, + NS_ConvertUTF8toUTF16(topLevelDocURISpec).get()); + } + }
// We don't extract the image for now -- user may override at prompt. return false; diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 249657c..cc4c4dc 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -619,6 +619,14 @@ parent: */ async RequestCrossBrowserNavigation(uint32_t aGlobalIndex);
+ /** + * This function is used to notify the parent that it should display a + * canvas permission prompt. + * + * @param aFirstPartyURI first party of the tab that is requesting access. + */ + async ShowCanvasPermissionPrompt(nsCString aFirstPartyURI); + child: /** * Notify the remote browser that it has been Show()n on this diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 0df4c12..ff1b41a 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -3277,6 +3277,18 @@ TabParent::RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) return NS_SUCCEEDED(frameLoader->RequestGroupedHistoryNavigation(aGlobalIndex)); }
+bool +TabParent::RecvShowCanvasPermissionPrompt(const nsCString& firstPartyURI) +{ + nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement); + NS_ENSURE_TRUE(browser, false); + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + NS_ENSURE_TRUE(os, false); + nsresult rv = os->NotifyObservers(browser, "canvas-permissions-prompt", + NS_ConvertUTF8toUTF16(firstPartyURI).get()); + return NS_SUCCEEDED(rv); +} + NS_IMETHODIMP FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 43afb05..b8022e1 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -633,6 +633,7 @@ protected: virtual bool RecvNotifySessionHistoryChange(const uint32_t& aCount) override;
virtual bool RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) override; + virtual bool RecvShowCanvasPermissionPrompt(const nsCString& firstPartyURI) override;
ContentCacheInParent mContentCache;