/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */
void RunInternal() {
MOZ_ASSERT(mActor); if (!mActor->IsActorDestroyed()) {
mActor->SendClose();
}
}
protected: virtual ~TeardownRunnable() = default;
private:
RefPtr<BroadcastChannelChild> mActor;
};
class TeardownRunnableOnMainThread final : public Runnable, public TeardownRunnable { public: explicit TeardownRunnableOnMainThread(BroadcastChannelChild* aActor)
: Runnable("TeardownRunnableOnMainThread"), TeardownRunnable(aActor) {}
class TeardownRunnableOnWorker final : public WorkerControlRunnable, public TeardownRunnable { public:
TeardownRunnableOnWorker(WorkerPrivate* aWorkerPrivate,
BroadcastChannelChild* aActor)
: WorkerControlRunnable("TeardownRunnableOnWorker"),
TeardownRunnable(aActor) {}
/* static */
already_AddRefed<BroadcastChannel>
BroadcastChannel::UnpartitionedTestingChannel(const GlobalObject& aGlobal, const nsAString& aChannel,
ErrorResult& aRv) { // This function must not be used outside of automation. if (!xpc::IsInAutomation()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
nsID portUUID = {};
aRv = nsID::GenerateUUIDInPlace(portUUID); if (aRv.Failed()) { return nullptr;
}
RefPtr<BroadcastChannel> bc = new BroadcastChannel(global, aChannel, portUUID);
nsCOMPtr<nsIPrincipal> unpartitionedPrincipal;
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global); if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
// We are *intentionally* getting the unpartitioned principal here for // testing purposes, but the correct thing to do normally is to get the // storage key/principal. Passerby, do not imitate this code.
unpartitionedPrincipal = sop->GetPrincipal(); if (!unpartitionedPrincipal) {
aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr;
}
} else {
JSContext* cx = aGlobal.Context();
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)) {
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
// We are *intentionally* getting the unpartitioned principal here for // testing purposes, but the correct thing to do normally is to get the // storage key/principal. Passerby, do not imitate this code.
unpartitionedPrincipal = workerPrivate->GetPrincipal();
bc->mWorkerRef = workerRef;
}
// Register this component to PBackground.
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!actorChild)) { // Firefox is probably shutting down. Let's return a 'generic' error.
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
nsAutoCString origin;
aRv = unpartitionedPrincipal->GetOrigin(origin); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
nsString originForEvents;
aRv = nsContentUtils::GetWebExposedOriginSerialization(unpartitionedPrincipal,
originForEvents); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PrincipalInfo unpartitionedPrincipalInfo;
aRv = PrincipalToPrincipalInfo(unpartitionedPrincipal,
&unpartitionedPrincipalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PBroadcastChannelChild* actor = actorChild->SendPBroadcastChannelConstructor(
unpartitionedPrincipalInfo, origin, nsString(aChannel)); if (!actor) { // The PBackground actor is shutting down, return a 'generic' error.
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
// We want to allow opaque origins. if (!storagePrincipal->GetIsNullPrincipal() &&
(storageAccess == StorageAccess::eDeny ||
(ShouldPartitionStorage(storageAccess) &&
!StoragePartitioningEnabled(storageAccess, cjs)))) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr;
}
// Register this component to PBackground.
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!actorChild)) { // Firefox is probably shutting down. Let's return a 'generic' error.
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
nsAutoCString origin;
aRv = storagePrincipal->GetOrigin(origin); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
nsString originForEvents;
aRv = nsContentUtils::GetWebExposedOriginSerialization(storagePrincipal,
originForEvents); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PrincipalInfo storagePrincipalInfo;
aRv = PrincipalToPrincipalInfo(storagePrincipal, &storagePrincipalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PBroadcastChannelChild* actor = actorChild->SendPBroadcastChannelConstructor(
storagePrincipalInfo, origin, nsString(aChannel)); if (!actor) { // The PBackground actor is shutting down, return a 'generic' error.
aRv.Throw(NS_ERROR_FAILURE); return nullptr;
}
void BroadcastChannel::Close() { if (mState != StateActive) { return;
}
// 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.
mState = StateClosed;
RefPtr<CloseRunnable> runnable = new CloseRunnable(this);
if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
NS_WARNING("Failed to dispatch to the current thread!");
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.