This repository has been archived by the owner on Aug 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 966439 - BroadcastChannel API - patch 1 - BroadcastChannel for ma…
…in-thread, r=smaug, r=bent
- Loading branch information
Showing
30 changed files
with
1,582 additions
and
4 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#ifndef mozilla_dom_BroadcastChannel_h | ||
#define mozilla_dom_BroadcastChannel_h | ||
|
||
#include "mozilla/Attributes.h" | ||
#include "mozilla/DOMEventTargetHelper.h" | ||
#include "mozilla/ipc/PBackgroundSharedTypes.h" | ||
#include "nsIIPCBackgroundChildCreateCallback.h" | ||
#include "nsIObserver.h" | ||
#include "nsTArray.h" | ||
#include "nsRefPtr.h" | ||
|
||
class nsPIDOMWindow; | ||
|
||
namespace mozilla { | ||
namespace dom { | ||
|
||
namespace workers { | ||
class WorkerFeature; | ||
} | ||
|
||
class BroadcastChannelChild; | ||
|
||
class BroadcastChannel MOZ_FINAL | ||
: public DOMEventTargetHelper | ||
, public nsIIPCBackgroundChildCreateCallback | ||
, public nsIObserver | ||
{ | ||
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK | ||
NS_DECL_NSIOBSERVER | ||
|
||
typedef mozilla::ipc::PrincipalInfo PrincipalInfo; | ||
|
||
public: | ||
NS_DECL_ISUPPORTS_INHERITED | ||
|
||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BroadcastChannel, | ||
DOMEventTargetHelper) | ||
|
||
virtual JSObject* | ||
WrapObject(JSContext* aCx) MOZ_OVERRIDE; | ||
|
||
static already_AddRefed<BroadcastChannel> | ||
Constructor(const GlobalObject& aGlobal, const nsAString& aChannel, | ||
ErrorResult& aRv); | ||
|
||
void GetName(nsAString& aName) const | ||
{ | ||
aName = mChannel; | ||
} | ||
|
||
void PostMessage(const nsAString& aMessage); | ||
|
||
EventHandlerNonNull* GetOnmessage(); | ||
void SetOnmessage(EventHandlerNonNull* aCallback); | ||
|
||
using nsIDOMEventTarget::AddEventListener; | ||
using nsIDOMEventTarget::RemoveEventListener; | ||
|
||
virtual void AddEventListener(const nsAString& aType, | ||
EventListener* aCallback, | ||
bool aCapture, | ||
const Nullable<bool>& aWantsUntrusted, | ||
ErrorResult& aRv) MOZ_OVERRIDE; | ||
virtual void RemoveEventListener(const nsAString& aType, | ||
EventListener* aCallback, | ||
bool aCapture, | ||
ErrorResult& aRv) MOZ_OVERRIDE; | ||
|
||
void Shutdown(); | ||
|
||
private: | ||
BroadcastChannel(nsPIDOMWindow* aWindow, | ||
const PrincipalInfo& aPrincipalInfo, | ||
const nsAString& aOrigin, | ||
const nsAString& aChannel); | ||
|
||
~BroadcastChannel(); | ||
|
||
void UpdateMustKeepAlive(); | ||
|
||
nsRefPtr<BroadcastChannelChild> mActor; | ||
nsTArray<nsString> mPendingMessages; | ||
|
||
workers::WorkerFeature* mWorkerFeature; | ||
|
||
PrincipalInfo mPrincipalInfo; | ||
nsString mOrigin; | ||
nsString mChannel; | ||
|
||
bool mIsKeptAlive; | ||
|
||
uint64_t mInnerID; | ||
}; | ||
|
||
} // namespace dom | ||
} // namespace mozilla | ||
|
||
#endif // mozilla_dom_BroadcastChannel_h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#include "BroadcastChannelChild.h" | ||
#include "BroadcastChannel.h" | ||
#include "jsapi.h" | ||
#include "mozilla/dom/MessageEvent.h" | ||
#include "mozilla/dom/MessageEventBinding.h" | ||
#include "mozilla/dom/ScriptSettings.h" | ||
#include "mozilla/ipc/PBackgroundChild.h" | ||
#include "WorkerPrivate.h" | ||
|
||
namespace mozilla { | ||
|
||
using namespace ipc; | ||
|
||
namespace dom { | ||
|
||
using namespace workers; | ||
|
||
BroadcastChannelChild::BroadcastChannelChild(const nsAString& aOrigin, | ||
const nsAString& aChannel) | ||
: mOrigin(aOrigin) | ||
, mChannel(aChannel) | ||
, mActorDestroyed(false) | ||
{ | ||
} | ||
|
||
BroadcastChannelChild::~BroadcastChannelChild() | ||
{ | ||
MOZ_ASSERT(!mEventTarget); | ||
} | ||
|
||
bool | ||
BroadcastChannelChild::RecvNotify(const nsString& aMessage) | ||
{ | ||
// This object is going to be deleted soon. No notify is required. | ||
if (!mEventTarget) { | ||
return true; | ||
} | ||
|
||
if (NS_IsMainThread()) { | ||
DOMEventTargetHelper* deth = | ||
DOMEventTargetHelper::FromSupports(mEventTarget); | ||
MOZ_ASSERT(deth); | ||
|
||
AutoJSAPI autoJS; | ||
if (!autoJS.Init(deth->GetParentObject())) { | ||
NS_WARNING("Dropping message"); | ||
return true; | ||
} | ||
|
||
Notify(autoJS.cx(), aMessage); | ||
return true; | ||
} | ||
|
||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); | ||
MOZ_ASSERT(workerPrivate); | ||
|
||
Notify(workerPrivate->GetJSContext(), aMessage); | ||
return true; | ||
} | ||
|
||
void | ||
BroadcastChannelChild::Notify(JSContext* aCx, const nsString& aMessage) | ||
{ | ||
JS::Rooted<JSString*> str(aCx, | ||
JS_NewUCStringCopyN(aCx, aMessage.get(), | ||
aMessage.Length())); | ||
if (!str) { | ||
// OOM, no exception needed. | ||
NS_WARNING("Failed allocating a JS string. Probably OOM."); | ||
return; | ||
} | ||
|
||
JS::Rooted<JS::Value> value(aCx, JS::StringValue(str)); | ||
|
||
RootedDictionary<MessageEventInit> init(aCx); | ||
init.mBubbles = false; | ||
init.mCancelable = false; | ||
init.mOrigin.Construct(mOrigin); | ||
init.mData = value; | ||
|
||
ErrorResult rv; | ||
nsRefPtr<MessageEvent> event = | ||
MessageEvent::Constructor(mEventTarget, NS_LITERAL_STRING("message"), | ||
init, rv); | ||
if (rv.Failed()) { | ||
NS_WARNING("Failed to create a MessageEvent object."); | ||
return; | ||
} | ||
|
||
event->SetTrusted(true); | ||
|
||
bool status; | ||
mEventTarget->DispatchEvent(static_cast<Event*>(event.get()), &status); | ||
} | ||
|
||
void | ||
BroadcastChannelChild::ActorDestroy(ActorDestroyReason aWhy) | ||
{ | ||
mActorDestroyed = true; | ||
} | ||
|
||
} // dom namespace | ||
} // mozilla namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
* You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#ifndef mozilla_dom_BroadcastChannelChild_h | ||
#define mozilla_dom_BroadcastChannelChild_h | ||
|
||
#include "mozilla/dom/EventTarget.h" | ||
#include "mozilla/dom/PBroadcastChannelChild.h" | ||
|
||
namespace mozilla { | ||
|
||
namespace ipc { | ||
class BackgroundChildImpl; | ||
} | ||
|
||
namespace dom { | ||
|
||
class EventTarget; | ||
|
||
class BroadcastChannelChild MOZ_FINAL : public PBroadcastChannelChild | ||
{ | ||
friend class mozilla::ipc::BackgroundChildImpl; | ||
|
||
public: | ||
NS_INLINE_DECL_REFCOUNTING(BroadcastChannelChild) | ||
|
||
void SetEventTarget(EventTarget* aEventTarget) | ||
{ | ||
mEventTarget = aEventTarget; | ||
} | ||
|
||
virtual bool RecvNotify(const nsString& aMessage) MOZ_OVERRIDE; | ||
|
||
bool IsActorDestroyed() const | ||
{ | ||
return mActorDestroyed; | ||
} | ||
|
||
private: | ||
BroadcastChannelChild(const nsAString& aOrigin, | ||
const nsAString& aChannel); | ||
|
||
~BroadcastChannelChild(); | ||
|
||
void Notify(JSContext* aCx, const nsString& aMessage); | ||
|
||
void ActorDestroy(ActorDestroyReason aWhy); | ||
|
||
// This raw pointer is actually the parent object. | ||
// It's set to null when the parent object is deleted. | ||
EventTarget* mEventTarget; | ||
|
||
nsString mOrigin; | ||
nsString mChannel; | ||
|
||
bool mActorDestroyed; | ||
}; | ||
|
||
} // dom namespace | ||
} // mozilla namespace | ||
|
||
#endif // mozilla_dom_BroadcastChannelChild_h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
||
#include "BroadcastChannelParent.h" | ||
#include "BroadcastChannelService.h" | ||
#include "mozilla/ipc/BackgroundParent.h" | ||
#include "mozilla/unused.h" | ||
|
||
namespace mozilla { | ||
|
||
using namespace ipc; | ||
|
||
namespace dom { | ||
|
||
BroadcastChannelParent::BroadcastChannelParent( | ||
const nsAString& aOrigin, | ||
const nsAString& aChannel) | ||
: mService(BroadcastChannelService::GetOrCreate()) | ||
, mOrigin(aOrigin) | ||
, mChannel(aChannel) | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
mService->RegisterActor(this); | ||
} | ||
|
||
BroadcastChannelParent::~BroadcastChannelParent() | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
} | ||
|
||
bool | ||
BroadcastChannelParent::RecvPostMessage(const nsString& aMessage) | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
|
||
if (NS_WARN_IF(!mService)) { | ||
return false; | ||
} | ||
|
||
mService->PostMessage(this, aMessage, mOrigin, mChannel); | ||
return true; | ||
} | ||
|
||
bool | ||
BroadcastChannelParent::RecvClose() | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
|
||
if (NS_WARN_IF(!mService)) { | ||
return false; | ||
} | ||
|
||
mService->UnregisterActor(this); | ||
mService = nullptr; | ||
|
||
unused << Send__delete__(this); | ||
|
||
return true; | ||
} | ||
|
||
void | ||
BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy) | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
|
||
if (mService) { | ||
// This object is about to be released and with it, also mService will be | ||
// released too. | ||
mService->UnregisterActor(this); | ||
} | ||
} | ||
|
||
void | ||
BroadcastChannelParent::CheckAndDeliver(const nsString& aMessage, | ||
const nsString& aOrigin, | ||
const nsString& aChannel) | ||
{ | ||
AssertIsOnBackgroundThread(); | ||
|
||
if (aOrigin == mOrigin && aChannel == mChannel) { | ||
unused << SendNotify(aMessage); | ||
} | ||
} | ||
|
||
} // dom namespace | ||
} // mozilla namespace |
Oops, something went wrong.