commit 916c78a0a56a38763077634cd492cfdcb2e37b81
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Mon Mar 28 17:04:07 2016 -0400
fixup! Bug #6253: Add canvas image extraction prompt.
Place Canvas MediaStream behind site permission prompt (#15640).
---
dom/html/HTMLCanvasElement.cpp | 46 ++++++++++++++++++++++++++++++++----------
dom/html/HTMLCanvasElement.h | 5 ++++-
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 314bf48..dd74d9f 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -59,8 +59,10 @@ class RequestedFrameRefreshObserver : public nsARefreshObserver
public:
RequestedFrameRefreshObserver(HTMLCanvasElement* const aOwningElement,
- nsRefreshDriver* aRefreshDriver)
+ nsRefreshDriver* aRefreshDriver,
+ bool aReturnPlaceholderData)
: mRegistered(false),
+ mReturnPlaceholderData(aReturnPlaceholderData),
mOwningElement(aOwningElement),
mRefreshDriver(aRefreshDriver)
{
@@ -68,7 +70,8 @@ public:
}
static already_AddRefed<DataSourceSurface>
- CopySurface(const RefPtr<SourceSurface>& aSurface)
+ CopySurface(const RefPtr<SourceSurface>& aSurface,
+ bool aReturnPlaceholderData)
{
RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
if (!data) {
@@ -97,12 +100,23 @@ public:
MOZ_ASSERT(data->GetSize() == copy->GetSize());
MOZ_ASSERT(data->GetFormat() == copy->GetFormat());
- memcpy(write.GetData(), read.GetData(),
- write.GetStride() * copy->GetSize().height);
+ 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);
+ }
return copy.forget();
}
+ void SetReturnPlaceholderData(bool aReturnPlaceholderData)
+ {
+ mReturnPlaceholderData = aReturnPlaceholderData;
+ }
+
void WillRefresh(TimeStamp aTime) override
{
MOZ_ASSERT(NS_IsMainThread());
@@ -128,8 +142,8 @@ public:
return;
}
- RefPtr<DataSourceSurface> copy = CopySurface(snapshot);
-
+ RefPtr<DataSourceSurface> copy = CopySurface(snapshot,
+ mReturnPlaceholderData);
mOwningElement->SetFrameCapture(copy.forget());
mOwningElement->MarkContextCleanForFrameCapture();
}
@@ -177,6 +191,7 @@ private:
}
bool mRegistered;
+ bool mReturnPlaceholderData;
HTMLCanvasElement* const mOwningElement;
RefPtr<nsRefreshDriver> mRefreshDriver;
};
@@ -682,8 +697,13 @@ HTMLCanvasElement::CaptureStream(const Optional<double>& aFrameRate,
return nullptr;
}
+ // 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());
stream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO);
- RegisterFrameCaptureListener(stream->FrameCaptureListener());
+ RegisterFrameCaptureListener(stream->FrameCaptureListener(), usePlaceholder);
return stream.forget();
}
@@ -693,7 +713,7 @@ HTMLCanvasElement::ExtractData(JSContext* aCx,
const nsAString& aOptions,
nsIInputStream** aStream)
{
- // Check site-speciifc permission and display prompt if appropriate.
+ // 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,
@@ -766,7 +786,7 @@ HTMLCanvasElement::ToBlob(JSContext* aCx,
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
- // Check site-speciifc permission and display prompt if appropriate.
+ // 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,
@@ -1131,7 +1151,8 @@ HTMLCanvasElement::IsContextCleanForFrameCapture()
}
void
-HTMLCanvasElement::RegisterFrameCaptureListener(FrameCaptureListener* aListener)
+HTMLCanvasElement::RegisterFrameCaptureListener(FrameCaptureListener* aListener,
+ bool aReturnPlaceholderData)
{
WeakPtr<FrameCaptureListener> listener = aListener;
@@ -1158,7 +1179,10 @@ HTMLCanvasElement::RegisterFrameCaptureListener(FrameCaptureListener* aListener)
MOZ_RELEASE_ASSERT(driver);
mRequestedFrameRefreshObserver =
- new RequestedFrameRefreshObserver(this, driver);
+ new RequestedFrameRefreshObserver(this, driver, aReturnPlaceholderData);
+ } else {
+ mRequestedFrameRefreshObserver->SetReturnPlaceholderData(
+ aReturnPlaceholderData);
}
mRequestedFrameRefreshObserver->Register();
diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h
index 542f11b..6ed7bbd 100644
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -263,8 +263,11 @@ public:
* 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.
+ * If aReturnPlaceholderData is true, white data is captured instead of the
+ * actual canvas contents.
*/
- void RegisterFrameCaptureListener(FrameCaptureListener* aListener);
+ void RegisterFrameCaptureListener(FrameCaptureListener* aListener,
+ bool aReturnPlaceholderData);
/*
* Returns true when there is at least one registered FrameCaptureListener