Files
palemoon27/dom/workers/ServiceWorkerWindowClient.cpp
T
roytam1 963b86a51f import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1175138 P1 Make the dom.caches.testing.enabled pref available in workers. r=ehsan (fe47d0e0a)
- Bug 1175138 P2 Expose dom.serviceWorkers.testing.enabled to workers. r=ehsan (efab5d0d3)
- Bug 1160458 - Part 1: Use the CSP of the principal passed to CreateServiceWorker. r=nsm (4d0a1d742)
- Bug 1172948 - Part 3: Add an explicit test case to ensure that authenticated origins that have a non-authenticated parent cannot register a service worker; r=nsm (78b3087c9)
- Bug 803537 - XHR crashes in workers and in debug-builds when blob URLs are used from file scheme documents, r=khuey (aa86f77b7)
- Bug 1163900 - crash in mozilla::net::nsHttpChannelCacheKey::GetData(unsigned int*, nsACString_internal&), r=jduell (adb5ddb01)
- Bug 1147746 - Null check mInterceptListener in HttpChannelChild::ResetInterception; r=jdm (4c8c4e630)
- Bug 1157283 - Recreate IPC redirected HTTP channels as necessary after intercepting the request in the child. r=mayhemer (3b144e45e)
- Bug 1172884 P1 Properly decode body when intercepted response redirects. r=jduell (f49c37d4f)
- Bug 1172884 P2 Add test for synthesizing a redirect to a compressed resource. r=ehsan (823d2122a)
- Bug 1160458 - Part 2: Test. r=nsm (02b9fb3a0)
- Bug 1169249 - Unregister service worker registration when uninstalling a service-worker-enabled application. Tests. r=baku (5509a19d6)
- Bug 1177621 - SharedWorkers should not be shared between a private and a non-private documents, r=nsm (0836234c7)
- Bug 1175138 P3 Expose the devtools SW testing flag on workers. r=ehsan (aade20454)
- Bug 1173467 P3 Pass private browsing flag into CacheStorage factory methods. r=ehsan (c4d062a80)
- Bug 1173467 P4 Add a test to validate Cache in private browsing window. r=ehsan (dde897e69)
- Bug 1162487 - Enable the dom.caches.enabled pref in test_chrome_constructor.html; r=baku (2c73e2929)
- Bug 1175138 P4 Enable dom.caches.testing.enabled in existing tests. r=ehsan (c453e03fb)
- Bug 1175138 P5 Make CacheStorage reject on untrusted origins. r=ehsan (c85424d4e)
- Bug 1175138 P6 Add a simple test to verify CacheStorage rejects in http origin. r=ehsan (5832eb99d)
- Bug 1179567 - Make ServiceWorker keep its document and window alive; r=baku (1ae847884)
- Bug 1179982 - Fix all compile errors in dom/workers on non-unified build. r=mrbkap (d30bece64)
2021-05-14 09:30:14 +08:00

161 lines
4.7 KiB
C++

/* -*- 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/.
*/
#include "ServiceWorkerWindowClient.h"
#include "mozilla/dom/ClientBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h"
#include "mozilla/UniquePtr.h"
#include "nsGlobalWindow.h"
#include "WorkerPrivate.h"
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
using mozilla::UniquePtr;
JSObject*
ServiceWorkerWindowClient::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return WindowClientBinding::Wrap(aCx, this, aGivenProto);
}
namespace {
// Passing a null clientInfo will reject the promise with InvalidAccessError.
class ResolveOrRejectPromiseRunnable final : public WorkerRunnable
{
nsRefPtr<PromiseWorkerProxy> mPromiseProxy;
UniquePtr<ServiceWorkerClientInfo> mClientInfo;
public:
ResolveOrRejectPromiseRunnable(WorkerPrivate* aWorkerPrivate,
PromiseWorkerProxy* aPromiseProxy,
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
, mPromiseProxy(aPromiseProxy)
, mClientInfo(Move(aClientInfo))
{
AssertIsOnMainThread();
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
Promise* promise = mPromiseProxy->GetWorkerPromise();
MOZ_ASSERT(promise);
if (mClientInfo) {
nsRefPtr<ServiceWorkerWindowClient> client =
new ServiceWorkerWindowClient(promise->GetParentObject(), *mClientInfo);
promise->MaybeResolve(client);
} else {
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
}
// Release the reference on the worker thread.
mPromiseProxy->CleanUp(aCx);
return true;
}
};
class ClientFocusRunnable final : public nsRunnable
{
uint64_t mWindowId;
nsRefPtr<PromiseWorkerProxy> mPromiseProxy;
public:
ClientFocusRunnable(uint64_t aWindowId, PromiseWorkerProxy* aPromiseProxy)
: mWindowId(aWindowId)
, mPromiseProxy(aPromiseProxy)
{
MOZ_ASSERT(mPromiseProxy);
MOZ_ASSERT(mPromiseProxy->GetWorkerPromise());
}
NS_IMETHOD
Run() override
{
AssertIsOnMainThread();
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
UniquePtr<ServiceWorkerClientInfo> clientInfo;
if (window) {
mozilla::ErrorResult result;
//FIXME(catalinb): Bug 1144660 - check if we are allowed to focus here.
window->Focus(result);
clientInfo.reset(new ServiceWorkerClientInfo(window->GetDocument(),
window->GetOuterWindow()));
}
DispatchResult(Move(clientInfo));
return NS_OK;
}
private:
void
DispatchResult(UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
{
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
MOZ_ASSERT(workerPrivate);
nsRefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable =
new ResolveOrRejectPromiseRunnable(workerPrivate, mPromiseProxy,
Move(aClientInfo));
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
if (!resolveRunnable->Dispatch(cx)) {
nsRefPtr<PromiseWorkerProxyControlRunnable> controlRunnable =
new PromiseWorkerProxyControlRunnable(workerPrivate, mPromiseProxy);
if (!controlRunnable->Dispatch(cx)) {
NS_RUNTIMEABORT("Failed to dispatch Focus promise control runnable.");
}
}
}
};
} // anonymous namespace
already_AddRefed<Promise>
ServiceWorkerWindowClient::Focus(ErrorResult& aRv) const
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
MOZ_ASSERT(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
nsRefPtr<PromiseWorkerProxy> promiseProxy =
PromiseWorkerProxy::Create(workerPrivate, promise);
if (!promiseProxy->GetWorkerPromise()) {
// Don't dispatch if adding the worker feature failed.
return promise.forget();
}
nsRefPtr<ClientFocusRunnable> r = new ClientFocusRunnable(mWindowId,
promiseProxy);
aRv = NS_DispatchToMainThread(r);
if (NS_WARN_IF(aRv.Failed())) {
promise->MaybeReject(aRv);
}
return promise.forget();
}