mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	This is part of removing [ManualDealloc] from all protocols which manage other protocols. Differential Revision: https://phabricator.services.mozilla.com/D198618
		
			
				
	
	
		
			1264 lines
		
	
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1264 lines
		
	
	
	
		
			34 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 "QuotaManagerService.h"
 | 
						|
 | 
						|
// Local includes
 | 
						|
#include "ActorsChild.h"
 | 
						|
#include "Client.h"
 | 
						|
#include "QuotaManager.h"
 | 
						|
#include "QuotaRequests.h"
 | 
						|
 | 
						|
// Global includes
 | 
						|
#include <cstdint>
 | 
						|
#include <cstring>
 | 
						|
#include <utility>
 | 
						|
#include "MainThreadUtils.h"
 | 
						|
#include "mozilla/Assertions.h"
 | 
						|
#include "mozilla/Atomics.h"
 | 
						|
#include "mozilla/ClearOnShutdown.h"
 | 
						|
#include "mozilla/Hal.h"
 | 
						|
#include "mozilla/MacroForEach.h"
 | 
						|
#include "mozilla/Maybe.h"
 | 
						|
#include "mozilla/OriginAttributes.h"
 | 
						|
#include "mozilla/RefPtr.h"
 | 
						|
#include "mozilla/Services.h"
 | 
						|
#include "mozilla/StaticPrefs_dom.h"
 | 
						|
#include "mozilla/StaticPtr.h"
 | 
						|
#include "mozilla/Unused.h"
 | 
						|
#include "mozilla/Variant.h"
 | 
						|
#include "mozilla/dom/quota/PQuota.h"
 | 
						|
#include "mozilla/dom/quota/PersistenceType.h"
 | 
						|
#include "mozilla/dom/quota/ResultExtensions.h"
 | 
						|
#include "mozilla/fallible.h"
 | 
						|
#include "mozilla/hal_sandbox/PHal.h"
 | 
						|
#include "mozilla/ipc/BackgroundChild.h"
 | 
						|
#include "mozilla/ipc/BackgroundUtils.h"
 | 
						|
#include "mozilla/ipc/PBackgroundChild.h"
 | 
						|
#include "mozilla/ipc/PBackgroundSharedTypes.h"
 | 
						|
#include "nsCOMPtr.h"
 | 
						|
#include "nsContentUtils.h"
 | 
						|
#include "nsDebug.h"
 | 
						|
#include "nsError.h"
 | 
						|
#include "nsIObserverService.h"
 | 
						|
#include "nsIPrincipal.h"
 | 
						|
#include "nsIUserIdleService.h"
 | 
						|
#include "nsServiceManagerUtils.h"
 | 
						|
#include "nsStringFwd.h"
 | 
						|
#include "nsVariant.h"
 | 
						|
#include "nsXULAppAPI.h"
 | 
						|
#include "nscore.h"
 | 
						|
 | 
						|
#define PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID "profile-before-change-qm"
 | 
						|
 | 
						|
namespace mozilla::dom::quota {
 | 
						|
 | 
						|
using namespace mozilla::ipc;
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
const char kIdleServiceContractId[] = "@mozilla.org/widget/useridleservice;1";
 | 
						|
 | 
						|
// The number of seconds we will wait after receiving the idle-daily
 | 
						|
// notification before beginning maintenance.
 | 
						|
const uint32_t kIdleObserverTimeSec = 1;
 | 
						|
 | 
						|
mozilla::StaticRefPtr<QuotaManagerService> gQuotaManagerService;
 | 
						|
 | 
						|
mozilla::Atomic<bool> gInitialized(false);
 | 
						|
mozilla::Atomic<bool> gClosed(false);
 | 
						|
 | 
						|
nsresult CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
 | 
						|
                                         PrincipalInfo& aPrincipalInfo) {
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(aPrincipalInfo))) {
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
 | 
						|
      aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
nsresult GetClearResetOriginParams(nsIPrincipal* aPrincipal,
 | 
						|
                                   const nsACString& aPersistenceType,
 | 
						|
                                   const nsAString& aClientType,
 | 
						|
                                   ClearResetOriginParams& aParams) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, aParams.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  if (aPersistenceType.IsVoid()) {
 | 
						|
    aParams.persistenceTypeIsExplicit() = false;
 | 
						|
  } else {
 | 
						|
    const auto maybePersistenceType =
 | 
						|
        PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
    if (NS_WARN_IF(maybePersistenceType.isNothing())) {
 | 
						|
      return NS_ERROR_INVALID_ARG;
 | 
						|
    }
 | 
						|
 | 
						|
    aParams.persistenceType() = maybePersistenceType.value();
 | 
						|
    aParams.persistenceTypeIsExplicit() = true;
 | 
						|
  }
 | 
						|
 | 
						|
  if (aClientType.IsVoid()) {
 | 
						|
    aParams.clientTypeIsExplicit() = false;
 | 
						|
  } else {
 | 
						|
    Client::Type clientType;
 | 
						|
    bool ok = Client::TypeFromText(aClientType, clientType, fallible);
 | 
						|
    if (NS_WARN_IF(!ok)) {
 | 
						|
      return NS_ERROR_INVALID_ARG;
 | 
						|
    }
 | 
						|
 | 
						|
    aParams.clientType() = clientType;
 | 
						|
    aParams.clientTypeIsExplicit() = true;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
class BoolResponsePromiseResolveOrRejectCallback {
 | 
						|
 public:
 | 
						|
  using PromiseType = BoolResponsePromise;
 | 
						|
  using RequestType = Request;
 | 
						|
 | 
						|
  explicit BoolResponsePromiseResolveOrRejectCallback(
 | 
						|
      RefPtr<RequestType> aRequest)
 | 
						|
      : mRequest(std::move(aRequest)) {}
 | 
						|
 | 
						|
  void operator()(const PromiseType::ResolveOrRejectValue& aValue) {
 | 
						|
    if (aValue.IsResolve()) {
 | 
						|
      const BoolResponse& response = aValue.ResolveValue();
 | 
						|
 | 
						|
      switch (response.type()) {
 | 
						|
        case BoolResponse::Tnsresult:
 | 
						|
          mRequest->SetError(response.get_nsresult());
 | 
						|
          break;
 | 
						|
 | 
						|
        case BoolResponse::Tbool: {
 | 
						|
          RefPtr<nsVariant> variant = new nsVariant();
 | 
						|
          variant->SetAsBool(response.get_bool());
 | 
						|
 | 
						|
          mRequest->SetResult(variant);
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
          MOZ_CRASH("Unknown response type!");
 | 
						|
      }
 | 
						|
 | 
						|
    } else {
 | 
						|
      mRequest->SetError(NS_ERROR_FAILURE);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  RefPtr<RequestType> mRequest;
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
class QuotaManagerService::PendingRequestInfo {
 | 
						|
 protected:
 | 
						|
  RefPtr<RequestBase> mRequest;
 | 
						|
 | 
						|
 public:
 | 
						|
  explicit PendingRequestInfo(RequestBase* aRequest) : mRequest(aRequest) {}
 | 
						|
 | 
						|
  virtual ~PendingRequestInfo() = default;
 | 
						|
 | 
						|
  RequestBase* GetRequest() const { return mRequest; }
 | 
						|
 | 
						|
  virtual nsresult InitiateRequest(QuotaChild* aActor) = 0;
 | 
						|
};
 | 
						|
 | 
						|
class QuotaManagerService::UsageRequestInfo : public PendingRequestInfo {
 | 
						|
  UsageRequestParams mParams;
 | 
						|
 | 
						|
 public:
 | 
						|
  UsageRequestInfo(UsageRequest* aRequest, const UsageRequestParams& aParams)
 | 
						|
      : PendingRequestInfo(aRequest), mParams(aParams) {
 | 
						|
    MOZ_ASSERT(aRequest);
 | 
						|
    MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
 | 
						|
  }
 | 
						|
 | 
						|
  virtual nsresult InitiateRequest(QuotaChild* aActor) override;
 | 
						|
};
 | 
						|
 | 
						|
class QuotaManagerService::RequestInfo : public PendingRequestInfo {
 | 
						|
  RequestParams mParams;
 | 
						|
 | 
						|
 public:
 | 
						|
  RequestInfo(Request* aRequest, const RequestParams& aParams)
 | 
						|
      : PendingRequestInfo(aRequest), mParams(aParams) {
 | 
						|
    MOZ_ASSERT(aRequest);
 | 
						|
    MOZ_ASSERT(aParams.type() != RequestParams::T__None);
 | 
						|
  }
 | 
						|
 | 
						|
  virtual nsresult InitiateRequest(QuotaChild* aActor) override;
 | 
						|
};
 | 
						|
 | 
						|
class QuotaManagerService::IdleMaintenanceInfo : public PendingRequestInfo {
 | 
						|
  const bool mStart;
 | 
						|
 | 
						|
 public:
 | 
						|
  explicit IdleMaintenanceInfo(bool aStart)
 | 
						|
      : PendingRequestInfo(nullptr), mStart(aStart) {}
 | 
						|
 | 
						|
  virtual nsresult InitiateRequest(QuotaChild* aActor) override;
 | 
						|
};
 | 
						|
 | 
						|
QuotaManagerService::QuotaManagerService()
 | 
						|
    : mBackgroundActor(nullptr),
 | 
						|
      mBackgroundActorFailed(false),
 | 
						|
      mIdleObserverRegistered(false) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
}
 | 
						|
 | 
						|
QuotaManagerService::~QuotaManagerService() {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(!mIdleObserverRegistered);
 | 
						|
}
 | 
						|
 | 
						|
// static
 | 
						|
QuotaManagerService* QuotaManagerService::GetOrCreate() {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (gClosed) {
 | 
						|
    MOZ_ASSERT(false, "Calling GetOrCreate() after shutdown!");
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!gQuotaManagerService) {
 | 
						|
    RefPtr<QuotaManagerService> instance(new QuotaManagerService());
 | 
						|
 | 
						|
    nsresult rv = instance->Init();
 | 
						|
    if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
      return nullptr;
 | 
						|
    }
 | 
						|
 | 
						|
    if (gInitialized.exchange(true)) {
 | 
						|
      MOZ_ASSERT(false, "Initialized more than once?!");
 | 
						|
    }
 | 
						|
 | 
						|
    gQuotaManagerService = instance;
 | 
						|
 | 
						|
    ClearOnShutdown(&gQuotaManagerService);
 | 
						|
  }
 | 
						|
 | 
						|
  return gQuotaManagerService;
 | 
						|
}
 | 
						|
 | 
						|
// static
 | 
						|
QuotaManagerService* QuotaManagerService::Get() {
 | 
						|
  // Does not return an owning reference.
 | 
						|
  return gQuotaManagerService;
 | 
						|
}
 | 
						|
 | 
						|
// static
 | 
						|
already_AddRefed<QuotaManagerService> QuotaManagerService::FactoryCreate() {
 | 
						|
  RefPtr<QuotaManagerService> quotaManagerService = GetOrCreate();
 | 
						|
  return quotaManagerService.forget();
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::ClearBackgroundActor() {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  mBackgroundActor = nullptr;
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::AbortOperationsForProcess(
 | 
						|
    ContentParentId aContentParentId) {
 | 
						|
  MOZ_ASSERT(XRE_IsParentProcess());
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  nsresult rv = EnsureBackgroundActor();
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (NS_WARN_IF(
 | 
						|
          !mBackgroundActor->SendAbortOperationsForProcess(aContentParentId))) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::Init() {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (XRE_IsParentProcess()) {
 | 
						|
    nsCOMPtr<nsIObserverService> observerService =
 | 
						|
        mozilla::services::GetObserverService();
 | 
						|
    if (NS_WARN_IF(!observerService)) {
 | 
						|
      return NS_ERROR_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
    nsresult rv = observerService->AddObserver(
 | 
						|
        this, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID, false);
 | 
						|
    if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
      return rv;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::Destroy() {
 | 
						|
  // Setting the closed flag prevents the service from being recreated.
 | 
						|
  // Don't set it though if there's no real instance created.
 | 
						|
  if (gInitialized && gClosed.exchange(true)) {
 | 
						|
    MOZ_ASSERT(false, "Shutdown more than once?!");
 | 
						|
  }
 | 
						|
 | 
						|
  delete this;
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::EnsureBackgroundActor() {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  // Nothing can be done here if we have previously failed to create a
 | 
						|
  // background actor.
 | 
						|
  if (mBackgroundActorFailed) {
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!mBackgroundActor) {
 | 
						|
    PBackgroundChild* backgroundActor =
 | 
						|
        BackgroundChild::GetOrCreateForCurrentThread();
 | 
						|
    if (NS_WARN_IF(!backgroundActor)) {
 | 
						|
      mBackgroundActorFailed = true;
 | 
						|
      return NS_ERROR_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
    {
 | 
						|
      RefPtr<QuotaChild> actor = new QuotaChild(this);
 | 
						|
 | 
						|
      mBackgroundActor = static_cast<QuotaChild*>(
 | 
						|
          backgroundActor->SendPQuotaConstructor(actor));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!mBackgroundActor) {
 | 
						|
    mBackgroundActorFailed = true;
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::InitiateRequest(PendingRequestInfo& aInfo) {
 | 
						|
  nsresult rv = EnsureBackgroundActor();
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  rv = aInfo.InitiateRequest(mBackgroundActor);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::PerformIdleMaintenance() {
 | 
						|
  using namespace mozilla::hal;
 | 
						|
 | 
						|
  MOZ_ASSERT(XRE_IsParentProcess());
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  // If we're running on battery power then skip all idle maintenance since we
 | 
						|
  // would otherwise be doing lots of disk I/O.
 | 
						|
  BatteryInformation batteryInfo;
 | 
						|
 | 
						|
#ifdef MOZ_WIDGET_ANDROID
 | 
						|
  // Android XPCShell doesn't load the AndroidBridge that is needed to make
 | 
						|
  // GetCurrentBatteryInformation work...
 | 
						|
  if (!QuotaManager::IsRunningXPCShellTests())
 | 
						|
#endif
 | 
						|
  {
 | 
						|
    // In order to give the correct battery level, hal must have registered
 | 
						|
    // battery observers.
 | 
						|
    RegisterBatteryObserver(this);
 | 
						|
    GetCurrentBatteryInformation(&batteryInfo);
 | 
						|
    UnregisterBatteryObserver(this);
 | 
						|
  }
 | 
						|
 | 
						|
  // If we're running XPCShell because we always want to be able to test this
 | 
						|
  // code so pretend that we're always charging.
 | 
						|
  if (QuotaManager::IsRunningXPCShellTests()) {
 | 
						|
    batteryInfo.level() = 100;
 | 
						|
    batteryInfo.charging() = true;
 | 
						|
  }
 | 
						|
 | 
						|
  if (NS_WARN_IF(!batteryInfo.charging())) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuotaManager::IsRunningXPCShellTests()) {
 | 
						|
    // We don't want user activity to impact this code if we're running tests.
 | 
						|
    Unused << Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
 | 
						|
  } else if (!mIdleObserverRegistered) {
 | 
						|
    nsCOMPtr<nsIUserIdleService> idleService =
 | 
						|
        do_GetService(kIdleServiceContractId);
 | 
						|
    MOZ_ASSERT(idleService);
 | 
						|
 | 
						|
    MOZ_ALWAYS_SUCCEEDS(
 | 
						|
        idleService->AddIdleObserver(this, kIdleObserverTimeSec));
 | 
						|
 | 
						|
    mIdleObserverRegistered = true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::RemoveIdleObserver() {
 | 
						|
  MOZ_ASSERT(XRE_IsParentProcess());
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (mIdleObserverRegistered) {
 | 
						|
    nsCOMPtr<nsIUserIdleService> idleService =
 | 
						|
        do_GetService(kIdleServiceContractId);
 | 
						|
    MOZ_ASSERT(idleService);
 | 
						|
 | 
						|
    // Ignore the return value of RemoveIdleObserver, it may fail if the
 | 
						|
    // observer has already been unregistered during shutdown.
 | 
						|
    Unused << idleService->RemoveIdleObserver(this, kIdleObserverTimeSec);
 | 
						|
 | 
						|
    mIdleObserverRegistered = false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
NS_IMPL_ADDREF(QuotaManagerService)
 | 
						|
NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
 | 
						|
NS_IMPL_QUERY_INTERFACE(QuotaManagerService, nsIQuotaManagerService,
 | 
						|
                        nsIObserver)
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::StorageName(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  StorageNameParams params;
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  nsresult rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::StorageInitialized(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendStorageInitialized()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::TemporaryStorageInitialized(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendTemporaryStorageInitialized()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Init(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendInitializeStorage()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::InitTemporaryStorage(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendInitializeTemporaryStorage()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::InitializePersistentOrigin(nsIPrincipal* aPrincipal,
 | 
						|
                                                nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  InitializePersistentOriginParams params;
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::InitializeTemporaryOrigin(
 | 
						|
    const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
 | 
						|
    nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  InitializeTemporaryOriginParams params;
 | 
						|
 | 
						|
  const auto maybePersistenceType =
 | 
						|
      PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
  if (NS_WARN_IF(maybePersistenceType.isNothing())) {
 | 
						|
    return NS_ERROR_INVALID_ARG;
 | 
						|
  }
 | 
						|
 | 
						|
  if (NS_WARN_IF(!IsBestEffortPersistenceType(maybePersistenceType.value()))) {
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  params.persistenceType() = maybePersistenceType.value();
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::InitializePersistentClient(nsIPrincipal* aPrincipal,
 | 
						|
                                                const nsAString& aClientType,
 | 
						|
                                                nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
 | 
						|
         NS_ERROR_UNEXPECTED);
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& principalInfo,
 | 
						|
      ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
 | 
						|
        PrincipalInfo principalInfo;
 | 
						|
        QM_TRY(MOZ_TO_RESULT(
 | 
						|
            PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
 | 
						|
 | 
						|
        QM_TRY(MOZ_TO_RESULT(QuotaManager::IsPrincipalInfoValid(principalInfo)),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return principalInfo;
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(const auto& clientType,
 | 
						|
                 ([&aClientType]() -> Result<Client::Type, nsresult> {
 | 
						|
                   Client::Type clientType;
 | 
						|
                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
 | 
						|
                              aClientType, clientType, fallible)),
 | 
						|
                          Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
                   return clientType;
 | 
						|
                 }()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendInitializePersistentClient(principalInfo, clientType)
 | 
						|
      ->Then(GetCurrentSerialEventTarget(), __func__,
 | 
						|
             BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::InitializeTemporaryClient(
 | 
						|
    const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
 | 
						|
    const nsAString& aClientType, nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
 | 
						|
         NS_ERROR_UNEXPECTED);
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& persistenceType,
 | 
						|
      ([&aPersistenceType]() -> Result<PersistenceType, nsresult> {
 | 
						|
        const auto persistenceType =
 | 
						|
            PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        QM_TRY(
 | 
						|
            MOZ_TO_RESULT(IsBestEffortPersistenceType(persistenceType.ref())),
 | 
						|
            Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return persistenceType.ref();
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& principalInfo,
 | 
						|
      ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
 | 
						|
        PrincipalInfo principalInfo;
 | 
						|
        QM_TRY(MOZ_TO_RESULT(
 | 
						|
            PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
 | 
						|
 | 
						|
        QM_TRY(MOZ_TO_RESULT(QuotaManager::IsPrincipalInfoValid(principalInfo)),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return principalInfo;
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(const auto& clientType,
 | 
						|
                 ([&aClientType]() -> Result<Client::Type, nsresult> {
 | 
						|
                   Client::Type clientType;
 | 
						|
                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
 | 
						|
                              aClientType, clientType, fallible)),
 | 
						|
                          Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
                   return clientType;
 | 
						|
                 }()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor
 | 
						|
      ->SendInitializeTemporaryClient(persistenceType, principalInfo,
 | 
						|
                                      clientType)
 | 
						|
      ->Then(GetCurrentSerialEventTarget(), __func__,
 | 
						|
             BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::GetFullOriginMetadata(const nsACString& aPersistenceType,
 | 
						|
                                           nsIPrincipal* aPrincipal,
 | 
						|
                                           nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 | 
						|
 | 
						|
  QM_TRY(OkIf(StaticPrefs::dom_quotaManager_testing()), NS_ERROR_UNEXPECTED);
 | 
						|
 | 
						|
  const auto maybePersistenceType =
 | 
						|
      PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
  QM_TRY(OkIf(maybePersistenceType.isSome()), NS_ERROR_INVALID_ARG);
 | 
						|
  QM_TRY(OkIf(IsBestEffortPersistenceType(*maybePersistenceType)),
 | 
						|
         NS_ERROR_INVALID_ARG);
 | 
						|
 | 
						|
  PrincipalInfo principalInfo;
 | 
						|
  QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
 | 
						|
  QM_TRY(OkIf(QuotaManager::IsPrincipalInfoValid(principalInfo)),
 | 
						|
         NS_ERROR_INVALID_ARG);
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  GetFullOriginMetadataParams params;
 | 
						|
 | 
						|
  params.persistenceType() = *maybePersistenceType;
 | 
						|
  params.principalInfo() = std::move(principalInfo);
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(InitiateRequest(info)));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback, bool aGetAll,
 | 
						|
                              nsIQuotaUsageRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aCallback);
 | 
						|
 | 
						|
  RefPtr<UsageRequest> request = new UsageRequest(aCallback);
 | 
						|
 | 
						|
  AllUsageParams params;
 | 
						|
 | 
						|
  params.getAll() = aGetAll;
 | 
						|
 | 
						|
  UsageRequestInfo info(request, params);
 | 
						|
 | 
						|
  nsresult rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
 | 
						|
                                          nsIQuotaUsageCallback* aCallback,
 | 
						|
                                          bool aFromMemory,
 | 
						|
                                          nsIQuotaUsageRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
  MOZ_ASSERT(aCallback);
 | 
						|
 | 
						|
  RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
 | 
						|
 | 
						|
  OriginUsageParams params;
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  params.fromMemory() = aFromMemory;
 | 
						|
 | 
						|
  UsageRequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Clear(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendClearStorage()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ClearStoragesForPrivateBrowsing(
 | 
						|
    nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendClearStoragesForPrivateBrowsing()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ClearStoragesForOriginAttributesPattern(
 | 
						|
    const nsAString& aPattern, nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  OriginAttributesPattern pattern;
 | 
						|
  MOZ_ALWAYS_TRUE(pattern.Init(aPattern));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendClearStoragesForOriginAttributesPattern(pattern)->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ClearStoragesForPrincipal(
 | 
						|
    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
 | 
						|
    const nsAString& aClientType, nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& persistenceType,
 | 
						|
      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
 | 
						|
        if (aPersistenceType.IsVoid()) {
 | 
						|
          return Maybe<PersistenceType>();
 | 
						|
        }
 | 
						|
 | 
						|
        const auto persistenceType =
 | 
						|
            PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return persistenceType;
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& principalInfo,
 | 
						|
      ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
 | 
						|
        PrincipalInfo principalInfo;
 | 
						|
        QM_TRY(MOZ_TO_RESULT(
 | 
						|
            PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
 | 
						|
 | 
						|
        QM_TRY(MOZ_TO_RESULT(QuotaManager::IsPrincipalInfoValid(principalInfo)),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return principalInfo;
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(const auto& clientType,
 | 
						|
                 ([&aClientType]() -> Result<Maybe<Client::Type>, nsresult> {
 | 
						|
                   if (aClientType.IsVoid()) {
 | 
						|
                     return Maybe<Client::Type>();
 | 
						|
                   }
 | 
						|
 | 
						|
                   Client::Type clientType;
 | 
						|
                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
 | 
						|
                              aClientType, clientType, fallible)),
 | 
						|
                          Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
                   return Some(clientType);
 | 
						|
                 }()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor
 | 
						|
      ->SendClearStoragesForOrigin(persistenceType, principalInfo, clientType)
 | 
						|
      ->Then(GetCurrentSerialEventTarget(), __func__,
 | 
						|
             BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ClearStoragesForOriginPrefix(
 | 
						|
    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
 | 
						|
    nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& persistenceType,
 | 
						|
      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
 | 
						|
        if (aPersistenceType.IsVoid()) {
 | 
						|
          return Maybe<PersistenceType>();
 | 
						|
        }
 | 
						|
 | 
						|
        const auto persistenceType =
 | 
						|
            PersistenceTypeFromString(aPersistenceType, fallible);
 | 
						|
        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        return persistenceType;
 | 
						|
      }()));
 | 
						|
 | 
						|
  QM_TRY_INSPECT(
 | 
						|
      const auto& principalInfo,
 | 
						|
      ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
 | 
						|
        PrincipalInfo principalInfo;
 | 
						|
        QM_TRY(MOZ_TO_RESULT(
 | 
						|
            PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
 | 
						|
 | 
						|
        QM_TRY(MOZ_TO_RESULT(QuotaManager::IsPrincipalInfoValid(principalInfo)),
 | 
						|
               Err(NS_ERROR_INVALID_ARG));
 | 
						|
 | 
						|
        if (principalInfo.type() == PrincipalInfo::TContentPrincipalInfo) {
 | 
						|
          nsCString suffix;
 | 
						|
          principalInfo.get_ContentPrincipalInfo().attrs().CreateSuffix(suffix);
 | 
						|
 | 
						|
          QM_TRY(MOZ_TO_RESULT(suffix.IsEmpty()), Err(NS_ERROR_INVALID_ARG));
 | 
						|
        }
 | 
						|
 | 
						|
        return principalInfo;
 | 
						|
      }()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor
 | 
						|
      ->SendClearStoragesForOriginPrefix(persistenceType, principalInfo)
 | 
						|
      ->Then(GetCurrentSerialEventTarget(), __func__,
 | 
						|
             BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Reset(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  mBackgroundActor->SendShutdownStorage()->Then(
 | 
						|
      GetCurrentSerialEventTarget(), __func__,
 | 
						|
      BoolResponsePromiseResolveOrRejectCallback(request));
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ResetStoragesForPrincipal(
 | 
						|
    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
 | 
						|
    const nsAString& aClientType, nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
 | 
						|
    return NS_ERROR_UNEXPECTED;
 | 
						|
  }
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request(aPrincipal);
 | 
						|
 | 
						|
  ClearResetOriginParams commonParams;
 | 
						|
 | 
						|
  nsresult rv = GetClearResetOriginParams(aPrincipal, aPersistenceType,
 | 
						|
                                          aClientType, commonParams);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestParams params;
 | 
						|
  params = ResetOriginParams(commonParams);
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Persisted(nsIPrincipal* aPrincipal,
 | 
						|
                               nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
  MOZ_ASSERT(_retval);
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request(aPrincipal);
 | 
						|
 | 
						|
  PersistedParams params;
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Persist(nsIPrincipal* aPrincipal,
 | 
						|
                             nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
  MOZ_ASSERT(_retval);
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request(aPrincipal);
 | 
						|
 | 
						|
  PersistParams params;
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Estimate(nsIPrincipal* aPrincipal,
 | 
						|
                              nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
  MOZ_ASSERT(aPrincipal);
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request(aPrincipal);
 | 
						|
 | 
						|
  EstimateParams params;
 | 
						|
 | 
						|
  nsresult rv =
 | 
						|
      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::ListOrigins(nsIQuotaRequest** _retval) {
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  RefPtr<Request> request = new Request();
 | 
						|
 | 
						|
  ListOriginsParams params;
 | 
						|
 | 
						|
  RequestInfo info(request, params);
 | 
						|
 | 
						|
  nsresult rv = InitiateRequest(info);
 | 
						|
  if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
    return rv;
 | 
						|
  }
 | 
						|
 | 
						|
  request.forget(_retval);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
QuotaManagerService::Observe(nsISupports* aSubject, const char* aTopic,
 | 
						|
                             const char16_t* aData) {
 | 
						|
  MOZ_ASSERT(XRE_IsParentProcess());
 | 
						|
  MOZ_ASSERT(NS_IsMainThread());
 | 
						|
 | 
						|
  if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID)) {
 | 
						|
    RemoveIdleObserver();
 | 
						|
    return NS_OK;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
 | 
						|
    PerformIdleMaintenance();
 | 
						|
    return NS_OK;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
 | 
						|
    IdleMaintenanceInfo info(/* aStart */ true);
 | 
						|
 | 
						|
    nsresult rv = InitiateRequest(info);
 | 
						|
    if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
      return rv;
 | 
						|
    }
 | 
						|
 | 
						|
    return NS_OK;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!strcmp(aTopic, OBSERVER_TOPIC_ACTIVE)) {
 | 
						|
    RemoveIdleObserver();
 | 
						|
 | 
						|
    IdleMaintenanceInfo info(/* aStart */ false);
 | 
						|
 | 
						|
    nsresult rv = InitiateRequest(info);
 | 
						|
    if (NS_WARN_IF(NS_FAILED(rv))) {
 | 
						|
      return rv;
 | 
						|
    }
 | 
						|
 | 
						|
    return NS_OK;
 | 
						|
  }
 | 
						|
 | 
						|
  MOZ_ASSERT_UNREACHABLE("Should never get here!");
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
void QuotaManagerService::Notify(const hal::BatteryInformation& aBatteryInfo) {
 | 
						|
  // This notification is received when battery data changes. We don't need to
 | 
						|
  // deal with this notification.
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::UsageRequestInfo::InitiateRequest(
 | 
						|
    QuotaChild* aActor) {
 | 
						|
  MOZ_ASSERT(aActor);
 | 
						|
 | 
						|
  auto request = static_cast<UsageRequest*>(mRequest.get());
 | 
						|
 | 
						|
  auto actor = new QuotaUsageRequestChild(request);
 | 
						|
 | 
						|
  if (!aActor->SendPQuotaUsageRequestConstructor(actor, mParams)) {
 | 
						|
    request->SetError(NS_ERROR_FAILURE);
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  request->SetBackgroundActor(actor);
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::RequestInfo::InitiateRequest(QuotaChild* aActor) {
 | 
						|
  MOZ_ASSERT(aActor);
 | 
						|
 | 
						|
  auto request = static_cast<Request*>(mRequest.get());
 | 
						|
 | 
						|
  auto actor = new QuotaRequestChild(request);
 | 
						|
 | 
						|
  if (!aActor->SendPQuotaRequestConstructor(actor, mParams)) {
 | 
						|
    request->SetError(NS_ERROR_FAILURE);
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
nsresult QuotaManagerService::IdleMaintenanceInfo::InitiateRequest(
 | 
						|
    QuotaChild* aActor) {
 | 
						|
  MOZ_ASSERT(aActor);
 | 
						|
 | 
						|
  bool result;
 | 
						|
 | 
						|
  if (mStart) {
 | 
						|
    result = aActor->SendStartIdleMaintenance();
 | 
						|
  } else {
 | 
						|
    result = aActor->SendStopIdleMaintenance();
 | 
						|
  }
 | 
						|
 | 
						|
  if (!result) {
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
  }
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace mozilla::dom::quota
 |