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