/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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/. */
if (XRE_IsParentProcess() && aGlobal->PrincipalOrNull() &&
aGlobal->PrincipalOrNull()->IsSystemPrincipal()) {
clientID = Nothing();
principal = aGlobal->PrincipalOrNull();
} else {
Maybe<ClientInfo> clientInfo = aGlobal->GetClientInfo(); if (!clientInfo) { // Pass the nonworking object and let request()/query() throw. return;
}
principal = clientInfo->GetPrincipal().unwrapOr(nullptr); if (!principal) { return;
}
if (!principal->GetIsContentPrincipal()) { // Same, the methods will throw instead of the constructor. return;
}
clientID = Some(clientInfo->Id());
}
mozilla::ipc::PBackgroundChild* backgroundActor =
mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
mActor = new locks::LockManagerChild(aGlobal);
if (!backgroundActor->SendPLockManagerConstructor(
mActor, WrapNotNull(principal), clientID)) { // Failed to construct the actor. Pass the nonworking object and let the // methods throw.
mActor = nullptr; return;
}
}
already_AddRefed<LockManager> LockManager::Create(nsIGlobalObject& aGlobal) {
RefPtr<LockManager> manager = new LockManager(&aGlobal);
if (!NS_IsMainThread()) { // Grabbing WorkerRef may fail and that will cause the methods throw later.
manager->mWorkerRef =
WeakWorkerRef::Create(GetCurrentThreadWorkerPrivate(), [manager]() { // Others may grab a strong reference and block immediate destruction. // Shutdown early as we don't have to wait for them.
manager->Shutdown();
manager->mWorkerRef = nullptr;
}); // Do not handle the WeakWorkerRef creation fail here. // Suppose WorkerNavigator::Invalidate() should call LockManager::Shutdown() // before set WorkerNavigator::mLocks as nullptr.
}
return manager.forget();
}
staticbool ValidateRequestArguments(const nsAString& name, const LockOptions& options,
ErrorResult& aRv) { if (name.Length() > 0 && name.First() == u'-') {
aRv.ThrowNotSupportedError("Names starting with `-` are reserved"); returnfalse;
} if (options.mSteal) { if (options.mIfAvailable) {
aRv.ThrowNotSupportedError( "`steal` and `ifAvailable` cannot be used together"); returnfalse;
} if (options.mMode != LockMode::Exclusive) {
aRv.ThrowNotSupportedError( "`steal` is only supported for exclusive lock requests"); returnfalse;
}
} if (options.mSignal.WasPassed()) { if (options.mSteal) {
aRv.ThrowNotSupportedError( "`steal` and `signal` cannot be used together"); returnfalse;
} if (options.mIfAvailable) {
aRv.ThrowNotSupportedError( "`ifAvailable` and `signal` cannot be used together"); returnfalse;
} if (options.mSignal.Value().Aborted()) {
AutoJSAPI jsapi; if (!jsapi.Init(options.mSignal.Value().GetParentObject())) {
aRv.ThrowNotSupportedError("Signal's realm isn't active anymore."); returnfalse;
}
already_AddRefed<Promise> LockManager::Request(const nsAString& aName,
LockGrantedCallback& aCallback,
ErrorResult& aRv) { return Request(aName, LockOptions(), aCallback, aRv);
};
already_AddRefed<Promise> LockManager::Request(const nsAString& aName, const LockOptions& aOptions,
LockGrantedCallback& aCallback,
ErrorResult& aRv) { if (!mOwner->PrincipalOrNull() ||
!mOwner->PrincipalOrNull()->IsSystemPrincipal()) { if (!mOwner->GetClientInfo()) { // We do have nsPIDOMWindowInner::IsFullyActive for this kind of check, // but this should be sufficient here as unloaded iframe is the only // non-fully-active case that Web Locks should worry about (since it does // not enter bfcache).
aRv.ThrowInvalidStateError( "The document of the lock manager is not fully active"); return nullptr;
}
}
const StorageAccess access = mOwner->GetStorageAccess(); bool allowed =
access > StorageAccess::eDeny ||
(StaticPrefs::
privacy_partition_always_partition_third_party_non_cookie_storage() &&
ShouldPartitionStorage(access)); if (!allowed) { // Step 4: If origin is an opaque origin, then return a promise rejected // with a "SecurityError" DOMException. // But per https://w3c.github.io/web-locks/#lock-managers this really means // whether it has storage access.
aRv.ThrowSecurityError("request() is not allowed in this context"); return nullptr;
}
if (!mActor) {
aRv.ThrowNotSupportedError( "Web Locks API is not enabled for this kind of document"); return nullptr;
}
if (!NS_IsMainThread() && !mWorkerRef) {
aRv.ThrowInvalidStateError("request() is not allowed at this point"); return nullptr;
}
if (!ValidateRequestArguments(aName, aOptions, aRv)) { return nullptr;
}
already_AddRefed<Promise> LockManager::Query(ErrorResult& aRv) { if (!mOwner->PrincipalOrNull() ||
!mOwner->PrincipalOrNull()->IsSystemPrincipal()) { if (!mOwner->GetClientInfo()) {
aRv.ThrowInvalidStateError( "The document of the lock manager is not fully active"); return nullptr;
}
}
if (mOwner->GetStorageAccess() <= StorageAccess::eDeny) {
aRv.ThrowSecurityError("query() is not allowed in this context"); return nullptr;
}
if (!mActor) {
aRv.ThrowNotSupportedError( "Web Locks API is not enabled for this kind of document"); return nullptr;
}
if (!NS_IsMainThread() && !mWorkerRef) {
aRv.ThrowInvalidStateError("query() is not allowed at this point"); return nullptr;
}
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.