Backed out changeset 71790f0ea832 (bug 967895)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Mon, 09 Oct 2017 19:18:12 +0200
changeset 435888 6fd0004b779171a3aa980c039e045fff8a9e6f8c
parent 435887 ffcb85a1cbe9e614fa4bc24b89183b22bbc735ad
child 435889 d4307f283714cd6e69d2719151f1478545388e77
push id8114
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 16:33:21 +0000
treeherdermozilla-beta@73e0d89a540f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs967895
milestone58.0a1
backs out71790f0ea83211fe47b0f0256dde4261319811e2
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 71790f0ea832 (bug 967895)
dom/bindings/Bindings.conf
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasRenderingContext2D.h
dom/canvas/CanvasRenderingContextHelper.cpp
dom/canvas/CanvasRenderingContextHelper.h
dom/canvas/CanvasUtils.cpp
dom/canvas/CanvasUtils.h
dom/canvas/OffscreenCanvas.cpp
dom/html/HTMLCanvasElement.cpp
dom/html/HTMLCanvasElement.h
dom/ipc/PBrowser.ipdl
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/media/imagecapture/CaptureTask.cpp
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -119,17 +119,17 @@ DOMInterfaces = {
 
 'CacheStorage': {
     'implicitJSContext': [ 'match' ],
     'nativeType': 'mozilla::dom::cache::CacheStorage',
 },
 
 'CanvasRenderingContext2D': {
     'implicitJSContext': [
-        'createImageData', 'getImageData', 'isPointInPath', 'isPointInStroke'
+        'createImageData', 'getImageData'
     ],
     'binaryNames': {
         'mozImageSmoothingEnabled': 'imageSmoothingEnabled'
     }
 },
 
 'CaretPosition' : {
     'nativeType': 'nsDOMCaretPosition',
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -4902,71 +4902,57 @@ CanvasRenderingContext2D::SetLineDashOff
 }
 
 double
 CanvasRenderingContext2D::LineDashOffset() const {
   return CurrentState().dashOffset;
 }
 
 bool
-CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, double aX, double aY, const CanvasWindingRule& aWinding)
+CanvasRenderingContext2D::IsPointInPath(double aX, double aY, const CanvasWindingRule& aWinding)
 {
   if (!FloatValidate(aX, aY)) {
     return false;
   }
 
-  // Check for site-specific permission and return false if no permission.
-  if (mCanvasElement) {
-    nsCOMPtr<nsIDocument> ownerDoc = mCanvasElement->OwnerDoc();
-    if (!ownerDoc || !CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx))
-      return false;
-  }
-
   EnsureUserSpacePath(aWinding);
   if (!mPath) {
     return false;
   }
 
   if (mPathTransformWillUpdate) {
     return mPath->ContainsPoint(Point(aX, aY), mPathToDS);
   }
 
   return mPath->ContainsPoint(Point(aX, aY), mTarget->GetTransform());
 }
 
-bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX, double aY, const CanvasWindingRule& aWinding)
+bool CanvasRenderingContext2D::IsPointInPath(const CanvasPath& aPath, double aX, double aY, const CanvasWindingRule& aWinding)
 {
   if (!FloatValidate(aX, aY)) {
     return false;
   }
 
   EnsureTarget();
   if (!IsTargetValid()) {
     return false;
   }
 
   RefPtr<gfx::Path> tempPath = aPath.GetPath(aWinding, mTarget);
 
   return tempPath->ContainsPoint(Point(aX, aY), mTarget->GetTransform());
 }
 
 bool
-CanvasRenderingContext2D::IsPointInStroke(JSContext* aCx, double aX, double aY)
+CanvasRenderingContext2D::IsPointInStroke(double aX, double aY)
 {
   if (!FloatValidate(aX, aY)) {
     return false;
   }
 
-  // Check for site-specific permission and return false if no permission.
-  if (mCanvasElement) {
-    nsCOMPtr<nsIDocument> ownerDoc = mCanvasElement->OwnerDoc();
-    if (!ownerDoc || !CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx))
-      return false;
-  }
-
   EnsureUserSpacePath();
   if (!mPath) {
     return false;
   }
 
   const ContextState &state = CurrentState();
 
   StrokeOptions strokeOptions(state.lineWidth,
@@ -4978,17 +4964,17 @@ CanvasRenderingContext2D::IsPointInStrok
                               state.dashOffset);
 
   if (mPathTransformWillUpdate) {
     return mPath->StrokeContainsPoint(strokeOptions, Point(aX, aY), mPathToDS);
   }
   return mPath->StrokeContainsPoint(strokeOptions, Point(aX, aY), mTarget->GetTransform());
 }
 
-bool CanvasRenderingContext2D::IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX, double aY)
+bool CanvasRenderingContext2D::IsPointInStroke(const CanvasPath& aPath, double aX, double aY)
 {
   if (!FloatValidate(aX, aY)) {
     return false;
   }
 
   EnsureTarget();
   if (!IsTargetValid()) {
     return false;
@@ -5827,37 +5813,16 @@ CanvasRenderingContext2D::GetImageDataAr
   {
     JS::AutoCheckCannotGC nogc;
     bool isShared;
     uint8_t* data = JS_GetUint8ClampedArrayData(darray, &isShared, nogc);
     MOZ_ASSERT(!isShared);        // Should not happen, data was created above
 
     uint32_t srcStride = rawData.mStride;
     uint8_t* src = rawData.mData + srcReadRect.y * srcStride + srcReadRect.x * 4;
-
-    // Check for site-specific permission and return all-white, opaque pixel
-    // data if no permission.  This check is not needed if the canvas was
-    // created with a docshell (that is only done for special internal uses).
-    bool usePlaceholder = false;
-    if (mCanvasElement) {
-      nsCOMPtr<nsIDocument> ownerDoc = mCanvasElement->OwnerDoc();
-      usePlaceholder = !ownerDoc ||
-        !CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx);
-    }
-
-    if (usePlaceholder) {
-      if (readback) {
-        readback->Unmap();
-      }
-
-      memset(data, 0xFF, len.value());
-      *aRetval = darray;
-      return NS_OK;
-    }
-
     uint8_t* dst = data + dstWriteRect.y * (aWidth * 4) + dstWriteRect.x * 4;
 
     if (mOpaque) {
       SwizzleData(src, srcStride, SurfaceFormat::X8R8G8B8_UINT32,
                   dst, aWidth * 4, SurfaceFormat::R8G8B8A8,
                   dstWriteRect.Size());
     } else {
       UnpremultiplyData(src, srcStride, SurfaceFormat::A8R8G8B8_UINT32,
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -199,20 +199,20 @@ public:
   void Fill(const CanvasWindingRule& aWinding);
   void Fill(const CanvasPath& aPath, const CanvasWindingRule& aWinding);
   void Stroke();
   void Stroke(const CanvasPath& aPath);
   void DrawFocusIfNeeded(mozilla::dom::Element& aElement, ErrorResult& aRv);
   bool DrawCustomFocusRing(mozilla::dom::Element& aElement);
   void Clip(const CanvasWindingRule& aWinding);
   void Clip(const CanvasPath& aPath, const CanvasWindingRule& aWinding);
-  bool IsPointInPath(JSContext* aCx, double aX, double aY, const CanvasWindingRule& aWinding);
-  bool IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX, double aY, const CanvasWindingRule& aWinding);
-  bool IsPointInStroke(JSContext* aCx, double aX, double aY);
-  bool IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX, double aY);
+  bool IsPointInPath(double aX, double aY, const CanvasWindingRule& aWinding);
+  bool IsPointInPath(const CanvasPath& aPath, double aX, double aY, const CanvasWindingRule& aWinding);
+  bool IsPointInStroke(double aX, double aY);
+  bool IsPointInStroke(const CanvasPath& aPath, double aX, double aY);
   void FillText(const nsAString& aText, double aX, double aY,
                 const Optional<double>& aMaxWidth,
                 mozilla::ErrorResult& aError);
   void StrokeText(const nsAString& aText, double aX, double aY,
                   const Optional<double>& aMaxWidth,
                   mozilla::ErrorResult& aError);
   TextMetrics*
     MeasureText(const nsAString& aRawText, mozilla::ErrorResult& aError);
--- a/dom/canvas/CanvasRenderingContextHelper.cpp
+++ b/dom/canvas/CanvasRenderingContextHelper.cpp
@@ -20,17 +20,16 @@ namespace mozilla {
 namespace dom {
 
 void
 CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
                                      nsIGlobalObject* aGlobal,
                                      BlobCallback& aCallback,
                                      const nsAString& aType,
                                      JS::Handle<JS::Value> aParams,
-                                     bool aUsePlaceholder,
                                      ErrorResult& aRv)
 {
   // Encoder callback when encoding is complete.
   class EncodeCallback : public EncodeCompleteCallback
   {
   public:
     EncodeCallback(nsIGlobalObject* aGlobal, BlobCallback* aCallback)
       : mGlobal(aGlobal)
@@ -54,26 +53,25 @@ CanvasRenderingContextHelper::ToBlob(JSC
 
     nsCOMPtr<nsIGlobalObject> mGlobal;
     RefPtr<BlobCallback> mBlobCallback;
   };
 
   RefPtr<EncodeCompleteCallback> callback =
     new EncodeCallback(aGlobal, &aCallback);
 
-  ToBlob(aCx, aGlobal, callback, aType, aParams, aUsePlaceholder, aRv);
+  ToBlob(aCx, aGlobal, callback, aType, aParams, aRv);
 }
 
 void
 CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
                                      nsIGlobalObject* aGlobal,
                                      EncodeCompleteCallback* aCallback,
                                      const nsAString& aType,
                                      JS::Handle<JS::Value> aParams,
-                                     bool aUsePlaceholder,
                                      ErrorResult& aRv)
 {
   nsAutoString type;
   nsContentUtils::ASCIIToLower(aType, type);
 
   nsAutoString params;
   bool usingCustomParseOptions;
   aRv = ParseParams(aCx, type, aParams, params, &usingCustomParseOptions);
@@ -104,17 +102,16 @@ CanvasRenderingContextHelper::ToBlob(JSC
   RefPtr<EncodeCompleteCallback> callback = aCallback;
 
   aRv = ImageEncoder::ExtractDataAsync(type,
                                        params,
                                        usingCustomParseOptions,
                                        Move(imageBuffer),
                                        format,
                                        GetWidthHeight(),
-                                       aUsePlaceholder,
                                        callback);
 }
 
 already_AddRefed<nsICanvasRenderingContextInternal>
 CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType)
 {
   return CreateContextHelper(aContextType, layers::LayersBackend::LAYERS_NONE);
 }
--- a/dom/canvas/CanvasRenderingContextHelper.h
+++ b/dom/canvas/CanvasRenderingContextHelper.h
@@ -53,21 +53,21 @@ protected:
   virtual nsresult ParseParams(JSContext* aCx,
                                const nsAString& aType,
                                const JS::Value& aEncoderOptions,
                                nsAString& outParams,
                                bool* const outCustomParseOptions);
 
   void ToBlob(JSContext* aCx, nsIGlobalObject* global, BlobCallback& aCallback,
               const nsAString& aType, JS::Handle<JS::Value> aParams,
-              bool aUsePlaceholder, ErrorResult& aRv);
+              ErrorResult& aRv);
 
   void ToBlob(JSContext* aCx, nsIGlobalObject* aGlobal, EncodeCompleteCallback* aCallback,
               const nsAString& aType, JS::Handle<JS::Value> aParams,
-              bool aUsePlaceholder, ErrorResult& aRv);
+              ErrorResult& aRv);
 
   virtual already_AddRefed<nsICanvasRenderingContextInternal>
   CreateContext(CanvasContextType aContextType);
 
   already_AddRefed<nsICanvasRenderingContextInternal>
   CreateContextHelper(CanvasContextType aContextType,
                       layers::LayersBackend aCompositorBackend);
 
--- a/dom/canvas/CanvasUtils.cpp
+++ b/dom/canvas/CanvasUtils.cpp
@@ -8,171 +8,31 @@
 
 #include "nsIServiceManager.h"
 
 #include "nsIConsoleService.h"
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "nsIHTMLCollection.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
-#include "mozilla/dom/TabChild.h"
 #include "nsIPrincipal.h"
 
 #include "nsGfxCIID.h"
 
 #include "nsTArray.h"
 
 #include "CanvasUtils.h"
 #include "mozilla/gfx/Matrix.h"
 #include "WebGL2Context.h"
 
-#include "nsIScriptObjectPrincipal.h"
-#include "nsIPermissionManager.h"
-#include "nsIObserverService.h"
-#include "mozilla/Services.h"
-#include "mozIThirdPartyUtil.h"
-#include "nsContentUtils.h"
-#include "nsUnicharUtils.h"
-#include "nsPrintfCString.h"
-#include "nsIConsoleService.h"
-#include "jsapi.h"
-
-#define TOPIC_CANVAS_PERMISSIONS_PROMPT "canvas-permissions-prompt"
-#define PERMISSION_CANVAS_EXTRACT_DATA "canvas/extractData"
-
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace CanvasUtils {
 
-bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx)
-{
-    // Do the rest of the checks only if privacy.resistFingerprinting is on.
-    if (!nsContentUtils::ShouldResistFingerprinting()) {
-        return true;
-    }
-
-    // Don't proceed if we don't have a document or JavaScript context.
-    if (!aDocument || !aCx) {
-        return false;
-    }
-
-    // Documents with system principal can always extract canvas data.
-    nsPIDOMWindowOuter *win = aDocument->GetWindow();
-    nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
-    if (sop && nsContentUtils::IsSystemPrincipal(sop->GetPrincipal())) {
-        return true;
-    }
-
-    // Always give permission to chrome scripts (e.g. Page Inspector).
-    if (nsContentUtils::ThreadsafeIsCallerChrome()) {
-        return true;
-    }
-
-    // Get the document URI and its spec.
-    nsIURI *docURI = aDocument->GetDocumentURI();
-    nsCString docURISpec;
-    docURI->GetSpec(docURISpec);
-
-    // Allow local files to extract canvas data.
-    bool isFileURL;
-    (void) docURI->SchemeIs("file", &isFileURL);
-    if (isFileURL) {
-        return true;
-    }
-
-    // Get calling script file and line for logging.
-    JS::AutoFilename scriptFile;
-    unsigned scriptLine = 0;
-    bool isScriptKnown = false;
-    if (JS::DescribeScriptedCaller(aCx, &scriptFile, &scriptLine)) {
-        isScriptKnown = true;
-        // Don't show canvas prompt for PDF.js
-        if (scriptFile.get() &&
-                strcmp(scriptFile.get(), "resource://pdf.js/build/pdf.js") == 0) {
-            return true;
-        }
-    }
-
-    nsIDocument* topLevelDocument = aDocument->GetTopLevelContentDocument();
-    nsIURI *topLevelDocURI = topLevelDocument ? topLevelDocument->GetDocumentURI() : nullptr;
-    nsCString topLevelDocURISpec;
-    if (topLevelDocURI) {
-        topLevelDocURI->GetSpec(topLevelDocURISpec);
-    }
-
-    // Load Third Party Util service.
-    nsresult rv;
-    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-        do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, false);
-
-    // Block all third-party attempts to extract canvas.
-    bool isThirdParty = true;
-    rv = thirdPartyUtil->IsThirdPartyURI(topLevelDocURI, docURI, &isThirdParty);
-    NS_ENSURE_SUCCESS(rv, false);
-    if (isThirdParty) {
-        nsAutoCString message;
-        message.AppendPrintf("Blocked third party %s in page %s from extracting canvas data.",
-                             docURISpec.get(), topLevelDocURISpec.get());
-        if (isScriptKnown) {
-            message.AppendPrintf(" %s:%u.", scriptFile.get(), scriptLine);
-        }
-        nsContentUtils::LogMessageToConsole(message.get());
-        return false;
-    }
-
-    // Load Permission Manager service.
-    nsCOMPtr<nsIPermissionManager> permissionManager =
-        do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, false);
-
-    // Check if the site has permission to extract canvas data.
-    // Either permit or block extraction if a stored permission setting exists.
-    uint32_t permission;
-    rv = permissionManager->TestPermission(topLevelDocURI,
-                                           PERMISSION_CANVAS_EXTRACT_DATA,
-                                           &permission);
-    NS_ENSURE_SUCCESS(rv, false);
-    switch (permission) {
-    case nsIPermissionManager::ALLOW_ACTION:
-        return true;
-    case nsIPermissionManager::DENY_ACTION:
-        return false;
-    default:
-        break;
-    }
-
-    // At this point, permission is unknown (nsIPermissionManager::UNKNOWN_ACTION).
-    nsAutoCString message;
-    message.AppendPrintf("Blocked %s in page %s from extracting canvas data.",
-                         docURISpec.get(), topLevelDocURISpec.get());
-    if (isScriptKnown) {
-        message.AppendPrintf(" %s:%u.", scriptFile.get(), scriptLine);
-    }
-    nsContentUtils::LogMessageToConsole(message.get());
-
-    // Prompt the user (asynchronous).
-    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;
-}
-
 bool
 GetCanvasContextType(const nsAString& str, dom::CanvasContextType* const out_type)
 {
   if (str.EqualsLiteral("2d")) {
     *out_type = dom::CanvasContextType::Canvas2D;
     return true;
   }
 
--- a/dom/canvas/CanvasUtils.h
+++ b/dom/canvas/CanvasUtils.h
@@ -44,19 +44,16 @@ inline bool CheckSaneSubrectSize(int32_t
 void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
                               nsIPrincipal *aPrincipal,
                               bool forceWriteOnly,
                               bool CORSUsed);
 
 // Check if the context is chrome or has the permission to drawWindow
 bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj);
 
-// Check site-specific permission and display prompt if appropriate.
-bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx);
-
 // Make a double out of |v|, treating undefined values as 0.0 (for
 // the sake of sparse arrays).  Return true iff coercion
 // succeeded.
 bool CoerceDouble(const JS::Value& v, double* d);
 
     /* Float validation stuff */
 #define VALIDATE(_f)  if (!IsFinite(_f)) return false
 
--- a/dom/canvas/OffscreenCanvas.cpp
+++ b/dom/canvas/OffscreenCanvas.cpp
@@ -279,23 +279,18 @@ OffscreenCanvas::ToBlob(JSContext* aCx,
 
     nsCOMPtr<nsIGlobalObject> mGlobal;
     RefPtr<Promise> mPromise;
   };
 
   RefPtr<EncodeCompleteCallback> callback =
     new EncodeCallback(global, promise);
 
-  // TODO: Can we obtain the context and document here somehow
-  // so that we can decide when usePlaceholder should be true/false?
-  // See https://trac.torproject.org/18599
-  // For now, we always return a placeholder if fingerprinting resistance is on.
-  bool usePlaceholder = nsContentUtils::ShouldResistFingerprinting();
-  CanvasRenderingContextHelper::ToBlob(aCx, global, callback, aType, aParams,
-                                       usePlaceholder, aRv);
+  CanvasRenderingContextHelper::ToBlob(aCx, global,
+                                       callback, aType, aParams, aRv);
 
   return promise.forget();
 }
 
 already_AddRefed<gfx::SourceSurface>
 OffscreenCanvas::GetSurfaceSnapshot(gfxAlphaType* const aOutAlphaType)
 {
   if (!mCurrentContext) {
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -39,17 +39,16 @@
 #include "nsIXPConnect.h"
 #include "nsJSUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsMathUtils.h"
 #include "nsNetUtil.h"
 #include "nsRefreshDriver.h"
 #include "nsStreamUtils.h"
 #include "ActiveLayerTracker.h"
-#include "CanvasUtils.h"
 #include "VRManagerChild.h"
 #include "WebGL1Context.h"
 #include "WebGL2Context.h"
 
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Canvas)
@@ -58,29 +57,26 @@ namespace mozilla {
 namespace dom {
 
 class RequestedFrameRefreshObserver : public nsARefreshObserver
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestedFrameRefreshObserver, override)
 
 public:
   RequestedFrameRefreshObserver(HTMLCanvasElement* const aOwningElement,
-                                nsRefreshDriver* aRefreshDriver,
-                                bool aReturnPlaceholderData)
+                                nsRefreshDriver* aRefreshDriver)
     : mRegistered(false),
-      mReturnPlaceholderData(aReturnPlaceholderData),
       mOwningElement(aOwningElement),
       mRefreshDriver(aRefreshDriver)
   {
     MOZ_ASSERT(mOwningElement);
   }
 
   static already_AddRefed<DataSourceSurface>
-  CopySurface(const RefPtr<SourceSurface>& aSurface,
-              bool aReturnPlaceholderData)
+  CopySurface(const RefPtr<SourceSurface>& aSurface)
   {
     RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
     if (!data) {
       return nullptr;
     }
 
     DataSourceSurface::ScopedMap read(data, DataSourceSurface::READ);
     if (!read.IsMapped()) {
@@ -99,33 +95,22 @@ public:
     if (!write.IsMapped()) {
       return nullptr;
     }
 
     MOZ_ASSERT(read.GetStride() == write.GetStride());
     MOZ_ASSERT(data->GetSize() == copy->GetSize());
     MOZ_ASSERT(data->GetFormat() == copy->GetFormat());
 
-    if (aReturnPlaceholderData) {
-      // If returning placeholder data, fill the frame copy with white pixels.
-      memset(write.GetData(), 0xFF,
-             write.GetStride() * copy->GetSize().height);
-    } else {
-      memcpy(write.GetData(), read.GetData(),
-             write.GetStride() * copy->GetSize().height);
-    }
+    memcpy(write.GetData(), read.GetData(),
+           write.GetStride() * copy->GetSize().height);
 
     return copy.forget();
   }
 
-  void SetReturnPlaceholderData(bool aReturnPlaceholderData)
-  {
-    mReturnPlaceholderData = aReturnPlaceholderData;
-  }
-
   void WillRefresh(TimeStamp aTime) override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     AUTO_PROFILER_LABEL("RequestedFrameRefreshObserver::WillRefresh", OTHER);
 
     if (!mOwningElement) {
       return;
@@ -154,17 +139,17 @@ public:
         return;
       }
     }
 
     RefPtr<DataSourceSurface> copy;
     {
       AUTO_PROFILER_LABEL(
         "RequestedFrameRefreshObserver::WillRefresh:CopySurface", OTHER);
-      copy = CopySurface(snapshot, mReturnPlaceholderData);
+      copy = CopySurface(snapshot);
       if (!copy) {
         return;
       }
     }
 
     {
       AUTO_PROFILER_LABEL(
         "RequestedFrameRefreshObserver::WillRefresh:SetFrame", OTHER);
@@ -211,17 +196,16 @@ public:
 private:
   virtual ~RequestedFrameRefreshObserver()
   {
     MOZ_ASSERT(!mRefreshDriver);
     MOZ_ASSERT(!mRegistered);
   }
 
   bool mRegistered;
-  bool mReturnPlaceholderData;
   HTMLCanvasElement* const mOwningElement;
   RefPtr<nsRefreshDriver> mRefreshDriver;
 };
 
 // ---------------------------------------------------------------------------
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLCanvasPrintState, mCanvas,
                                       mContext, mCallback)
@@ -763,45 +747,33 @@ HTMLCanvasElement::CaptureStream(const O
     return nullptr;
   }
 
   RefPtr<MediaStreamTrack> track =
   stream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO,
                          new CanvasCaptureTrackSource(principal, stream));
   stream->AddTrackInternal(track);
 
-  // Check site-specific permission and display prompt if appropriate.
-  // If no permission, arrange for the frame capture listener to return
-  // all-white, opaque image data.
-  bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(
-    OwnerDoc(),
-    nsContentUtils::GetCurrentJSContext());
-
-  rv = RegisterFrameCaptureListener(stream->FrameCaptureListener(), usePlaceholder);
+  rv = RegisterFrameCaptureListener(stream->FrameCaptureListener());
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return stream.forget();
 }
 
 nsresult
-HTMLCanvasElement::ExtractData(JSContext* aCx,
-                               nsAString& aType,
+HTMLCanvasElement::ExtractData(nsAString& aType,
                                const nsAString& aOptions,
                                nsIInputStream** aStream)
 {
-  // Check site-specific permission and display prompt if appropriate.
-  // If no permission, return all-white, opaque image data.
-  bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc(), aCx);
   return ImageEncoder::ExtractData(aType,
                                    aOptions,
                                    GetSize(),
-                                   usePlaceholder,
                                    mCurrentContext,
                                    mAsyncCanvasRenderer,
                                    aStream);
 }
 
 nsresult
 HTMLCanvasElement::ToDataURLImpl(JSContext* aCx,
                                  const nsAString& aMimeType,
@@ -821,22 +793,22 @@ HTMLCanvasElement::ToDataURLImpl(JSConte
   bool usingCustomParseOptions;
   nsresult rv =
     ParseParams(aCx, type, aEncoderOptions, params, &usingCustomParseOptions);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIInputStream> stream;
-  rv = ExtractData(aCx, type, params, getter_AddRefs(stream));
+  rv = ExtractData(type, params, getter_AddRefs(stream));
 
   // If there are unrecognized custom parse options, we should fall back to
   // the default values for the encoder without any options at all.
   if (rv == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
-    rv = ExtractData(aCx, type, EmptyString(), getter_AddRefs(stream));
+    rv = ExtractData(type, EmptyString(), getter_AddRefs(stream));
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // build data URL string
   aDataURL = NS_LITERAL_STRING("data:") + type + NS_LITERAL_STRING(";base64,");
 
   uint64_t count;
@@ -876,21 +848,18 @@ HTMLCanvasElement::ToBlob(JSContext* aCx
         &aCallback,
         static_cast<void (BlobCallback::*)(Blob*, const char*)>(
           &BlobCallback::Call),
         nullptr,
         nullptr));
     return;
   }
 
-  // Check site-specific permission and display prompt if appropriate.
-  // If no permission, return all-white, opaque image data.
-  bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc(), aCx);
   CanvasRenderingContextHelper::ToBlob(aCx, global, aCallback, aType,
-                                       aParams, usePlaceholder, aRv);
+                                       aParams, aRv);
 
 }
 
 OffscreenCanvas*
 HTMLCanvasElement::TransferControlToOffscreen(ErrorResult& aRv)
 {
   if (mCurrentContext) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@@ -949,18 +918,17 @@ HTMLCanvasElement::MozGetAsFile(const ns
 
 nsresult
 HTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
                                     const nsAString& aType,
                                     File** aResult)
 {
   nsCOMPtr<nsIInputStream> stream;
   nsAutoString type(aType);
-  nsresult rv = ExtractData(nsContentUtils::GetCurrentJSContext(),
-                            type, EmptyString(), getter_AddRefs(stream));
+  nsresult rv = ExtractData(type, EmptyString(), getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint64_t imgSize;
   rv = stream->Available(&imgSize);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(imgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
   void* imgData = nullptr;
@@ -1271,18 +1239,17 @@ HTMLCanvasElement::MarkContextCleanForFr
 
 bool
 HTMLCanvasElement::IsContextCleanForFrameCapture()
 {
   return mCurrentContext && mCurrentContext->IsContextCleanForFrameCapture();
 }
 
 nsresult
-HTMLCanvasElement::RegisterFrameCaptureListener(FrameCaptureListener* aListener,
-                                                bool aReturnPlaceholderData)
+HTMLCanvasElement::RegisterFrameCaptureListener(FrameCaptureListener* aListener)
 {
   WeakPtr<FrameCaptureListener> listener = aListener;
 
   if (mRequestedFrameListeners.Contains(listener)) {
     return NS_OK;
   }
 
   if (!mRequestedFrameRefreshObserver) {
@@ -1311,19 +1278,17 @@ HTMLCanvasElement::RegisterFrameCaptureL
     }
 
     nsRefreshDriver* driver = context->RefreshDriver();
     if (!driver) {
       return NS_ERROR_FAILURE;
     }
 
     mRequestedFrameRefreshObserver =
-      new RequestedFrameRefreshObserver(this, driver, aReturnPlaceholderData);
-  } else {
-    mRequestedFrameRefreshObserver->SetReturnPlaceholderData(aReturnPlaceholderData);
+      new RequestedFrameRefreshObserver(this, driver);
   }
 
   mRequestedFrameListeners.AppendElement(listener);
   mRequestedFrameRefreshObserver->Register();
   return NS_OK;
 }
 
 bool
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -257,18 +257,17 @@ public:
   /*
    * Register a FrameCaptureListener with this canvas.
    * The canvas hooks into the RefreshDriver while there are
    * FrameCaptureListeners registered.
    * The registered FrameCaptureListeners are stored as WeakPtrs, thus it's the
    * caller's responsibility to keep them alive. Once a registered
    * FrameCaptureListener is destroyed it will be automatically deregistered.
    */
-  nsresult RegisterFrameCaptureListener(FrameCaptureListener* aListener,
-                                        bool aReturnPlaceholderData);
+  nsresult RegisterFrameCaptureListener(FrameCaptureListener* aListener);
 
   /*
    * Returns true when there is at least one registered FrameCaptureListener
    * that has requested a frame capture.
    */
   bool IsFrameCaptureRequested() const;
 
   /*
@@ -344,18 +343,17 @@ protected:
 
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   virtual nsIntSize GetWidthHeight() override;
 
   virtual already_AddRefed<nsICanvasRenderingContextInternal>
   CreateContext(CanvasContextType aContextType) override;
 
-  nsresult ExtractData(JSContext* aCx,
-                       nsAString& aType,
+  nsresult ExtractData(nsAString& aType,
                        const nsAString& aOptions,
                        nsIInputStream** aStream);
   nsresult ToDataURLImpl(JSContext* aCx,
                          const nsAString& aMimeType,
                          const JS::Value& aEncoderOptions,
                          nsAString& aDataURL);
   nsresult MozGetAsFileImpl(const nsAString& aName,
                             const nsAString& aType,
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -589,24 +589,16 @@ parent:
      * When the session history is across multiple root docshells, this function
      * is used to notify parent that it needs to navigate to an entry out of
      * local index of the child.
      *
      * @param aGlobalIndex The global index of history entry to navigate to.
      */
     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
      * side, with the given |visibleRect|.  This message is expected
      * to trigger creation of the remote browser's "widget".
      *
      * |Show()| and |Move()| take IntSizes rather than Rects because
      * content processes always render to a virtual <0, 0> top-left
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3599,37 +3599,16 @@ TabParent::RecvRequestCrossBrowserNaviga
   nsCOMPtr<nsISupports> promise;
   if (NS_FAILED(frameLoader->RequestGroupedHistoryNavigation(aGlobalIndex,
                                                              getter_AddRefs(promise)))) {
     return IPC_FAIL_NO_REASON(this);
   }
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-TabParent::RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI)
-{
-  nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
-  if (!browser) {
-    // If the tab is being closed, the browser may not be available.
-    // In this case we can ignore the request.
-    return IPC_OK();
-  }
-  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-  if (!os) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-  nsresult rv = os->NotifyObservers(browser, "canvas-permissions-prompt",
-                                    NS_ConvertUTF8toUTF16(aFirstPartyURI).get());
-  if (NS_FAILED(rv)) {
-    return IPC_FAIL_NO_REASON(this);
-  }
-  return IPC_OK();
-}
-
 void
 TabParent::LiveResizeStarted()
 {
   SuppressDisplayport(true);
 }
 
 void
 TabParent::LiveResizeStopped()
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -641,17 +641,16 @@ protected:
 
   virtual mozilla::ipc::IPCResult RecvGetTabCount(uint32_t* aValue) override;
 
   virtual mozilla::ipc::IPCResult RecvSHistoryUpdate(const uint32_t& aCount,
                                                      const uint32_t& aLocalIndex,
                                                      const bool& aTruncate) override;
 
   virtual mozilla::ipc::IPCResult RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) override;
-  virtual mozilla::ipc::IPCResult RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI) override;
 
   ContentCacheInParent mContentCache;
 
   nsIntRect mRect;
   ScreenIntSize mDimensions;
   ScreenOrientationInternal mOrientation;
   float mDPI;
   int32_t mRounding;
--- a/dom/media/imagecapture/CaptureTask.cpp
+++ b/dom/media/imagecapture/CaptureTask.cpp
@@ -152,17 +152,16 @@ CaptureTask::SetCurrentFrames(const Vide
       nsresult rv;
       nsAutoString type(NS_LITERAL_STRING("image/jpeg"));
       nsAutoString options;
       rv = dom::ImageEncoder::ExtractDataFromLayersImageAsync(
                                 type,
                                 options,
                                 false,
                                 image,
-                                false,
                                 new EncodeComplete(this));
       if (NS_FAILED(rv)) {
         PostTrackEndEvent();
       }
       return;
     }
   }
 }