Bug 966439 - BroadcastChannel API - patch 7 - Blob supported, r=bent

This commit is contained in:
Andrea Marchesini 2015-01-14 11:50:35 +00:00
parent e71ca9a728
commit 58bd113b8c
11 changed files with 80 additions and 38 deletions

View File

@ -190,18 +190,28 @@ public:
return NS_OK; return NS_OK;
} }
BroadcastChannelMessageData message; ClonedMessageData message;
SerializedStructuredCloneBuffer& buffer = message.data(); SerializedStructuredCloneBuffer& buffer = message.data();
buffer.data = mData->mBuffer.data(); buffer.data = mData->mBuffer.data();
buffer.dataLength = mData->mBuffer.nbytes(); buffer.dataLength = mData->mBuffer.nbytes();
#ifdef DEBUG PBackgroundChild* backgroundManager = mActor->Manager();
{ MOZ_ASSERT(backgroundManager);
const nsTArray<nsRefPtr<File>>& blobs = mData->mClosure.mBlobs;
MOZ_ASSERT(blobs.IsEmpty()); const nsTArray<nsRefPtr<File>>& blobs = mData->mClosure.mBlobs;
if (!blobs.IsEmpty()) {
message.blobsChild().SetCapacity(blobs.Length());
for (uint32_t i = 0, len = blobs.Length(); i < len; ++i) {
PBlobChild* blobChild =
BackgroundChild::GetOrCreateActorForBlob(backgroundManager, blobs[i]);
MOZ_ASSERT(blobChild);
message.blobsChild().AppendElement(blobChild);
}
} }
#endif
mActor->SendPostMessage(message); mActor->SendPostMessage(message);
return NS_OK; return NS_OK;
@ -270,9 +280,6 @@ public:
virtual bool Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE virtual bool Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE
{ {
if (aStatus >= Canceling) { if (aStatus >= Canceling) {
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
MOZ_ASSERT(workerPrivate);
mChannel->Shutdown(); mChannel->Shutdown();
} }

View File

@ -24,7 +24,7 @@ class WorkerFeature;
} }
class BroadcastChannelChild; class BroadcastChannelChild;
struct BroadcastChannelMessage; class BroadcastChannelMessage;
class BroadcastChannel MOZ_FINAL class BroadcastChannel MOZ_FINAL
: public DOMEventTargetHelper : public DOMEventTargetHelper

View File

@ -6,6 +6,8 @@
#include "BroadcastChannelChild.h" #include "BroadcastChannelChild.h"
#include "BroadcastChannel.h" #include "BroadcastChannel.h"
#include "jsapi.h" #include "jsapi.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessageEvent.h" #include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/MessageEventBinding.h" #include "mozilla/dom/MessageEventBinding.h"
#include "mozilla/dom/StructuredCloneUtils.h" #include "mozilla/dom/StructuredCloneUtils.h"
@ -37,7 +39,7 @@ BroadcastChannelChild::~BroadcastChannelChild()
} }
bool bool
BroadcastChannelChild::RecvNotify(const BroadcastChannelMessageData& aData) BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
{ {
nsCOMPtr<DOMEventTargetHelper> helper = mBC; nsCOMPtr<DOMEventTargetHelper> helper = mBC;
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper); nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper);
@ -76,6 +78,18 @@ BroadcastChannelChild::RecvNotify(const BroadcastChannelMessageData& aData)
cloneData.mData = buffer.data; cloneData.mData = buffer.data;
cloneData.mDataLength = buffer.dataLength; cloneData.mDataLength = buffer.dataLength;
if (!aData.blobsChild().IsEmpty()) {
cloneData.mClosure.mBlobs.SetCapacity(aData.blobsChild().Length());
for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) {
nsRefPtr<FileImpl> impl =
static_cast<BlobChild*>(aData.blobsChild()[i])->GetBlobImpl();
nsRefPtr<File> blob = new File(mBC->GetOwner(), impl);
cloneData.mClosure.mBlobs.AppendElement(blob);
}
}
JS::Rooted<JS::Value> value(cx, JS::NullValue()); JS::Rooted<JS::Value> value(cx, JS::NullValue());
if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) { if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) {
JS_ClearPendingException(cx); JS_ClearPendingException(cx);

View File

@ -29,8 +29,7 @@ public:
mBC = aBC; mBC = aBC;
} }
virtual bool RecvNotify(const BroadcastChannelMessageData& aData) virtual bool RecvNotify(const ClonedMessageData& aData) MOZ_OVERRIDE;
MOZ_OVERRIDE;
bool IsActorDestroyed() const bool IsActorDestroyed() const
{ {

View File

@ -5,6 +5,8 @@
#include "BroadcastChannelParent.h" #include "BroadcastChannelParent.h"
#include "BroadcastChannelService.h" #include "BroadcastChannelService.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/unused.h" #include "mozilla/unused.h"
@ -31,8 +33,7 @@ BroadcastChannelParent::~BroadcastChannelParent()
} }
bool bool
BroadcastChannelParent::RecvPostMessage( BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
const BroadcastChannelMessageData& aData)
{ {
AssertIsOnBackgroundThread(); AssertIsOnBackgroundThread();
@ -74,15 +75,37 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
} }
void void
BroadcastChannelParent::CheckAndDeliver( BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
const BroadcastChannelMessageData& aData, const nsString& aOrigin,
const nsString& aOrigin, const nsString& aChannel)
const nsString& aChannel)
{ {
AssertIsOnBackgroundThread(); AssertIsOnBackgroundThread();
if (aOrigin == mOrigin && aChannel == mChannel) { if (aOrigin == mOrigin && aChannel == mChannel) {
unused << SendNotify(aData); // We need to duplicate data only if we have blobs.
if (aData.blobsParent().IsEmpty()) {
unused << SendNotify(aData);
return;
}
// Duplicate the data for this parent.
ClonedMessageData newData(aData);
// Ricreate the BlobParent for this new message.
for (uint32_t i = 0, len = newData.blobsParent().Length(); i < len; ++i) {
nsRefPtr<FileImpl> impl =
static_cast<BlobParent*>(newData.blobsParent()[i])->GetBlobImpl();
PBlobParent* blobParent =
BackgroundParent::GetOrCreateActorForBlobImpl(Manager(), impl);
if (!blobParent) {
return;
}
newData.blobsParent()[i] = blobParent;
}
unused << SendNotify(newData);
} }
} }

View File

@ -22,7 +22,7 @@ class BroadcastChannelParent MOZ_FINAL : public PBroadcastChannelParent
friend class mozilla::ipc::BackgroundParentImpl; friend class mozilla::ipc::BackgroundParentImpl;
public: public:
void CheckAndDeliver(const BroadcastChannelMessageData& aData, void CheckAndDeliver(const ClonedMessageData& aData,
const nsString& aOrigin, const nsString& aOrigin,
const nsString& aChannel); const nsString& aChannel);
@ -32,7 +32,7 @@ private:
~BroadcastChannelParent(); ~BroadcastChannelParent();
virtual bool virtual bool
RecvPostMessage(const BroadcastChannelMessageData& aData) MOZ_OVERRIDE; RecvPostMessage(const ClonedMessageData& aData) MOZ_OVERRIDE;
virtual bool RecvClose() MOZ_OVERRIDE; virtual bool RecvClose() MOZ_OVERRIDE;

View File

@ -75,7 +75,7 @@ namespace {
struct MOZ_STACK_CLASS PostMessageData MOZ_FINAL struct MOZ_STACK_CLASS PostMessageData MOZ_FINAL
{ {
PostMessageData(BroadcastChannelParent* aParent, PostMessageData(BroadcastChannelParent* aParent,
const BroadcastChannelMessageData& aData, const ClonedMessageData& aData,
const nsAString& aOrigin, const nsAString& aOrigin,
const nsAString& aChannel) const nsAString& aChannel)
: mParent(aParent) : mParent(aParent)
@ -93,7 +93,7 @@ struct MOZ_STACK_CLASS PostMessageData MOZ_FINAL
} }
BroadcastChannelParent* mParent; BroadcastChannelParent* mParent;
const BroadcastChannelMessageData& mData; const ClonedMessageData& mData;
const nsString mOrigin; const nsString mOrigin;
const nsString mChannel; const nsString mChannel;
}; };
@ -118,7 +118,7 @@ PostMessageEnumerator(nsPtrHashKey<BroadcastChannelParent>* aKey, void* aPtr)
void void
BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent, BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
const BroadcastChannelMessageData& aData, const ClonedMessageData& aData,
const nsAString& aOrigin, const nsAString& aOrigin,
const nsAString& aChannel) const nsAString& aChannel)
{ {

View File

@ -13,7 +13,7 @@ namespace mozilla {
namespace dom { namespace dom {
class BroadcastChannelParent; class BroadcastChannelParent;
class BroadcastChannelMessageData; class ClonedMessageData;
class BroadcastChannelService MOZ_FINAL class BroadcastChannelService MOZ_FINAL
{ {
@ -26,7 +26,7 @@ public:
void UnregisterActor(BroadcastChannelParent* aParent); void UnregisterActor(BroadcastChannelParent* aParent);
void PostMessage(BroadcastChannelParent* aParent, void PostMessage(BroadcastChannelParent* aParent,
const BroadcastChannelMessageData& aData, const ClonedMessageData& aData,
const nsAString& aOrigin, const nsAString& aOrigin,
const nsAString& aChannel); const nsAString& aChannel);

View File

@ -3,28 +3,25 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackground; include protocol PBackground;
include protocol PBlob;
include DOMTypes;
using struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; using struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
struct BroadcastChannelMessageData
{
SerializedStructuredCloneBuffer data;
};
// This protocol is used for the BroadcastChannel API // This protocol is used for the BroadcastChannel API
protocol PBroadcastChannel protocol PBroadcastChannel
{ {
manager PBackground; manager PBackground;
parent: parent:
PostMessage(BroadcastChannelMessageData message); PostMessage(ClonedMessageData message);
Close(); Close();
child: child:
Notify(BroadcastChannelMessageData message); Notify(ClonedMessageData message);
__delete__(); __delete__();
}; };

View File

@ -19,6 +19,7 @@ var tests = [
new Date(), new Date(),
[ 1, 'test', true, new Date() ], [ 1, 'test', true, new Date() ],
{ a: true, b: null, c: new Date(), d: [ true, false, {} ] }, { a: true, b: null, c: new Date(), d: [ true, false, {} ] },
new Blob([123], { type: 'plain/text' })
]; ];
var currentTest = null; var currentTest = null;

View File

@ -26,15 +26,17 @@ namespace {
void void
Error(JSContext* aCx, uint32_t aErrorId) Error(JSContext* aCx, uint32_t aErrorId)
{ {
MOZ_ASSERT(NS_IsMainThread()); if (NS_IsMainThread()) {
NS_DOMStructuredCloneError(aCx, aErrorId); NS_DOMStructuredCloneError(aCx, aErrorId);
} else {
Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
}
} }
JSObject* JSObject*
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag, Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
uint32_t aData, void* aClosure) uint32_t aData, void* aClosure)
{ {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aClosure); MOZ_ASSERT(aClosure);
StructuredCloneClosure* closure = StructuredCloneClosure* closure =
@ -80,7 +82,6 @@ bool
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj, void* aClosure) JS::Handle<JSObject*> aObj, void* aClosure)
{ {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aClosure); MOZ_ASSERT(aClosure);
StructuredCloneClosure* closure = StructuredCloneClosure* closure =