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;
}
BroadcastChannelMessageData message;
ClonedMessageData message;
SerializedStructuredCloneBuffer& buffer = message.data();
buffer.data = mData->mBuffer.data();
buffer.dataLength = mData->mBuffer.nbytes();
#ifdef DEBUG
{
const nsTArray<nsRefPtr<File>>& blobs = mData->mClosure.mBlobs;
MOZ_ASSERT(blobs.IsEmpty());
PBackgroundChild* backgroundManager = mActor->Manager();
MOZ_ASSERT(backgroundManager);
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);
return NS_OK;
@ -270,9 +280,6 @@ public:
virtual bool Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE
{
if (aStatus >= Canceling) {
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
MOZ_ASSERT(workerPrivate);
mChannel->Shutdown();
}

View File

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

View File

@ -6,6 +6,8 @@
#include "BroadcastChannelChild.h"
#include "BroadcastChannel.h"
#include "jsapi.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/MessageEventBinding.h"
#include "mozilla/dom/StructuredCloneUtils.h"
@ -37,7 +39,7 @@ BroadcastChannelChild::~BroadcastChannelChild()
}
bool
BroadcastChannelChild::RecvNotify(const BroadcastChannelMessageData& aData)
BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
{
nsCOMPtr<DOMEventTargetHelper> helper = mBC;
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper);
@ -76,6 +78,18 @@ BroadcastChannelChild::RecvNotify(const BroadcastChannelMessageData& aData)
cloneData.mData = buffer.data;
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());
if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) {
JS_ClearPendingException(cx);

View File

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

View File

@ -5,6 +5,8 @@
#include "BroadcastChannelParent.h"
#include "BroadcastChannelService.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/unused.h"
@ -31,8 +33,7 @@ BroadcastChannelParent::~BroadcastChannelParent()
}
bool
BroadcastChannelParent::RecvPostMessage(
const BroadcastChannelMessageData& aData)
BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
{
AssertIsOnBackgroundThread();
@ -74,15 +75,37 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
}
void
BroadcastChannelParent::CheckAndDeliver(
const BroadcastChannelMessageData& aData,
const nsString& aOrigin,
const nsString& aChannel)
BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
const nsString& aOrigin,
const nsString& aChannel)
{
AssertIsOnBackgroundThread();
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;
public:
void CheckAndDeliver(const BroadcastChannelMessageData& aData,
void CheckAndDeliver(const ClonedMessageData& aData,
const nsString& aOrigin,
const nsString& aChannel);
@ -32,7 +32,7 @@ private:
~BroadcastChannelParent();
virtual bool
RecvPostMessage(const BroadcastChannelMessageData& aData) MOZ_OVERRIDE;
RecvPostMessage(const ClonedMessageData& aData) MOZ_OVERRIDE;
virtual bool RecvClose() MOZ_OVERRIDE;

View File

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

View File

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

View File

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

View File

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

View File

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