tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

QuotaManagerService.cpp (52236B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "QuotaManagerService.h"
      8 
      9 // Local includes
     10 #include "ActorsChild.h"
     11 #include "Client.h"
     12 #include "QuotaManager.h"
     13 #include "QuotaRequests.h"
     14 #include "QuotaResults.h"
     15 
     16 // Global includes
     17 #include <cstdint>
     18 #include <cstring>
     19 #include <utility>
     20 
     21 #include "MainThreadUtils.h"
     22 #include "mozilla/Assertions.h"
     23 #include "mozilla/Atomics.h"
     24 #include "mozilla/ClearOnShutdown.h"
     25 #include "mozilla/Hal.h"
     26 #include "mozilla/Maybe.h"
     27 #include "mozilla/OriginAttributes.h"
     28 #include "mozilla/RefPtr.h"
     29 #include "mozilla/Services.h"
     30 #include "mozilla/StaticPrefs_dom.h"
     31 #include "mozilla/StaticPtr.h"
     32 #include "mozilla/dom/quota/PQuota.h"
     33 #include "mozilla/dom/quota/PersistenceType.h"
     34 #include "mozilla/dom/quota/PrincipalUtils.h"
     35 #include "mozilla/dom/quota/QuotaUsageRequestChild.h"
     36 #include "mozilla/dom/quota/ResultExtensions.h"
     37 #include "mozilla/fallible.h"
     38 #include "mozilla/hal_sandbox/PHal.h"
     39 #include "mozilla/ipc/BackgroundChild.h"
     40 #include "mozilla/ipc/BackgroundUtils.h"
     41 #include "mozilla/ipc/Endpoint.h"
     42 #include "mozilla/ipc/PBackgroundChild.h"
     43 #include "mozilla/ipc/PBackgroundSharedTypes.h"
     44 #include "nsCOMPtr.h"
     45 #include "nsContentUtils.h"
     46 #include "nsDebug.h"
     47 #include "nsError.h"
     48 #include "nsIObserverService.h"
     49 #include "nsIPrincipal.h"
     50 #include "nsIUserIdleService.h"
     51 #include "nsServiceManagerUtils.h"
     52 #include "nsStringFwd.h"
     53 #include "nsVariant.h"
     54 #include "nsXULAppAPI.h"
     55 #include "nscore.h"
     56 
     57 #define PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID "profile-before-change-qm"
     58 
     59 namespace mozilla::dom::quota {
     60 
     61 using namespace mozilla::ipc;
     62 
     63 namespace {
     64 
     65 const char kIdleServiceContractId[] = "@mozilla.org/widget/useridleservice;1";
     66 
     67 // The number of seconds we will wait after receiving the idle-daily
     68 // notification before beginning maintenance.
     69 const uint32_t kIdleObserverTimeSec = 1;
     70 
     71 mozilla::StaticRefPtr<QuotaManagerService> gQuotaManagerService;
     72 
     73 mozilla::Atomic<bool> gInitialized(false);
     74 mozilla::Atomic<bool> gClosed(false);
     75 
     76 nsresult CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
     77                                         PrincipalInfo& aPrincipalInfo) {
     78  MOZ_ASSERT(aPrincipal);
     79 
     80  nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
     81  if (NS_WARN_IF(NS_FAILED(rv))) {
     82    return rv;
     83  }
     84 
     85  if (NS_WARN_IF(!IsPrincipalInfoValid(aPrincipalInfo))) {
     86    return NS_ERROR_FAILURE;
     87  }
     88 
     89  if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
     90      aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
     91    return NS_ERROR_UNEXPECTED;
     92  }
     93 
     94  return NS_OK;
     95 }
     96 
     97 template <typename ResponseType>
     98 struct ResponseTypeTraits;
     99 
    100 template <>
    101 struct ResponseTypeTraits<BoolResponse> {
    102  static constexpr auto kType = BoolResponse::Tbool;
    103 
    104  static RefPtr<nsVariant> CreateVariant(const BoolResponse& aResponse) {
    105    auto variant = MakeRefPtr<nsVariant>();
    106    variant->SetAsBool(aResponse.get_bool());
    107    return variant;
    108  }
    109 };
    110 
    111 template <>
    112 struct ResponseTypeTraits<UInt64Response> {
    113  static constexpr auto kType = UInt64Response::Tuint64_t;
    114 
    115  static RefPtr<nsVariant> CreateVariant(const UInt64Response& aResponse) {
    116    RefPtr<nsVariant> variant = new nsVariant();
    117    variant->SetAsUint64(aResponse.get_uint64_t());
    118    return variant;
    119  }
    120 };
    121 
    122 template <>
    123 struct ResponseTypeTraits<CStringArrayResponse> {
    124  static constexpr auto kType = CStringArrayResponse::TArrayOfnsCString;
    125 
    126  static RefPtr<nsVariant> CreateVariant(
    127      const CStringArrayResponse& aResponse) {
    128    const CStringArray& strings = aResponse.get_ArrayOfnsCString();
    129 
    130    auto variant = MakeRefPtr<nsVariant>();
    131 
    132    if (strings.IsEmpty()) {
    133      MOZ_ALWAYS_SUCCEEDS(variant->SetAsEmptyArray());
    134    } else {
    135      nsTArray<const char*> stringPointers(strings.Length());
    136 
    137      std::transform(strings.cbegin(), strings.cend(),
    138                     MakeBackInserter(stringPointers),
    139                     std::mem_fn(&nsCString::get));
    140 
    141      QM_TRY(MOZ_TO_RESULT(variant->SetAsArray(
    142                 nsIDataType::VTYPE_CHAR_STR, /* aIID */ nullptr,
    143                 stringPointers.Length(), stringPointers.Elements())),
    144             nullptr);
    145    }
    146 
    147    return variant;
    148  }
    149 };
    150 
    151 template <>
    152 struct ResponseTypeTraits<OriginUsageMetadataArrayResponse> {
    153  static constexpr auto kType =
    154      OriginUsageMetadataArrayResponse::TOriginUsageMetadataArray;
    155 
    156  static RefPtr<nsVariant> CreateVariant(
    157      const OriginUsageMetadataArrayResponse& aResponse) {
    158    const OriginUsageMetadataArray& originUsages =
    159        aResponse.get_OriginUsageMetadataArray();
    160 
    161    auto variant = MakeRefPtr<nsVariant>();
    162 
    163    if (originUsages.IsEmpty()) {
    164      variant->SetAsEmptyArray();
    165    } else {
    166      nsTArray<RefPtr<UsageResult>> usageResults(originUsages.Length());
    167 
    168      for (const auto& originUsage : originUsages) {
    169        usageResults.AppendElement(MakeRefPtr<UsageResult>(
    170            originUsage.mOrigin, originUsage.mPersisted, originUsage.mUsage,
    171            originUsage.mLastAccessTime));
    172      }
    173 
    174      variant->SetAsArray(
    175          nsIDataType::VTYPE_INTERFACE_IS, &NS_GET_IID(nsIQuotaUsageResult),
    176          usageResults.Length(), static_cast<void*>(usageResults.Elements()));
    177    }
    178 
    179    return variant;
    180  }
    181 };
    182 
    183 template <>
    184 struct ResponseTypeTraits<UsageInfoResponse> {
    185  static constexpr auto kType = UsageInfoResponse::TUsageInfo;
    186 
    187  static RefPtr<nsVariant> CreateVariant(const UsageInfoResponse& aResponse) {
    188    RefPtr<OriginUsageResult> result =
    189        new OriginUsageResult(aResponse.get_UsageInfo());
    190 
    191    auto variant = MakeRefPtr<nsVariant>();
    192    variant->SetAsInterface(NS_GET_IID(nsIQuotaOriginUsageResult), result);
    193 
    194    return variant;
    195  }
    196 };
    197 
    198 template <typename RequestType, typename PromiseType, typename ResponseType>
    199 class ResponsePromiseResolveOrRejectCallback {
    200 public:
    201  explicit ResponsePromiseResolveOrRejectCallback(RefPtr<RequestType> aRequest)
    202      : mRequest(std::move(aRequest)) {}
    203 
    204  void operator()(const typename PromiseType::ResolveOrRejectValue& aValue) {
    205    if (aValue.IsResolve()) {
    206      const ResponseType& response = aValue.ResolveValue();
    207 
    208      switch (response.type()) {
    209        case ResponseType::Tnsresult:
    210          mRequest->SetError(response.get_nsresult());
    211          break;
    212 
    213        case ResponseTypeTraits<ResponseType>::kType: {
    214          RefPtr<nsVariant> variant =
    215              ResponseTypeTraits<ResponseType>::CreateVariant(response);
    216 
    217          if (variant) {
    218            mRequest->SetResult(variant);
    219          } else {
    220            mRequest->SetError(NS_ERROR_FAILURE);
    221          }
    222          break;
    223        }
    224        default:
    225          MOZ_CRASH("Unknown response type!");
    226      }
    227 
    228    } else {
    229      mRequest->SetError(NS_ERROR_FAILURE);
    230    }
    231  }
    232 
    233 private:
    234  RefPtr<RequestType> mRequest;
    235 };
    236 
    237 using BoolResponsePromiseResolveOrRejectCallback =
    238    ResponsePromiseResolveOrRejectCallback<Request, BoolResponsePromise,
    239                                           BoolResponse>;
    240 using UInt64ResponsePromiseResolveOrRejectCallback =
    241    ResponsePromiseResolveOrRejectCallback<Request, UInt64ResponsePromise,
    242                                           UInt64Response>;
    243 using CStringArrayResponsePromiseResolveOrRejectCallback =
    244    ResponsePromiseResolveOrRejectCallback<Request, CStringArrayResponsePromise,
    245                                           CStringArrayResponse>;
    246 using OriginUsageMetadataArrayResponsePromiseResolveOrRejectCallback =
    247    ResponsePromiseResolveOrRejectCallback<
    248        UsageRequest, OriginUsageMetadataArrayResponsePromise,
    249        OriginUsageMetadataArrayResponse>;
    250 using UsageInfoResponsePromiseResolveOrRejectCallback =
    251    ResponsePromiseResolveOrRejectCallback<
    252        UsageRequest, UsageInfoResponsePromise, UsageInfoResponse>;
    253 
    254 }  // namespace
    255 
    256 class QuotaManagerService::PendingRequestInfo {
    257 protected:
    258  RefPtr<RequestBase> mRequest;
    259 
    260 public:
    261  explicit PendingRequestInfo(RequestBase* aRequest) : mRequest(aRequest) {}
    262 
    263  virtual ~PendingRequestInfo() = default;
    264 
    265  RequestBase* GetRequest() const { return mRequest; }
    266 
    267  virtual nsresult InitiateRequest(QuotaChild* aActor) = 0;
    268 };
    269 
    270 class QuotaManagerService::RequestInfo : public PendingRequestInfo {
    271  RequestParams mParams;
    272 
    273 public:
    274  RequestInfo(Request* aRequest, const RequestParams& aParams)
    275      : PendingRequestInfo(aRequest), mParams(aParams) {
    276    MOZ_ASSERT(aRequest);
    277    MOZ_ASSERT(aParams.type() != RequestParams::T__None);
    278  }
    279 
    280  virtual nsresult InitiateRequest(QuotaChild* aActor) override;
    281 };
    282 
    283 class QuotaManagerService::IdleMaintenanceInfo : public PendingRequestInfo {
    284  const bool mStart;
    285 
    286 public:
    287  explicit IdleMaintenanceInfo(bool aStart)
    288      : PendingRequestInfo(nullptr), mStart(aStart) {}
    289 
    290  virtual nsresult InitiateRequest(QuotaChild* aActor) override;
    291 };
    292 
    293 QuotaManagerService::QuotaManagerService()
    294    : mBackgroundActor(nullptr),
    295      mBackgroundActorFailed(false),
    296      mIdleObserverRegistered(false) {
    297  MOZ_ASSERT(NS_IsMainThread());
    298 }
    299 
    300 QuotaManagerService::~QuotaManagerService() {
    301  MOZ_ASSERT(NS_IsMainThread());
    302  MOZ_ASSERT(!mIdleObserverRegistered);
    303 }
    304 
    305 // static
    306 QuotaManagerService* QuotaManagerService::GetOrCreate() {
    307  MOZ_ASSERT(NS_IsMainThread());
    308 
    309  if (gClosed) {
    310    MOZ_ASSERT(false, "Calling GetOrCreate() after shutdown!");
    311    return nullptr;
    312  }
    313 
    314  if (!gQuotaManagerService) {
    315    RefPtr<QuotaManagerService> instance(new QuotaManagerService());
    316 
    317    nsresult rv = instance->Init();
    318    if (NS_WARN_IF(NS_FAILED(rv))) {
    319      return nullptr;
    320    }
    321 
    322    if (gInitialized.exchange(true)) {
    323      MOZ_ASSERT(false, "Initialized more than once?!");
    324    }
    325 
    326    gQuotaManagerService = instance;
    327 
    328    ClearOnShutdown(&gQuotaManagerService);
    329  }
    330 
    331  return gQuotaManagerService;
    332 }
    333 
    334 // static
    335 QuotaManagerService* QuotaManagerService::Get() {
    336  // Does not return an owning reference.
    337  return gQuotaManagerService;
    338 }
    339 
    340 // static
    341 already_AddRefed<QuotaManagerService> QuotaManagerService::FactoryCreate() {
    342  RefPtr<QuotaManagerService> quotaManagerService = GetOrCreate();
    343  return quotaManagerService.forget();
    344 }
    345 
    346 void QuotaManagerService::ClearBackgroundActor() {
    347  MOZ_ASSERT(NS_IsMainThread());
    348 
    349  mBackgroundActor = nullptr;
    350 }
    351 
    352 void QuotaManagerService::AbortOperationsForProcess(
    353    ContentParentId aContentParentId) {
    354  MOZ_ASSERT(XRE_IsParentProcess());
    355  MOZ_ASSERT(NS_IsMainThread());
    356 
    357  nsresult rv = EnsureBackgroundActor();
    358  if (NS_WARN_IF(NS_FAILED(rv))) {
    359    return;
    360  }
    361 
    362  if (NS_WARN_IF(
    363          !mBackgroundActor->SendAbortOperationsForProcess(aContentParentId))) {
    364    return;
    365  }
    366 }
    367 
    368 nsresult QuotaManagerService::Init() {
    369  MOZ_ASSERT(NS_IsMainThread());
    370 
    371  if (XRE_IsParentProcess()) {
    372    nsCOMPtr<nsIObserverService> observerService =
    373        mozilla::services::GetObserverService();
    374    if (NS_WARN_IF(!observerService)) {
    375      return NS_ERROR_FAILURE;
    376    }
    377 
    378    nsresult rv = observerService->AddObserver(
    379        this, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID, false);
    380    if (NS_WARN_IF(NS_FAILED(rv))) {
    381      return rv;
    382    }
    383  }
    384 
    385  return NS_OK;
    386 }
    387 
    388 void QuotaManagerService::Destroy() {
    389  // Setting the closed flag prevents the service from being recreated.
    390  // Don't set it though if there's no real instance created.
    391  if (gInitialized && gClosed.exchange(true)) {
    392    MOZ_ASSERT(false, "Shutdown more than once?!");
    393  }
    394 
    395  delete this;
    396 }
    397 
    398 nsresult QuotaManagerService::EnsureBackgroundActor() {
    399  MOZ_ASSERT(NS_IsMainThread());
    400 
    401  // Nothing can be done here if we have previously failed to create a
    402  // background actor.
    403  if (mBackgroundActorFailed) {
    404    return NS_ERROR_FAILURE;
    405  }
    406 
    407  if (!mBackgroundActor) {
    408    PBackgroundChild* backgroundActor =
    409        BackgroundChild::GetOrCreateForCurrentThread();
    410    if (NS_WARN_IF(!backgroundActor)) {
    411      mBackgroundActorFailed = true;
    412      return NS_ERROR_FAILURE;
    413    }
    414 
    415    {
    416      RefPtr<QuotaChild> actor = new QuotaChild(this);
    417 
    418      mBackgroundActor = static_cast<QuotaChild*>(
    419          backgroundActor->SendPQuotaConstructor(actor));
    420    }
    421  }
    422 
    423  if (!mBackgroundActor) {
    424    mBackgroundActorFailed = true;
    425    return NS_ERROR_FAILURE;
    426  }
    427 
    428  return NS_OK;
    429 }
    430 
    431 nsresult QuotaManagerService::InitiateRequest(PendingRequestInfo& aInfo) {
    432  nsresult rv = EnsureBackgroundActor();
    433  if (NS_WARN_IF(NS_FAILED(rv))) {
    434    return rv;
    435  }
    436 
    437  rv = aInfo.InitiateRequest(mBackgroundActor);
    438  if (NS_WARN_IF(NS_FAILED(rv))) {
    439    return rv;
    440  }
    441 
    442  return NS_OK;
    443 }
    444 
    445 void QuotaManagerService::PerformIdleMaintenance() {
    446  using namespace mozilla::hal;
    447 
    448  MOZ_ASSERT(XRE_IsParentProcess());
    449  MOZ_ASSERT(NS_IsMainThread());
    450 
    451  // If we're running on battery power then skip all idle maintenance since we
    452  // would otherwise be doing lots of disk I/O.
    453  BatteryInformation batteryInfo;
    454 
    455 #ifdef MOZ_WIDGET_ANDROID
    456  // Android XPCShell doesn't load the AndroidBridge that is needed to make
    457  // GetCurrentBatteryInformation work...
    458  if (!QuotaManager::IsRunningXPCShellTests())
    459 #endif
    460  {
    461    // In order to give the correct battery level, hal must have registered
    462    // battery observers.
    463    RegisterBatteryObserver(this);
    464    GetCurrentBatteryInformation(&batteryInfo);
    465    UnregisterBatteryObserver(this);
    466  }
    467 
    468  // If we're running XPCShell because we always want to be able to test this
    469  // code so pretend that we're always charging.
    470  if (QuotaManager::IsRunningXPCShellTests()) {
    471    batteryInfo.level() = 100;
    472    batteryInfo.charging() = true;
    473  }
    474 
    475  if (NS_WARN_IF(!batteryInfo.charging())) {
    476    return;
    477  }
    478 
    479  if (QuotaManager::IsRunningXPCShellTests()) {
    480    // We don't want user activity to impact this code if we're running tests.
    481    (void)Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
    482  } else if (!mIdleObserverRegistered) {
    483    nsCOMPtr<nsIUserIdleService> idleService =
    484        do_GetService(kIdleServiceContractId);
    485    MOZ_ASSERT(idleService);
    486 
    487    MOZ_ALWAYS_SUCCEEDS(
    488        idleService->AddIdleObserver(this, kIdleObserverTimeSec));
    489 
    490    mIdleObserverRegistered = true;
    491  }
    492 }
    493 
    494 void QuotaManagerService::RemoveIdleObserver() {
    495  MOZ_ASSERT(XRE_IsParentProcess());
    496  MOZ_ASSERT(NS_IsMainThread());
    497 
    498  if (mIdleObserverRegistered) {
    499    nsCOMPtr<nsIUserIdleService> idleService =
    500        do_GetService(kIdleServiceContractId);
    501    MOZ_ASSERT(idleService);
    502 
    503    // Ignore the return value of RemoveIdleObserver, it may fail if the
    504    // observer has already been unregistered during shutdown.
    505    (void)idleService->RemoveIdleObserver(this, kIdleObserverTimeSec);
    506 
    507    mIdleObserverRegistered = false;
    508  }
    509 }
    510 
    511 NS_IMPL_ADDREF(QuotaManagerService)
    512 NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
    513 NS_IMPL_QUERY_INTERFACE(QuotaManagerService, nsIQuotaManagerService,
    514                        nsIQuotaManagerServiceInternal, nsIObserver)
    515 
    516 NS_IMETHODIMP
    517 QuotaManagerService::StorageName(nsIQuotaRequest** _retval) {
    518  MOZ_ASSERT(NS_IsMainThread());
    519  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    520 
    521  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    522    return NS_ERROR_UNEXPECTED;
    523  }
    524 
    525  RefPtr<Request> request = new Request();
    526 
    527  StorageNameParams params;
    528 
    529  RequestInfo info(request, params);
    530 
    531  nsresult rv = InitiateRequest(info);
    532  if (NS_WARN_IF(NS_FAILED(rv))) {
    533    return rv;
    534  }
    535 
    536  request.forget(_retval);
    537  return NS_OK;
    538 }
    539 
    540 NS_IMETHODIMP
    541 QuotaManagerService::StorageInitialized(nsIQuotaRequest** _retval) {
    542  MOZ_ASSERT(NS_IsMainThread());
    543  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    544 
    545  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    546    return NS_ERROR_UNEXPECTED;
    547  }
    548 
    549  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    550 
    551  RefPtr<Request> request = new Request();
    552 
    553  mBackgroundActor->SendStorageInitialized()->Then(
    554      GetCurrentSerialEventTarget(), __func__,
    555      BoolResponsePromiseResolveOrRejectCallback(request));
    556 
    557  request.forget(_retval);
    558  return NS_OK;
    559 }
    560 
    561 NS_IMETHODIMP
    562 QuotaManagerService::PersistentStorageInitialized(nsIQuotaRequest** _retval) {
    563  MOZ_ASSERT(NS_IsMainThread());
    564  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    565 
    566  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    567    return NS_ERROR_UNEXPECTED;
    568  }
    569 
    570  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    571 
    572  RefPtr<Request> request = new Request();
    573 
    574  mBackgroundActor->SendPersistentStorageInitialized()->Then(
    575      GetCurrentSerialEventTarget(), __func__,
    576      BoolResponsePromiseResolveOrRejectCallback(request));
    577 
    578  request.forget(_retval);
    579  return NS_OK;
    580 }
    581 
    582 NS_IMETHODIMP
    583 QuotaManagerService::TemporaryStorageInitialized(nsIQuotaRequest** _retval) {
    584  MOZ_ASSERT(NS_IsMainThread());
    585  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    586 
    587  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    588    return NS_ERROR_UNEXPECTED;
    589  }
    590 
    591  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    592 
    593  RefPtr<Request> request = new Request();
    594 
    595  mBackgroundActor->SendTemporaryStorageInitialized()->Then(
    596      GetCurrentSerialEventTarget(), __func__,
    597      BoolResponsePromiseResolveOrRejectCallback(request));
    598 
    599  request.forget(_retval);
    600  return NS_OK;
    601 }
    602 
    603 NS_IMETHODIMP
    604 QuotaManagerService::TemporaryGroupInitialized(nsIPrincipal* aPrincipal,
    605                                               nsIQuotaRequest** _retval) {
    606  MOZ_ASSERT(NS_IsMainThread());
    607  MOZ_ASSERT(aPrincipal);
    608  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    609 
    610  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    611         NS_ERROR_UNEXPECTED);
    612 
    613  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    614 
    615  QM_TRY_INSPECT(const auto& principalInfo,
    616                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    617                   PrincipalInfo principalInfo;
    618                   QM_TRY(MOZ_TO_RESULT(
    619                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    620 
    621                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    622                          Err(NS_ERROR_INVALID_ARG));
    623 
    624                   return principalInfo;
    625                 }()));
    626 
    627  RefPtr<Request> request = new Request();
    628 
    629  mBackgroundActor->SendTemporaryGroupInitialized(principalInfo)
    630      ->Then(GetCurrentSerialEventTarget(), __func__,
    631             BoolResponsePromiseResolveOrRejectCallback(request));
    632 
    633  request.forget(_retval);
    634  return NS_OK;
    635 }
    636 
    637 NS_IMETHODIMP
    638 QuotaManagerService::PersistentOriginInitialized(nsIPrincipal* aPrincipal,
    639                                                 nsIQuotaRequest** _retval) {
    640  MOZ_ASSERT(NS_IsMainThread());
    641  MOZ_ASSERT(aPrincipal);
    642  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    643 
    644  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    645         NS_ERROR_UNEXPECTED);
    646 
    647  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    648 
    649  QM_TRY_INSPECT(const auto& principalInfo,
    650                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    651                   PrincipalInfo principalInfo;
    652                   QM_TRY(MOZ_TO_RESULT(
    653                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    654 
    655                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    656                          Err(NS_ERROR_INVALID_ARG));
    657 
    658                   return principalInfo;
    659                 }()));
    660 
    661  RefPtr<Request> request = new Request();
    662 
    663  mBackgroundActor->SendPersistentOriginInitialized(principalInfo)
    664      ->Then(GetCurrentSerialEventTarget(), __func__,
    665             BoolResponsePromiseResolveOrRejectCallback(request));
    666 
    667  request.forget(_retval);
    668  return NS_OK;
    669 }
    670 
    671 NS_IMETHODIMP
    672 QuotaManagerService::TemporaryOriginInitialized(
    673    const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
    674    nsIQuotaRequest** _retval) {
    675  MOZ_ASSERT(NS_IsMainThread());
    676  MOZ_ASSERT(aPrincipal);
    677  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    678 
    679  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    680         NS_ERROR_UNEXPECTED);
    681 
    682  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    683 
    684  QM_TRY_INSPECT(
    685      const auto& persistenceType,
    686      ([&aPersistenceType]() -> Result<PersistenceType, nsresult> {
    687        const auto persistenceType =
    688            PersistenceTypeFromString(aPersistenceType, fallible);
    689        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
    690               Err(NS_ERROR_INVALID_ARG));
    691 
    692        QM_TRY(
    693            MOZ_TO_RESULT(IsBestEffortPersistenceType(persistenceType.ref())),
    694            Err(NS_ERROR_INVALID_ARG));
    695 
    696        return persistenceType.ref();
    697      }()));
    698 
    699  QM_TRY_INSPECT(const auto& principalInfo,
    700                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    701                   PrincipalInfo principalInfo;
    702                   QM_TRY(MOZ_TO_RESULT(
    703                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    704 
    705                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    706                          Err(NS_ERROR_INVALID_ARG));
    707 
    708                   return principalInfo;
    709                 }()));
    710 
    711  RefPtr<Request> request = new Request();
    712 
    713  mBackgroundActor
    714      ->SendTemporaryOriginInitialized(persistenceType, principalInfo)
    715      ->Then(GetCurrentSerialEventTarget(), __func__,
    716             BoolResponsePromiseResolveOrRejectCallback(request));
    717 
    718  request.forget(_retval);
    719  return NS_OK;
    720 }
    721 
    722 NS_IMETHODIMP
    723 QuotaManagerService::Init(nsIQuotaRequest** _retval) {
    724  MOZ_ASSERT(NS_IsMainThread());
    725  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    726 
    727  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    728    return NS_ERROR_UNEXPECTED;
    729  }
    730 
    731  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    732 
    733  RefPtr<Request> request = new Request();
    734 
    735  mBackgroundActor->SendInitializeStorage()->Then(
    736      GetCurrentSerialEventTarget(), __func__,
    737      BoolResponsePromiseResolveOrRejectCallback(request));
    738 
    739  request.forget(_retval);
    740  return NS_OK;
    741 }
    742 
    743 NS_IMETHODIMP
    744 QuotaManagerService::InitializePersistentStorage(nsIQuotaRequest** _retval) {
    745  MOZ_ASSERT(NS_IsMainThread());
    746  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    747 
    748  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    749    return NS_ERROR_UNEXPECTED;
    750  }
    751 
    752  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    753 
    754  RefPtr<Request> request = new Request();
    755 
    756  mBackgroundActor->SendInitializePersistentStorage()->Then(
    757      GetCurrentSerialEventTarget(), __func__,
    758      BoolResponsePromiseResolveOrRejectCallback(request));
    759 
    760  request.forget(_retval);
    761  return NS_OK;
    762 }
    763 
    764 NS_IMETHODIMP
    765 QuotaManagerService::InitTemporaryStorage(nsIQuotaRequest** _retval) {
    766  MOZ_ASSERT(NS_IsMainThread());
    767  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    768 
    769  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    770    return NS_ERROR_UNEXPECTED;
    771  }
    772 
    773  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    774 
    775  RefPtr<Request> request = new Request();
    776 
    777  mBackgroundActor->SendInitializeTemporaryStorage()->Then(
    778      GetCurrentSerialEventTarget(), __func__,
    779      BoolResponsePromiseResolveOrRejectCallback(request));
    780 
    781  request.forget(_retval);
    782  return NS_OK;
    783 }
    784 
    785 NS_IMETHODIMP
    786 QuotaManagerService::InitializeAllTemporaryOrigins(nsIQuotaRequest** _retval) {
    787  MOZ_ASSERT(NS_IsMainThread());
    788  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    789 
    790  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
    791    return NS_ERROR_UNEXPECTED;
    792  }
    793 
    794  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    795 
    796  RefPtr<Request> request = new Request();
    797 
    798  mBackgroundActor->SendInitializeAllTemporaryOrigins()->Then(
    799      GetCurrentSerialEventTarget(), __func__,
    800      BoolResponsePromiseResolveOrRejectCallback(request));
    801 
    802  request.forget(_retval);
    803  return NS_OK;
    804 }
    805 
    806 NS_IMETHODIMP
    807 QuotaManagerService::InitializeTemporaryGroup(nsIPrincipal* aPrincipal,
    808                                              nsIQuotaRequest** _retval) {
    809  MOZ_ASSERT(NS_IsMainThread());
    810  MOZ_ASSERT(aPrincipal);
    811  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    812 
    813  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    814         NS_ERROR_UNEXPECTED);
    815 
    816  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    817 
    818  QM_TRY_INSPECT(const auto& principalInfo,
    819                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    820                   PrincipalInfo principalInfo;
    821                   QM_TRY(MOZ_TO_RESULT(
    822                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    823 
    824                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    825                          Err(NS_ERROR_INVALID_ARG));
    826 
    827                   return principalInfo;
    828                 }()));
    829 
    830  RefPtr<Request> request = new Request();
    831 
    832  mBackgroundActor->SendInitializeTemporaryGroup(principalInfo)
    833      ->Then(GetCurrentSerialEventTarget(), __func__,
    834             BoolResponsePromiseResolveOrRejectCallback(request));
    835 
    836  request.forget(_retval);
    837  return NS_OK;
    838 }
    839 
    840 NS_IMETHODIMP
    841 QuotaManagerService::InitializePersistentOrigin(nsIPrincipal* aPrincipal,
    842                                                nsIQuotaRequest** _retval) {
    843  MOZ_ASSERT(NS_IsMainThread());
    844  MOZ_ASSERT(aPrincipal);
    845  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    846 
    847  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    848         NS_ERROR_UNEXPECTED);
    849 
    850  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    851 
    852  QM_TRY_INSPECT(const auto& principalInfo,
    853                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    854                   PrincipalInfo principalInfo;
    855                   QM_TRY(MOZ_TO_RESULT(
    856                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    857 
    858                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    859                          Err(NS_ERROR_INVALID_ARG));
    860 
    861                   return principalInfo;
    862                 }()));
    863 
    864  auto request = MakeRefPtr<Request>();
    865 
    866  mBackgroundActor->SendInitializePersistentOrigin(principalInfo)
    867      ->Then(GetCurrentSerialEventTarget(), __func__,
    868             BoolResponsePromiseResolveOrRejectCallback(request));
    869 
    870  request.forget(_retval);
    871  return NS_OK;
    872 }
    873 
    874 NS_IMETHODIMP
    875 QuotaManagerService::InitializeTemporaryOrigin(
    876    const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
    877    bool aCreateIfNonExistent, nsIQuotaRequest** _retval) {
    878  MOZ_ASSERT(NS_IsMainThread());
    879  MOZ_ASSERT(aPrincipal);
    880  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    881 
    882  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    883         NS_ERROR_UNEXPECTED);
    884 
    885  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    886 
    887  QM_TRY_INSPECT(
    888      const auto& persistenceType,
    889      ([&aPersistenceType]() -> Result<PersistenceType, nsresult> {
    890        const auto persistenceType =
    891            PersistenceTypeFromString(aPersistenceType, fallible);
    892        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
    893               Err(NS_ERROR_INVALID_ARG));
    894 
    895        QM_TRY(
    896            MOZ_TO_RESULT(IsBestEffortPersistenceType(persistenceType.ref())),
    897            Err(NS_ERROR_INVALID_ARG));
    898 
    899        return persistenceType.ref();
    900      }()));
    901 
    902  QM_TRY_INSPECT(const auto& principalInfo,
    903                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    904                   PrincipalInfo principalInfo;
    905                   QM_TRY(MOZ_TO_RESULT(
    906                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    907 
    908                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    909                          Err(NS_ERROR_INVALID_ARG));
    910 
    911                   return principalInfo;
    912                 }()));
    913 
    914  auto request = MakeRefPtr<Request>();
    915 
    916  mBackgroundActor
    917      ->SendInitializeTemporaryOrigin(persistenceType, principalInfo,
    918                                      aCreateIfNonExistent)
    919      ->Then(GetCurrentSerialEventTarget(), __func__,
    920             BoolResponsePromiseResolveOrRejectCallback(request));
    921 
    922  request.forget(_retval);
    923  return NS_OK;
    924 }
    925 
    926 NS_IMETHODIMP
    927 QuotaManagerService::InitializePersistentClient(nsIPrincipal* aPrincipal,
    928                                                const nsAString& aClientType,
    929                                                nsIQuotaRequest** _retval) {
    930  MOZ_ASSERT(NS_IsMainThread());
    931  MOZ_ASSERT(aPrincipal);
    932  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    933 
    934  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    935         NS_ERROR_UNEXPECTED);
    936 
    937  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    938 
    939  QM_TRY_INSPECT(const auto& principalInfo,
    940                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
    941                   PrincipalInfo principalInfo;
    942                   QM_TRY(MOZ_TO_RESULT(
    943                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
    944 
    945                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
    946                          Err(NS_ERROR_INVALID_ARG));
    947 
    948                   return principalInfo;
    949                 }()));
    950 
    951  QM_TRY_INSPECT(const auto& clientType,
    952                 ([&aClientType]() -> Result<Client::Type, nsresult> {
    953                   Client::Type clientType;
    954                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
    955                              aClientType, clientType, fallible)),
    956                          Err(NS_ERROR_INVALID_ARG));
    957 
    958                   return clientType;
    959                 }()));
    960 
    961  RefPtr<Request> request = new Request();
    962 
    963  mBackgroundActor->SendInitializePersistentClient(principalInfo, clientType)
    964      ->Then(GetCurrentSerialEventTarget(), __func__,
    965             BoolResponsePromiseResolveOrRejectCallback(request));
    966 
    967  request.forget(_retval);
    968  return NS_OK;
    969 }
    970 
    971 NS_IMETHODIMP
    972 QuotaManagerService::InitializeTemporaryClient(
    973    const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
    974    const nsAString& aClientType, bool aCreateIfNonExistent,
    975    nsIQuotaRequest** _retval) {
    976  MOZ_ASSERT(NS_IsMainThread());
    977  MOZ_ASSERT(aPrincipal);
    978  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
    979 
    980  QM_TRY(MOZ_TO_RESULT(StaticPrefs::dom_quotaManager_testing()),
    981         NS_ERROR_UNEXPECTED);
    982 
    983  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
    984 
    985  QM_TRY_INSPECT(
    986      const auto& persistenceType,
    987      ([&aPersistenceType]() -> Result<PersistenceType, nsresult> {
    988        const auto persistenceType =
    989            PersistenceTypeFromString(aPersistenceType, fallible);
    990        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
    991               Err(NS_ERROR_INVALID_ARG));
    992 
    993        QM_TRY(
    994            MOZ_TO_RESULT(IsBestEffortPersistenceType(persistenceType.ref())),
    995            Err(NS_ERROR_INVALID_ARG));
    996 
    997        return persistenceType.ref();
    998      }()));
    999 
   1000  QM_TRY_INSPECT(const auto& principalInfo,
   1001                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1002                   PrincipalInfo principalInfo;
   1003                   QM_TRY(MOZ_TO_RESULT(
   1004                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1005 
   1006                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1007                          Err(NS_ERROR_INVALID_ARG));
   1008 
   1009                   return principalInfo;
   1010                 }()));
   1011 
   1012  QM_TRY_INSPECT(const auto& clientType,
   1013                 ([&aClientType]() -> Result<Client::Type, nsresult> {
   1014                   Client::Type clientType;
   1015                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
   1016                              aClientType, clientType, fallible)),
   1017                          Err(NS_ERROR_INVALID_ARG));
   1018 
   1019                   return clientType;
   1020                 }()));
   1021 
   1022  RefPtr<Request> request = new Request();
   1023 
   1024  mBackgroundActor
   1025      ->SendInitializeTemporaryClient(persistenceType, principalInfo,
   1026                                      clientType, aCreateIfNonExistent)
   1027      ->Then(GetCurrentSerialEventTarget(), __func__,
   1028             BoolResponsePromiseResolveOrRejectCallback(request));
   1029 
   1030  request.forget(_retval);
   1031  return NS_OK;
   1032 }
   1033 
   1034 NS_IMETHODIMP
   1035 QuotaManagerService::GetFullOriginMetadata(const nsACString& aPersistenceType,
   1036                                           nsIPrincipal* aPrincipal,
   1037                                           nsIQuotaRequest** _retval) {
   1038  MOZ_ASSERT(NS_IsMainThread());
   1039  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
   1040 
   1041  QM_TRY(OkIf(StaticPrefs::dom_quotaManager_testing()), NS_ERROR_UNEXPECTED);
   1042 
   1043  const auto maybePersistenceType =
   1044      PersistenceTypeFromString(aPersistenceType, fallible);
   1045  QM_TRY(OkIf(maybePersistenceType.isSome()), NS_ERROR_INVALID_ARG);
   1046  QM_TRY(OkIf(IsBestEffortPersistenceType(*maybePersistenceType)),
   1047         NS_ERROR_INVALID_ARG);
   1048 
   1049  PrincipalInfo principalInfo;
   1050  QM_TRY(MOZ_TO_RESULT(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1051  QM_TRY(OkIf(IsPrincipalInfoValid(principalInfo)), NS_ERROR_INVALID_ARG);
   1052 
   1053  RefPtr<Request> request = new Request();
   1054 
   1055  GetFullOriginMetadataParams params;
   1056 
   1057  params.persistenceType() = *maybePersistenceType;
   1058  params.principalInfo() = std::move(principalInfo);
   1059 
   1060  RequestInfo info(request, params);
   1061 
   1062  QM_TRY(MOZ_TO_RESULT(InitiateRequest(info)));
   1063 
   1064  request.forget(_retval);
   1065  return NS_OK;
   1066 }
   1067 
   1068 NS_IMETHODIMP
   1069 QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback, bool aGetAll,
   1070                              nsIQuotaUsageRequest** _retval) {
   1071  MOZ_ASSERT(NS_IsMainThread());
   1072  MOZ_ASSERT(aCallback);
   1073 
   1074  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1075 
   1076  RefPtr<UsageRequest> request = new UsageRequest(aCallback);
   1077 
   1078  RefPtr<QuotaUsageRequestChild> usageRequestChild =
   1079      new QuotaUsageRequestChild(request);
   1080 
   1081  ManagedEndpoint<PQuotaUsageRequestParent> usageRequestParentEndpoint =
   1082      mBackgroundActor->OpenPQuotaUsageRequestEndpoint(usageRequestChild);
   1083  QM_TRY(MOZ_TO_RESULT(usageRequestParentEndpoint.IsValid()));
   1084 
   1085  mBackgroundActor->SendGetUsage(aGetAll, std::move(usageRequestParentEndpoint))
   1086      ->Then(GetCurrentSerialEventTarget(), __func__,
   1087             OriginUsageMetadataArrayResponsePromiseResolveOrRejectCallback(
   1088                 request));
   1089 
   1090  request->SetBackgroundActor(usageRequestChild);
   1091 
   1092  request.forget(_retval);
   1093  return NS_OK;
   1094 }
   1095 
   1096 NS_IMETHODIMP
   1097 QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
   1098                                          nsIQuotaUsageCallback* aCallback,
   1099                                          nsIQuotaUsageRequest** _retval) {
   1100  MOZ_ASSERT(NS_IsMainThread());
   1101  MOZ_ASSERT(aPrincipal);
   1102  MOZ_ASSERT(aCallback);
   1103 
   1104  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1105 
   1106  QM_TRY_INSPECT(const auto& principalInfo,
   1107                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1108                   PrincipalInfo principalInfo;
   1109                   QM_TRY(MOZ_TO_RESULT(
   1110                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1111 
   1112                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1113                          Err(NS_ERROR_INVALID_ARG));
   1114 
   1115                   return principalInfo;
   1116                 }()));
   1117 
   1118  RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
   1119 
   1120  RefPtr<QuotaUsageRequestChild> usageRequestChild =
   1121      new QuotaUsageRequestChild(request);
   1122 
   1123  ManagedEndpoint<PQuotaUsageRequestParent> usageRequestParentEndpoint =
   1124      mBackgroundActor->OpenPQuotaUsageRequestEndpoint(usageRequestChild);
   1125  QM_TRY(MOZ_TO_RESULT(usageRequestParentEndpoint.IsValid()));
   1126 
   1127  mBackgroundActor
   1128      ->SendGetOriginUsage(principalInfo, std::move(usageRequestParentEndpoint))
   1129      ->Then(GetCurrentSerialEventTarget(), __func__,
   1130             UsageInfoResponsePromiseResolveOrRejectCallback(request));
   1131 
   1132  request->SetBackgroundActor(usageRequestChild);
   1133 
   1134  request.forget(_retval);
   1135  return NS_OK;
   1136 }
   1137 
   1138 NS_IMETHODIMP
   1139 QuotaManagerService::GetCachedUsageForPrincipal(nsIPrincipal* aPrincipal,
   1140                                                nsIQuotaRequest** _retval) {
   1141  MOZ_ASSERT(NS_IsMainThread());
   1142  MOZ_ASSERT(aPrincipal);
   1143 
   1144  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1145 
   1146  QM_TRY_INSPECT(const auto& principalInfo,
   1147                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1148                   PrincipalInfo principalInfo;
   1149                   QM_TRY(MOZ_TO_RESULT(
   1150                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1151 
   1152                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1153                          Err(NS_ERROR_INVALID_ARG));
   1154 
   1155                   return principalInfo;
   1156                 }()));
   1157 
   1158  RefPtr<Request> request = new Request();
   1159 
   1160  mBackgroundActor->SendGetCachedOriginUsage(principalInfo)
   1161      ->Then(GetCurrentSerialEventTarget(), __func__,
   1162             UInt64ResponsePromiseResolveOrRejectCallback(request));
   1163 
   1164  request.forget(_retval);
   1165  return NS_OK;
   1166 }
   1167 
   1168 NS_IMETHODIMP
   1169 QuotaManagerService::Clear(nsIQuotaRequest** _retval) {
   1170  MOZ_ASSERT(NS_IsMainThread());
   1171 
   1172  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
   1173    return NS_ERROR_UNEXPECTED;
   1174  }
   1175 
   1176  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1177 
   1178  RefPtr<Request> request = new Request();
   1179 
   1180  mBackgroundActor->SendClearStorage()->Then(
   1181      GetCurrentSerialEventTarget(), __func__,
   1182      BoolResponsePromiseResolveOrRejectCallback(request));
   1183 
   1184  request.forget(_retval);
   1185  return NS_OK;
   1186 }
   1187 
   1188 NS_IMETHODIMP
   1189 QuotaManagerService::ClearStoragesForPrivateBrowsing(
   1190    nsIQuotaRequest** _retval) {
   1191  MOZ_ASSERT(NS_IsMainThread());
   1192 
   1193  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1194 
   1195  RefPtr<Request> request = new Request();
   1196 
   1197  mBackgroundActor->SendClearStoragesForPrivateBrowsing()->Then(
   1198      GetCurrentSerialEventTarget(), __func__,
   1199      BoolResponsePromiseResolveOrRejectCallback(request));
   1200 
   1201  request.forget(_retval);
   1202  return NS_OK;
   1203 }
   1204 
   1205 NS_IMETHODIMP
   1206 QuotaManagerService::ClearStoragesForOriginAttributesPattern(
   1207    const nsAString& aPattern, nsIQuotaRequest** _retval) {
   1208  MOZ_ASSERT(NS_IsMainThread());
   1209 
   1210  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1211 
   1212  OriginAttributesPattern pattern;
   1213  MOZ_ALWAYS_TRUE(pattern.Init(aPattern));
   1214 
   1215  RefPtr<Request> request = new Request();
   1216 
   1217  mBackgroundActor->SendClearStoragesForOriginAttributesPattern(pattern)->Then(
   1218      GetCurrentSerialEventTarget(), __func__,
   1219      BoolResponsePromiseResolveOrRejectCallback(request));
   1220 
   1221  request.forget(_retval);
   1222  return NS_OK;
   1223 }
   1224 
   1225 NS_IMETHODIMP
   1226 QuotaManagerService::ClearStoragesForPrincipal(
   1227    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
   1228    nsIQuotaRequest** _retval) {
   1229  MOZ_ASSERT(NS_IsMainThread());
   1230  MOZ_ASSERT(aPrincipal);
   1231 
   1232  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1233 
   1234  QM_TRY_INSPECT(
   1235      const auto& persistenceType,
   1236      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
   1237        if (aPersistenceType.IsVoid()) {
   1238          return Maybe<PersistenceType>();
   1239        }
   1240 
   1241        const auto persistenceType =
   1242            PersistenceTypeFromString(aPersistenceType, fallible);
   1243        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
   1244               Err(NS_ERROR_INVALID_ARG));
   1245 
   1246        return persistenceType;
   1247      }()));
   1248 
   1249  QM_TRY_INSPECT(const auto& principalInfo,
   1250                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1251                   PrincipalInfo principalInfo;
   1252                   QM_TRY(MOZ_TO_RESULT(
   1253                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1254 
   1255                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1256                          Err(NS_ERROR_INVALID_ARG));
   1257 
   1258                   return principalInfo;
   1259                 }()));
   1260 
   1261  RefPtr<Request> request = new Request();
   1262 
   1263  mBackgroundActor->SendClearStoragesForOrigin(persistenceType, principalInfo)
   1264      ->Then(GetCurrentSerialEventTarget(), __func__,
   1265             BoolResponsePromiseResolveOrRejectCallback(request));
   1266 
   1267  request.forget(_retval);
   1268  return NS_OK;
   1269 }
   1270 
   1271 NS_IMETHODIMP
   1272 QuotaManagerService::ClearStoragesForClient(nsIPrincipal* aPrincipal,
   1273                                            const nsAString& aClientType,
   1274                                            const nsACString& aPersistenceType,
   1275                                            nsIQuotaRequest** _retval) {
   1276  MOZ_ASSERT(NS_IsMainThread());
   1277  MOZ_ASSERT(aPrincipal);
   1278 
   1279  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1280 
   1281  QM_TRY_INSPECT(
   1282      const auto& persistenceType,
   1283      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
   1284        if (aPersistenceType.IsVoid()) {
   1285          return Maybe<PersistenceType>();
   1286        }
   1287 
   1288        const auto persistenceType =
   1289            PersistenceTypeFromString(aPersistenceType, fallible);
   1290        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
   1291               Err(NS_ERROR_INVALID_ARG));
   1292 
   1293        return persistenceType;
   1294      }()));
   1295 
   1296  QM_TRY_INSPECT(const auto& principalInfo,
   1297                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1298                   PrincipalInfo principalInfo;
   1299                   QM_TRY(MOZ_TO_RESULT(
   1300                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1301 
   1302                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1303                          Err(NS_ERROR_INVALID_ARG));
   1304 
   1305                   return principalInfo;
   1306                 }()));
   1307 
   1308  QM_TRY_INSPECT(const auto& clientType,
   1309                 ([&aClientType]() -> Result<Client::Type, nsresult> {
   1310                   Client::Type clientType;
   1311                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
   1312                              aClientType, clientType, fallible)),
   1313                          Err(NS_ERROR_INVALID_ARG));
   1314 
   1315                   return clientType;
   1316                 }()));
   1317 
   1318  RefPtr<Request> request = new Request();
   1319 
   1320  mBackgroundActor
   1321      ->SendClearStoragesForClient(persistenceType, principalInfo, clientType)
   1322      ->Then(GetCurrentSerialEventTarget(), __func__,
   1323             BoolResponsePromiseResolveOrRejectCallback(request));
   1324 
   1325  request.forget(_retval);
   1326  return NS_OK;
   1327 }
   1328 
   1329 NS_IMETHODIMP
   1330 QuotaManagerService::ClearStoragesForOriginPrefix(
   1331    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
   1332    nsIQuotaRequest** _retval) {
   1333  MOZ_ASSERT(NS_IsMainThread());
   1334  MOZ_ASSERT(aPrincipal);
   1335 
   1336  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1337 
   1338  QM_TRY_INSPECT(
   1339      const auto& persistenceType,
   1340      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
   1341        if (aPersistenceType.IsVoid()) {
   1342          return Maybe<PersistenceType>();
   1343        }
   1344 
   1345        const auto persistenceType =
   1346            PersistenceTypeFromString(aPersistenceType, fallible);
   1347        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
   1348               Err(NS_ERROR_INVALID_ARG));
   1349 
   1350        return persistenceType;
   1351      }()));
   1352 
   1353  QM_TRY_INSPECT(
   1354      const auto& principalInfo,
   1355      ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1356        PrincipalInfo principalInfo;
   1357        QM_TRY(MOZ_TO_RESULT(
   1358            PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1359 
   1360        QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1361               Err(NS_ERROR_INVALID_ARG));
   1362 
   1363        if (principalInfo.type() == PrincipalInfo::TContentPrincipalInfo) {
   1364          nsCString suffix;
   1365          principalInfo.get_ContentPrincipalInfo().attrs().CreateSuffix(suffix);
   1366 
   1367          QM_TRY(MOZ_TO_RESULT(suffix.IsEmpty()), Err(NS_ERROR_INVALID_ARG));
   1368        }
   1369 
   1370        return principalInfo;
   1371      }()));
   1372 
   1373  RefPtr<Request> request = new Request();
   1374 
   1375  mBackgroundActor
   1376      ->SendClearStoragesForOriginPrefix(persistenceType, principalInfo)
   1377      ->Then(GetCurrentSerialEventTarget(), __func__,
   1378             BoolResponsePromiseResolveOrRejectCallback(request));
   1379 
   1380  request.forget(_retval);
   1381  return NS_OK;
   1382 }
   1383 
   1384 NS_IMETHODIMP
   1385 QuotaManagerService::Reset(nsIQuotaRequest** _retval) {
   1386  MOZ_ASSERT(NS_IsMainThread());
   1387 
   1388  if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
   1389    return NS_ERROR_UNEXPECTED;
   1390  }
   1391 
   1392  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1393 
   1394  RefPtr<Request> request = new Request();
   1395 
   1396  mBackgroundActor->SendShutdownStorage()->Then(
   1397      GetCurrentSerialEventTarget(), __func__,
   1398      BoolResponsePromiseResolveOrRejectCallback(request));
   1399 
   1400  request.forget(_retval);
   1401  return NS_OK;
   1402 }
   1403 
   1404 NS_IMETHODIMP
   1405 QuotaManagerService::ResetStoragesForPrincipal(
   1406    nsIPrincipal* aPrincipal, const nsACString& aPersistenceType,
   1407    nsIQuotaRequest** _retval) {
   1408  MOZ_ASSERT(NS_IsMainThread());
   1409  MOZ_ASSERT(aPrincipal);
   1410 
   1411  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1412 
   1413  QM_TRY_INSPECT(
   1414      const auto& persistenceType,
   1415      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
   1416        if (aPersistenceType.IsVoid()) {
   1417          return Maybe<PersistenceType>();
   1418        }
   1419 
   1420        const auto persistenceType =
   1421            PersistenceTypeFromString(aPersistenceType, fallible);
   1422        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
   1423               Err(NS_ERROR_INVALID_ARG));
   1424 
   1425        return persistenceType;
   1426      }()));
   1427 
   1428  QM_TRY_INSPECT(const auto& principalInfo,
   1429                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1430                   PrincipalInfo principalInfo;
   1431                   QM_TRY(MOZ_TO_RESULT(
   1432                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1433 
   1434                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1435                          Err(NS_ERROR_INVALID_ARG));
   1436 
   1437                   return principalInfo;
   1438                 }()));
   1439 
   1440  RefPtr<Request> request = new Request();
   1441 
   1442  mBackgroundActor
   1443      ->SendShutdownStoragesForOrigin(persistenceType, principalInfo)
   1444      ->Then(GetCurrentSerialEventTarget(), __func__,
   1445             BoolResponsePromiseResolveOrRejectCallback(request));
   1446 
   1447  request.forget(_retval);
   1448  return NS_OK;
   1449 }
   1450 
   1451 NS_IMETHODIMP
   1452 QuotaManagerService::ResetStoragesForClient(nsIPrincipal* aPrincipal,
   1453                                            const nsAString& aClientType,
   1454                                            const nsACString& aPersistenceType,
   1455                                            nsIQuotaRequest** _retval) {
   1456  MOZ_ASSERT(NS_IsMainThread());
   1457  MOZ_ASSERT(aPrincipal);
   1458 
   1459  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1460 
   1461  QM_TRY_INSPECT(
   1462      const auto& persistenceType,
   1463      ([&aPersistenceType]() -> Result<Maybe<PersistenceType>, nsresult> {
   1464        if (aPersistenceType.IsVoid()) {
   1465          return Maybe<PersistenceType>();
   1466        }
   1467 
   1468        const auto persistenceType =
   1469            PersistenceTypeFromString(aPersistenceType, fallible);
   1470        QM_TRY(MOZ_TO_RESULT(persistenceType.isSome()),
   1471               Err(NS_ERROR_INVALID_ARG));
   1472 
   1473        return persistenceType;
   1474      }()));
   1475 
   1476  QM_TRY_INSPECT(const auto& principalInfo,
   1477                 ([&aPrincipal]() -> Result<PrincipalInfo, nsresult> {
   1478                   PrincipalInfo principalInfo;
   1479                   QM_TRY(MOZ_TO_RESULT(
   1480                       PrincipalToPrincipalInfo(aPrincipal, &principalInfo)));
   1481 
   1482                   QM_TRY(MOZ_TO_RESULT(IsPrincipalInfoValid(principalInfo)),
   1483                          Err(NS_ERROR_INVALID_ARG));
   1484 
   1485                   return principalInfo;
   1486                 }()));
   1487 
   1488  QM_TRY_INSPECT(const auto& clientType,
   1489                 ([&aClientType]() -> Result<Client::Type, nsresult> {
   1490                   Client::Type clientType;
   1491                   QM_TRY(MOZ_TO_RESULT(Client::TypeFromText(
   1492                              aClientType, clientType, fallible)),
   1493                          Err(NS_ERROR_INVALID_ARG));
   1494 
   1495                   return clientType;
   1496                 }()));
   1497 
   1498  RefPtr<Request> request = new Request();
   1499 
   1500  mBackgroundActor
   1501      ->SendShutdownStoragesForClient(persistenceType, principalInfo,
   1502                                      clientType)
   1503      ->Then(GetCurrentSerialEventTarget(), __func__,
   1504             BoolResponsePromiseResolveOrRejectCallback(request));
   1505 
   1506  request.forget(_retval);
   1507  return NS_OK;
   1508 }
   1509 
   1510 NS_IMETHODIMP
   1511 QuotaManagerService::Persisted(nsIPrincipal* aPrincipal,
   1512                               nsIQuotaRequest** _retval) {
   1513  MOZ_ASSERT(NS_IsMainThread());
   1514  MOZ_ASSERT(aPrincipal);
   1515  MOZ_ASSERT(_retval);
   1516 
   1517  RefPtr<Request> request = new Request(aPrincipal);
   1518 
   1519  PersistedParams params;
   1520 
   1521  nsresult rv =
   1522      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
   1523  if (NS_WARN_IF(NS_FAILED(rv))) {
   1524    return rv;
   1525  }
   1526 
   1527  RequestInfo info(request, params);
   1528 
   1529  rv = InitiateRequest(info);
   1530  if (NS_WARN_IF(NS_FAILED(rv))) {
   1531    return rv;
   1532  }
   1533 
   1534  request.forget(_retval);
   1535  return NS_OK;
   1536 }
   1537 
   1538 NS_IMETHODIMP
   1539 QuotaManagerService::Persist(nsIPrincipal* aPrincipal,
   1540                             nsIQuotaRequest** _retval) {
   1541  MOZ_ASSERT(NS_IsMainThread());
   1542  MOZ_ASSERT(aPrincipal);
   1543  MOZ_ASSERT(_retval);
   1544 
   1545  RefPtr<Request> request = new Request(aPrincipal);
   1546 
   1547  PersistParams params;
   1548 
   1549  nsresult rv =
   1550      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
   1551  if (NS_WARN_IF(NS_FAILED(rv))) {
   1552    return rv;
   1553  }
   1554 
   1555  RequestInfo info(request, params);
   1556 
   1557  rv = InitiateRequest(info);
   1558  if (NS_WARN_IF(NS_FAILED(rv))) {
   1559    return rv;
   1560  }
   1561 
   1562  request.forget(_retval);
   1563  return NS_OK;
   1564 }
   1565 
   1566 NS_IMETHODIMP
   1567 QuotaManagerService::Estimate(nsIPrincipal* aPrincipal,
   1568                              nsIQuotaRequest** _retval) {
   1569  MOZ_ASSERT(NS_IsMainThread());
   1570  MOZ_ASSERT(aPrincipal);
   1571 
   1572  RefPtr<Request> request = new Request(aPrincipal);
   1573 
   1574  EstimateParams params;
   1575 
   1576  nsresult rv =
   1577      CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
   1578  if (NS_WARN_IF(NS_FAILED(rv))) {
   1579    return rv;
   1580  }
   1581 
   1582  RequestInfo info(request, params);
   1583 
   1584  rv = InitiateRequest(info);
   1585  if (NS_WARN_IF(NS_FAILED(rv))) {
   1586    return rv;
   1587  }
   1588 
   1589  request.forget(_retval);
   1590  return NS_OK;
   1591 }
   1592 
   1593 NS_IMETHODIMP
   1594 QuotaManagerService::ListOrigins(nsIQuotaRequest** _retval) {
   1595  MOZ_ASSERT(NS_IsMainThread());
   1596 
   1597  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1598 
   1599  auto request = MakeRefPtr<Request>();
   1600 
   1601  mBackgroundActor->SendListOrigins()->Then(
   1602      GetCurrentSerialEventTarget(), __func__,
   1603      CStringArrayResponsePromiseResolveOrRejectCallback(request));
   1604 
   1605  request.forget(_retval);
   1606  return NS_OK;
   1607 }
   1608 
   1609 NS_IMETHODIMP
   1610 QuotaManagerService::ListCachedOrigins(nsIQuotaRequest** _retval) {
   1611  MOZ_ASSERT(NS_IsMainThread());
   1612 
   1613  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1614 
   1615  auto request = MakeRefPtr<Request>();
   1616 
   1617  mBackgroundActor->SendListCachedOrigins()->Then(
   1618      GetCurrentSerialEventTarget(), __func__,
   1619      CStringArrayResponsePromiseResolveOrRejectCallback(request));
   1620 
   1621  request.forget(_retval);
   1622  return NS_OK;
   1623 }
   1624 
   1625 NS_IMETHODIMP
   1626 QuotaManagerService::SetThumbnailPrivateIdentityId(
   1627    uint32_t aThumbnailPrivateIdentityId) {
   1628  MOZ_ASSERT(NS_IsMainThread());
   1629 
   1630  QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
   1631 
   1632  mBackgroundActor->SendSetThumbnailPrivateIdentityId(
   1633      aThumbnailPrivateIdentityId);
   1634 
   1635  return NS_OK;
   1636 }
   1637 
   1638 NS_IMETHODIMP
   1639 QuotaManagerService::Observe(nsISupports* aSubject, const char* aTopic,
   1640                             const char16_t* aData) {
   1641  MOZ_ASSERT(XRE_IsParentProcess());
   1642  MOZ_ASSERT(NS_IsMainThread());
   1643 
   1644  if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID)) {
   1645    RemoveIdleObserver();
   1646    return NS_OK;
   1647  }
   1648 
   1649  if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
   1650    PerformIdleMaintenance();
   1651    return NS_OK;
   1652  }
   1653 
   1654  if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
   1655    IdleMaintenanceInfo info(/* aStart */ true);
   1656 
   1657    nsresult rv = InitiateRequest(info);
   1658    if (NS_WARN_IF(NS_FAILED(rv))) {
   1659      return rv;
   1660    }
   1661 
   1662    return NS_OK;
   1663  }
   1664 
   1665  if (!strcmp(aTopic, OBSERVER_TOPIC_ACTIVE)) {
   1666    RemoveIdleObserver();
   1667 
   1668    IdleMaintenanceInfo info(/* aStart */ false);
   1669 
   1670    nsresult rv = InitiateRequest(info);
   1671    if (NS_WARN_IF(NS_FAILED(rv))) {
   1672      return rv;
   1673    }
   1674 
   1675    return NS_OK;
   1676  }
   1677 
   1678  MOZ_ASSERT_UNREACHABLE("Should never get here!");
   1679  return NS_OK;
   1680 }
   1681 
   1682 void QuotaManagerService::Notify(const hal::BatteryInformation& aBatteryInfo) {
   1683  // This notification is received when battery data changes. We don't need to
   1684  // deal with this notification.
   1685 }
   1686 
   1687 nsresult QuotaManagerService::RequestInfo::InitiateRequest(QuotaChild* aActor) {
   1688  MOZ_ASSERT(aActor);
   1689 
   1690  auto request = static_cast<Request*>(mRequest.get());
   1691 
   1692  auto actor = new QuotaRequestChild(request);
   1693 
   1694  if (!aActor->SendPQuotaRequestConstructor(actor, mParams)) {
   1695    request->SetError(NS_ERROR_FAILURE);
   1696    return NS_ERROR_FAILURE;
   1697  }
   1698 
   1699  return NS_OK;
   1700 }
   1701 
   1702 nsresult QuotaManagerService::IdleMaintenanceInfo::InitiateRequest(
   1703    QuotaChild* aActor) {
   1704  MOZ_ASSERT(aActor);
   1705 
   1706  bool result;
   1707 
   1708  if (mStart) {
   1709    result = aActor->SendStartIdleMaintenance();
   1710  } else {
   1711    result = aActor->SendStopIdleMaintenance();
   1712  }
   1713 
   1714  if (!result) {
   1715    return NS_ERROR_FAILURE;
   1716  }
   1717 
   1718  return NS_OK;
   1719 }
   1720 
   1721 }  // namespace mozilla::dom::quota