2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2015-01-15 19:58:40 +03:00
|
|
|
/* 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 "BroadcastChannel.h"
|
|
|
|
#include "BroadcastChannelChild.h"
|
|
|
|
#include "mozilla/dom/BroadcastChannelBinding.h"
|
2015-01-15 19:58:41 +03:00
|
|
|
#include "mozilla/dom/Navigator.h"
|
2015-07-28 10:38:16 +03:00
|
|
|
#include "mozilla/dom/File.h"
|
2015-09-30 15:22:08 +03:00
|
|
|
#include "mozilla/dom/StructuredCloneHolder.h"
|
2016-11-08 11:09:31 +03:00
|
|
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
2018-01-31 10:25:30 +03:00
|
|
|
#include "mozilla/dom/WorkerPrivate.h"
|
2018-03-13 23:16:54 +03:00
|
|
|
#include "mozilla/dom/WorkerRef.h"
|
2018-01-31 10:25:30 +03:00
|
|
|
#include "mozilla/dom/WorkerRunnable.h"
|
2015-01-15 19:58:40 +03:00
|
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
|
|
|
#include "mozilla/ipc/BackgroundUtils.h"
|
|
|
|
#include "mozilla/ipc/PBackgroundChild.h"
|
2015-10-26 19:14:47 +03:00
|
|
|
#include "nsContentUtils.h"
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2015-10-13 14:04:17 +03:00
|
|
|
#include "nsIBFCacheEntry.h"
|
2015-01-15 19:58:40 +03:00
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsISupportsPrimitives.h"
|
|
|
|
|
2015-01-15 19:58:42 +03:00
|
|
|
#ifdef XP_WIN
|
|
|
|
#undef PostMessage
|
|
|
|
#endif
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
using namespace ipc;
|
|
|
|
|
|
|
|
namespace dom {
|
|
|
|
|
2016-11-08 11:09:31 +03:00
|
|
|
using namespace ipc;
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2016-11-08 11:09:31 +03:00
|
|
|
class BroadcastChannelMessage final : public StructuredCloneDataNoTransfers
|
2015-01-15 19:58:41 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(BroadcastChannelMessage)
|
|
|
|
|
|
|
|
BroadcastChannelMessage()
|
2016-11-08 11:09:31 +03:00
|
|
|
: StructuredCloneDataNoTransfers()
|
2015-07-28 10:38:16 +03:00
|
|
|
{}
|
2015-01-15 19:58:41 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
~BroadcastChannelMessage()
|
2015-07-28 10:38:16 +03:00
|
|
|
{}
|
2015-01-15 19:58:41 +03:00
|
|
|
};
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
namespace {
|
|
|
|
|
2015-01-15 19:58:41 +03:00
|
|
|
nsIPrincipal*
|
2018-03-13 23:16:54 +03:00
|
|
|
GetPrincipalFromThreadSafeWorkerRef(ThreadSafeWorkerRef* aWorkerRef)
|
2015-01-15 19:58:41 +03:00
|
|
|
{
|
2018-03-13 23:16:54 +03:00
|
|
|
nsIPrincipal* principal = aWorkerRef->Private()->GetPrincipal();
|
2015-01-15 19:58:41 +03:00
|
|
|
if (principal) {
|
|
|
|
return principal;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Walk up to our containing page
|
2018-03-13 23:16:54 +03:00
|
|
|
WorkerPrivate* wp = aWorkerRef->Private();
|
2015-01-15 19:58:41 +03:00
|
|
|
while (wp->GetParent()) {
|
|
|
|
wp = wp->GetParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return wp->GetPrincipal();
|
|
|
|
}
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class InitializeRunnable final : public WorkerMainThreadRunnable
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
|
|
|
public:
|
2018-03-13 23:16:54 +03:00
|
|
|
InitializeRunnable(ThreadSafeWorkerRef* aWorkerRef, nsACString& aOrigin,
|
2016-06-07 14:50:00 +03:00
|
|
|
PrincipalInfo& aPrincipalInfo, ErrorResult& aRv)
|
2018-03-13 23:16:54 +03:00
|
|
|
: WorkerMainThreadRunnable(aWorkerRef->Private(),
|
2016-05-03 10:09:47 +03:00
|
|
|
NS_LITERAL_CSTRING("BroadcastChannel :: Initialize"))
|
2018-03-13 23:16:54 +03:00
|
|
|
, mWorkerRef(aWorkerRef)
|
2015-01-15 19:58:40 +03:00
|
|
|
, mOrigin(aOrigin)
|
|
|
|
, mPrincipalInfo(aPrincipalInfo)
|
|
|
|
, mRv(aRv)
|
|
|
|
{
|
2018-03-13 23:16:54 +03:00
|
|
|
MOZ_ASSERT(mWorkerRef);
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
bool MainThreadRun() override
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2015-01-15 19:58:41 +03:00
|
|
|
|
2018-03-13 23:16:54 +03:00
|
|
|
nsIPrincipal* principal = GetPrincipalFromThreadSafeWorkerRef(mWorkerRef);
|
2015-01-15 19:58:41 +03:00
|
|
|
if (!principal) {
|
|
|
|
mRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return true;
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
|
|
|
mRv = PrincipalToPrincipalInfo(principal, &mPrincipalInfo);
|
|
|
|
if (NS_WARN_IF(mRv.Failed())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-07-06 21:28:41 +03:00
|
|
|
mRv = principal->GetOrigin(mOrigin);
|
2015-01-15 19:58:40 +03:00
|
|
|
if (NS_WARN_IF(mRv.Failed())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-15 19:58:41 +03:00
|
|
|
// Walk up to our containing page
|
2018-03-13 23:16:54 +03:00
|
|
|
WorkerPrivate* wp = mWorkerRef->Private();
|
2015-01-15 19:58:41 +03:00
|
|
|
while (wp->GetParent()) {
|
|
|
|
wp = wp->GetParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Window doesn't exist for some kind of workers (eg: SharedWorkers)
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowInner* window = wp->GetWindow();
|
2015-01-15 19:58:41 +03:00
|
|
|
if (!window) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-03-13 23:16:54 +03:00
|
|
|
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
|
2015-07-06 21:28:41 +03:00
|
|
|
nsACString& mOrigin;
|
2015-01-15 19:58:40 +03:00
|
|
|
PrincipalInfo& mPrincipalInfo;
|
|
|
|
ErrorResult& mRv;
|
|
|
|
};
|
|
|
|
|
2016-04-11 21:40:06 +03:00
|
|
|
class CloseRunnable final : public nsIRunnable,
|
|
|
|
public nsICancelableRunnable
|
2015-01-15 19:58:42 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2015-01-15 19:58:42 +03:00
|
|
|
explicit CloseRunnable(BroadcastChannel* aBC)
|
2015-01-15 19:58:42 +03:00
|
|
|
: mBC(aBC)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mBC);
|
|
|
|
}
|
|
|
|
|
2016-08-08 03:54:47 +03:00
|
|
|
NS_IMETHOD Run() override
|
2015-01-15 19:58:42 +03:00
|
|
|
{
|
|
|
|
mBC->Shutdown();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-04-11 21:40:06 +03:00
|
|
|
nsresult Cancel() override
|
2015-01-15 19:58:42 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
~CloseRunnable() {}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<BroadcastChannel> mBC;
|
2015-01-15 19:58:42 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(CloseRunnable, nsICancelableRunnable, nsIRunnable)
|
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
class TeardownRunnable
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
2018-02-15 10:50:49 +03:00
|
|
|
protected:
|
2015-01-15 19:58:42 +03:00
|
|
|
explicit TeardownRunnable(BroadcastChannelChild* aActor)
|
2015-01-15 19:58:40 +03:00
|
|
|
: mActor(aActor)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mActor);
|
|
|
|
}
|
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
void RunInternal()
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(mActor);
|
|
|
|
if (!mActor->IsActorDestroyed()) {
|
|
|
|
mActor->SendClose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
protected:
|
|
|
|
virtual ~TeardownRunnable() = default;
|
|
|
|
|
|
|
|
private:
|
|
|
|
RefPtr<BroadcastChannelChild> mActor;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TeardownRunnableOnMainThread final : public Runnable
|
|
|
|
, public TeardownRunnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit TeardownRunnableOnMainThread(BroadcastChannelChild* aActor)
|
|
|
|
: Runnable("TeardownRunnableOnMainThread")
|
|
|
|
, TeardownRunnable(aActor)
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
2018-02-15 10:50:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD Run() override
|
|
|
|
{
|
|
|
|
RunInternal();
|
2015-01-15 19:58:40 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2018-02-15 10:50:49 +03:00
|
|
|
};
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
class TeardownRunnableOnWorker final : public WorkerControlRunnable
|
|
|
|
, public TeardownRunnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TeardownRunnableOnWorker(WorkerPrivate* aWorkerPrivate,
|
|
|
|
BroadcastChannelChild* aActor)
|
|
|
|
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
|
|
|
|
, TeardownRunnable(aActor)
|
|
|
|
{
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
bool WorkerRun(JSContext*, WorkerPrivate*) override
|
|
|
|
{
|
|
|
|
RunInternal();
|
|
|
|
return true;
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
bool
|
|
|
|
PreDispatch(WorkerPrivate* aWorkerPrivate) override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PreRun(WorkerPrivate* aWorkerPrivate) override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
|
|
|
bool aRunResult) override
|
|
|
|
{}
|
|
|
|
};
|
2015-01-15 19:58:40 +03:00
|
|
|
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
BroadcastChannel::BroadcastChannel(nsPIDOMWindowInner* aWindow,
|
2016-06-07 14:50:00 +03:00
|
|
|
const nsAString& aChannel)
|
2015-01-15 19:58:40 +03:00
|
|
|
: DOMEventTargetHelper(aWindow)
|
|
|
|
, mChannel(aChannel)
|
2015-01-15 19:58:40 +03:00
|
|
|
, mState(StateActive)
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
|
|
|
// Window can be null in workers
|
2017-04-18 14:51:59 +03:00
|
|
|
|
|
|
|
KeepAliveIfHasListenersFor(NS_LITERAL_STRING("message"));
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
BroadcastChannel::~BroadcastChannel()
|
|
|
|
{
|
|
|
|
Shutdown();
|
2018-03-13 23:16:54 +03:00
|
|
|
MOZ_ASSERT(!mWorkerRef);
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
JSObject*
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
|
|
|
BroadcastChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
|
|
|
return BroadcastChannelBinding::Wrap(aCx, this, aGivenProto);
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ already_AddRefed<BroadcastChannel>
|
|
|
|
BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|
|
|
const nsAString& aChannel,
|
|
|
|
ErrorResult& aRv)
|
|
|
|
{
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowInner> window =
|
|
|
|
do_QueryInterface(aGlobal.GetAsSupports());
|
2015-01-15 19:58:40 +03:00
|
|
|
// Window is null in workers.
|
|
|
|
|
2018-03-13 23:16:54 +03:00
|
|
|
RefPtr<BroadcastChannel> bc = new BroadcastChannel(window, aChannel);
|
|
|
|
|
2015-07-06 21:28:41 +03:00
|
|
|
nsAutoCString origin;
|
2015-01-15 19:58:40 +03:00
|
|
|
PrincipalInfo principalInfo;
|
|
|
|
|
|
|
|
if (NS_IsMainThread()) {
|
|
|
|
nsCOMPtr<nsIGlobalObject> incumbent = mozilla::dom::GetIncumbentGlobal();
|
|
|
|
|
|
|
|
if (!incumbent) {
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIPrincipal* principal = incumbent->PrincipalOrNull();
|
|
|
|
if (!principal) {
|
|
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-07-06 21:28:41 +03:00
|
|
|
aRv = principal->GetOrigin(origin);
|
2015-01-23 20:32:23 +03:00
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
|
|
|
aRv = PrincipalToPrincipalInfo(principal, &principalInfo);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
JSContext* cx = aGlobal.Context();
|
2018-03-13 23:16:54 +03:00
|
|
|
|
|
|
|
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
2015-01-15 19:58:40 +03:00
|
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
|
2018-03-13 23:16:54 +03:00
|
|
|
RefPtr<StrongWorkerRef> workerRef =
|
|
|
|
StrongWorkerRef::Create(workerPrivate, "BroadcastChannel",
|
|
|
|
[bc] () { bc->Shutdown(); });
|
|
|
|
// We are already shutting down the worker. Let's return a non-active
|
|
|
|
// object.
|
|
|
|
if (NS_WARN_IF(!workerRef)) {
|
2018-04-17 21:51:02 +03:00
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
2018-03-13 23:16:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<ThreadSafeWorkerRef> tsr = new ThreadSafeWorkerRef(workerRef);
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<InitializeRunnable> runnable =
|
2018-03-13 23:16:54 +03:00
|
|
|
new InitializeRunnable(tsr, origin, principalInfo, aRv);
|
2018-04-17 21:51:02 +03:00
|
|
|
runnable->Dispatch(Canceling, aRv);
|
2018-03-13 23:16:54 +03:00
|
|
|
if (aRv.Failed()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2018-03-13 23:16:54 +03:00
|
|
|
bc->mWorkerRef = Move(workerRef);
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Register this component to PBackground.
|
2017-10-24 13:02:39 +03:00
|
|
|
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
|
|
|
|
if (NS_WARN_IF(!actorChild)) {
|
2017-10-25 09:45:52 +03:00
|
|
|
// Firefox is probably shutting down. Let's return a 'generic' error.
|
|
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
|
|
return nullptr;
|
2015-01-15 19:58:42 +03:00
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2017-10-24 13:02:39 +03:00
|
|
|
PBroadcastChannelChild* actor =
|
|
|
|
actorChild->SendPBroadcastChannelConstructor(principalInfo, origin,
|
|
|
|
nsString(aChannel));
|
|
|
|
|
|
|
|
bc->mActor = static_cast<BroadcastChannelChild*>(actor);
|
|
|
|
MOZ_ASSERT(bc->mActor);
|
|
|
|
|
|
|
|
bc->mActor->SetParent(bc);
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
return bc.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-01-15 19:58:41 +03:00
|
|
|
BroadcastChannel::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
|
|
|
ErrorResult& aRv)
|
2015-01-15 19:58:40 +03:00
|
|
|
{
|
|
|
|
if (mState != StateActive) {
|
2016-05-22 14:22:52 +03:00
|
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
2015-01-15 19:58:40 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<BroadcastChannelMessage> data = new BroadcastChannelMessage();
|
2015-01-15 19:58:41 +03:00
|
|
|
|
2015-09-02 19:20:30 +03:00
|
|
|
data->Write(aCx, aMessage, aRv);
|
2015-07-31 03:38:00 +03:00
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
2015-01-15 19:58:41 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-13 14:04:17 +03:00
|
|
|
RemoveDocFromBFCache();
|
|
|
|
|
2018-04-14 02:01:52 +03:00
|
|
|
ClonedMessageData message;
|
|
|
|
data->BuildClonedMessageDataForBackgroundChild(mActor->Manager(), message);
|
|
|
|
mActor->SendPostMessage(message);
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
void
|
|
|
|
BroadcastChannel::Close()
|
|
|
|
{
|
|
|
|
if (mState != StateActive) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-10-24 13:02:39 +03:00
|
|
|
// We cannot call Shutdown() immediatelly because we could have some
|
|
|
|
// postMessage runnable already dispatched. Instead, we change the state to
|
|
|
|
// StateClosed and we shutdown the actor asynchrounsly.
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2017-10-24 13:02:39 +03:00
|
|
|
mState = StateClosed;
|
|
|
|
RefPtr<CloseRunnable> runnable = new CloseRunnable(this);
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2017-10-24 13:02:39 +03:00
|
|
|
if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
|
|
|
|
NS_WARNING("Failed to dispatch to the current thread!");
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BroadcastChannel::Shutdown()
|
|
|
|
{
|
2015-01-15 19:58:40 +03:00
|
|
|
mState = StateClosed;
|
|
|
|
|
2018-03-13 23:16:54 +03:00
|
|
|
// The DTOR of this WorkerRef will release the worker for us.
|
|
|
|
mWorkerRef = nullptr;
|
2015-01-15 19:58:40 +03:00
|
|
|
|
|
|
|
if (mActor) {
|
2015-01-15 19:58:41 +03:00
|
|
|
mActor->SetParent(nullptr);
|
2015-01-15 19:58:40 +03:00
|
|
|
|
2018-02-15 10:50:49 +03:00
|
|
|
if (NS_IsMainThread()) {
|
|
|
|
RefPtr<TeardownRunnableOnMainThread> runnable =
|
|
|
|
new TeardownRunnableOnMainThread(mActor);
|
|
|
|
NS_DispatchToCurrentThread(runnable);
|
|
|
|
} else {
|
|
|
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
|
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
|
|
|
|
RefPtr<TeardownRunnableOnWorker> runnable =
|
|
|
|
new TeardownRunnableOnWorker(workerPrivate, mActor);
|
|
|
|
runnable->Dispatch();
|
|
|
|
}
|
2015-01-15 19:58:40 +03:00
|
|
|
|
|
|
|
mActor = nullptr;
|
|
|
|
}
|
2015-02-20 00:21:18 +03:00
|
|
|
|
2017-04-18 14:51:59 +03:00
|
|
|
IgnoreKeepAliveIfHasListenersFor(NS_LITERAL_STRING("message"));
|
2015-01-15 19:58:40 +03:00
|
|
|
}
|
|
|
|
|
2015-10-13 14:04:17 +03:00
|
|
|
void
|
|
|
|
BroadcastChannel::RemoveDocFromBFCache()
|
|
|
|
{
|
|
|
|
if (!NS_IsMainThread()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowInner* window = GetOwner();
|
2015-10-13 14:04:17 +03:00
|
|
|
if (!window) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIDocument* doc = window->GetExtantDoc();
|
|
|
|
if (!doc) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBFCacheEntry> bfCacheEntry = doc->GetBFCacheEntry();
|
|
|
|
if (!bfCacheEntry) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bfCacheEntry->RemoveFromBFCacheSync();
|
|
|
|
}
|
|
|
|
|
2018-04-05 17:55:16 +03:00
|
|
|
void
|
|
|
|
BroadcastChannel::DisconnectFromOwner()
|
|
|
|
{
|
|
|
|
Shutdown();
|
|
|
|
DOMEventTargetHelper::DisconnectFromOwner();
|
|
|
|
}
|
|
|
|
|
2015-01-15 19:58:40 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(BroadcastChannel)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BroadcastChannel,
|
|
|
|
DOMEventTargetHelper)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BroadcastChannel,
|
|
|
|
DOMEventTargetHelper)
|
|
|
|
tmp->Shutdown();
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
2017-08-30 02:02:48 +03:00
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BroadcastChannel)
|
2015-01-15 19:58:40 +03:00
|
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF_INHERITED(BroadcastChannel, DOMEventTargetHelper)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(BroadcastChannel, DOMEventTargetHelper)
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|