123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- /* -*- Mode: C++; tab-width: 8; 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 "ServiceWorkerManagerParent.h"
- #include "ServiceWorkerManagerService.h"
- #include "mozilla/AppProcessChecker.h"
- #include "mozilla/dom/ContentParent.h"
- #include "mozilla/dom/ServiceWorkerRegistrar.h"
- #include "mozilla/ipc/BackgroundParent.h"
- #include "mozilla/ipc/BackgroundUtils.h"
- #include "mozilla/Unused.h"
- #include "nsThreadUtils.h"
- namespace mozilla {
- using namespace ipc;
- namespace dom {
- namespace workers {
- namespace {
- uint64_t sServiceWorkerManagerParentID = 0;
- class RegisterServiceWorkerCallback final : public Runnable
- {
- public:
- RegisterServiceWorkerCallback(const ServiceWorkerRegistrationData& aData,
- uint64_t aParentID)
- : mData(aData)
- , mParentID(aParentID)
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- }
- NS_IMETHOD
- Run() override
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- RefPtr<dom::ServiceWorkerRegistrar> service =
- dom::ServiceWorkerRegistrar::Get();
- // Shutdown during the process of trying to update the registrar. Give
- // up on this modification.
- if (!service) {
- return NS_OK;
- }
- service->RegisterServiceWorker(mData);
- RefPtr<ServiceWorkerManagerService> managerService =
- ServiceWorkerManagerService::Get();
- if (managerService) {
- managerService->PropagateRegistration(mParentID, mData);
- }
- return NS_OK;
- }
- private:
- ServiceWorkerRegistrationData mData;
- const uint64_t mParentID;
- };
- class UnregisterServiceWorkerCallback final : public Runnable
- {
- public:
- UnregisterServiceWorkerCallback(const PrincipalInfo& aPrincipalInfo,
- const nsString& aScope,
- uint64_t aParentID)
- : mPrincipalInfo(aPrincipalInfo)
- , mScope(aScope)
- , mParentID(aParentID)
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- }
- NS_IMETHOD
- Run() override
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- RefPtr<dom::ServiceWorkerRegistrar> service =
- dom::ServiceWorkerRegistrar::Get();
- // Shutdown during the process of trying to update the registrar. Give
- // up on this modification.
- if (!service) {
- return NS_OK;
- }
- service->UnregisterServiceWorker(mPrincipalInfo,
- NS_ConvertUTF16toUTF8(mScope));
- RefPtr<ServiceWorkerManagerService> managerService =
- ServiceWorkerManagerService::Get();
- if (managerService) {
- managerService->PropagateUnregister(mParentID, mPrincipalInfo,
- mScope);
- }
- return NS_OK;
- }
- private:
- const PrincipalInfo mPrincipalInfo;
- nsString mScope;
- uint64_t mParentID;
- };
- class CheckPrincipalWithCallbackRunnable final : public Runnable
- {
- public:
- CheckPrincipalWithCallbackRunnable(already_AddRefed<ContentParent> aParent,
- const PrincipalInfo& aPrincipalInfo,
- Runnable* aCallback)
- : mContentParent(aParent)
- , mPrincipalInfo(aPrincipalInfo)
- , mCallback(aCallback)
- , mBackgroundThread(NS_GetCurrentThread())
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- MOZ_ASSERT(mContentParent);
- MOZ_ASSERT(mCallback);
- MOZ_ASSERT(mBackgroundThread);
- }
- NS_IMETHOD Run() override
- {
- if (NS_IsMainThread()) {
- nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(mPrincipalInfo);
- AssertAppPrincipal(mContentParent, principal);
- mContentParent = nullptr;
- mBackgroundThread->Dispatch(this, NS_DISPATCH_NORMAL);
- return NS_OK;
- }
- AssertIsOnBackgroundThread();
- mCallback->Run();
- mCallback = nullptr;
- return NS_OK;
- }
- private:
- RefPtr<ContentParent> mContentParent;
- PrincipalInfo mPrincipalInfo;
- RefPtr<Runnable> mCallback;
- nsCOMPtr<nsIThread> mBackgroundThread;
- };
- } // namespace
- ServiceWorkerManagerParent::ServiceWorkerManagerParent()
- : mService(ServiceWorkerManagerService::GetOrCreate())
- , mID(++sServiceWorkerManagerParentID)
- {
- AssertIsOnBackgroundThread();
- mService->RegisterActor(this);
- }
- ServiceWorkerManagerParent::~ServiceWorkerManagerParent()
- {
- AssertIsOnBackgroundThread();
- }
- bool
- ServiceWorkerManagerParent::RecvRegister(
- const ServiceWorkerRegistrationData& aData)
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- // Basic validation.
- if (aData.scope().IsEmpty() ||
- aData.principal().type() == PrincipalInfo::TNullPrincipalInfo ||
- aData.principal().type() == PrincipalInfo::TSystemPrincipalInfo) {
- return false;
- }
- RefPtr<RegisterServiceWorkerCallback> callback =
- new RegisterServiceWorkerCallback(aData, mID);
- RefPtr<ContentParent> parent =
- BackgroundParent::GetContentParent(Manager());
- // If the ContentParent is null we are dealing with a same-process actor.
- if (!parent) {
- callback->Run();
- return true;
- }
- RefPtr<CheckPrincipalWithCallbackRunnable> runnable =
- new CheckPrincipalWithCallbackRunnable(parent.forget(), aData.principal(),
- callback);
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvUnregister(const PrincipalInfo& aPrincipalInfo,
- const nsString& aScope)
- {
- AssertIsInMainProcess();
- AssertIsOnBackgroundThread();
- // Basic validation.
- if (aScope.IsEmpty() ||
- aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo ||
- aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
- return false;
- }
- RefPtr<UnregisterServiceWorkerCallback> callback =
- new UnregisterServiceWorkerCallback(aPrincipalInfo, aScope, mID);
- RefPtr<ContentParent> parent =
- BackgroundParent::GetContentParent(Manager());
- // If the ContentParent is null we are dealing with a same-process actor.
- if (!parent) {
- callback->Run();
- return true;
- }
- RefPtr<CheckPrincipalWithCallbackRunnable> runnable =
- new CheckPrincipalWithCallbackRunnable(parent.forget(), aPrincipalInfo,
- callback);
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
- const nsString& aScope)
- {
- AssertIsOnBackgroundThread();
- if (NS_WARN_IF(!mService)) {
- return false;
- }
- mService->PropagateSoftUpdate(mID, aOriginAttributes, aScope);
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
- const nsString& aScope)
- {
- AssertIsOnBackgroundThread();
- if (NS_WARN_IF(!mService)) {
- return false;
- }
- mService->PropagateUnregister(mID, aPrincipalInfo, aScope);
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvPropagateRemove(const nsCString& aHost)
- {
- AssertIsOnBackgroundThread();
- if (NS_WARN_IF(!mService)) {
- return false;
- }
- mService->PropagateRemove(mID, aHost);
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvPropagateRemoveAll()
- {
- AssertIsOnBackgroundThread();
- if (NS_WARN_IF(!mService)) {
- return false;
- }
- mService->PropagateRemoveAll(mID);
- return true;
- }
- bool
- ServiceWorkerManagerParent::RecvShutdown()
- {
- AssertIsOnBackgroundThread();
- if (NS_WARN_IF(!mService)) {
- return false;
- }
- mService->UnregisterActor(this);
- mService = nullptr;
- Unused << Send__delete__(this);
- return true;
- }
- void
- ServiceWorkerManagerParent::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);
- }
- }
- } // namespace workers
- } // namespace dom
- } // namespace mozilla
|