LCOV - code coverage report
Current view: top level - dom/quota - QuotaManagerService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 428 0.2 %
Date: 2017-07-14 16:53:18 Functions: 0 60 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=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             : #include "ActorsChild.h"
      10             : #include "mozilla/BasePrincipal.h"
      11             : #include "mozilla/ClearOnShutdown.h"
      12             : #include "mozilla/Hal.h"
      13             : #include "mozilla/Preferences.h"
      14             : #include "mozilla/Unused.h"
      15             : #include "mozilla/ipc/BackgroundChild.h"
      16             : #include "mozilla/ipc/BackgroundParent.h"
      17             : #include "mozilla/ipc/BackgroundUtils.h"
      18             : #include "mozilla/ipc/PBackgroundChild.h"
      19             : #include "nsIIdleService.h"
      20             : #include "nsIIPCBackgroundChildCreateCallback.h"
      21             : #include "nsIObserverService.h"
      22             : #include "nsIScriptSecurityManager.h"
      23             : #include "nsXULAppAPI.h"
      24             : #include "QuotaManager.h"
      25             : #include "QuotaRequests.h"
      26             : 
      27             : #define PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID "profile-before-change-qm"
      28             : 
      29             : namespace mozilla {
      30             : namespace dom {
      31             : namespace quota {
      32             : 
      33             : using namespace mozilla::ipc;
      34             : 
      35             : namespace {
      36             : 
      37             : // Preference that is used to enable testing features.
      38             : const char kTestingPref[] = "dom.quotaManager.testing";
      39             : 
      40             : const char kIdleServiceContractId[] = "@mozilla.org/widget/idleservice;1";
      41             : 
      42             : // The number of seconds we will wait after receiving the idle-daily
      43             : // notification before beginning maintenance.
      44             : const uint32_t kIdleObserverTimeSec = 1;
      45             : 
      46           3 : mozilla::StaticRefPtr<QuotaManagerService> gQuotaManagerService;
      47             : 
      48             : mozilla::Atomic<bool> gInitialized(false);
      49             : mozilla::Atomic<bool> gClosed(false);
      50             : mozilla::Atomic<bool> gTestingMode(false);
      51             : 
      52             : void
      53           0 : TestingPrefChangedCallback(const char* aPrefName,
      54             :                            void* aClosure)
      55             : {
      56           0 :   MOZ_ASSERT(NS_IsMainThread());
      57           0 :   MOZ_ASSERT(!strcmp(aPrefName, kTestingPref));
      58           0 :   MOZ_ASSERT(!aClosure);
      59             : 
      60           0 :   gTestingMode = Preferences::GetBool(aPrefName);
      61           0 : }
      62             : 
      63             : nsresult
      64           0 : CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
      65             :                                 PrincipalInfo& aPrincipalInfo)
      66             : {
      67           0 :   MOZ_ASSERT(aPrincipal);
      68             : 
      69           0 :   nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
      70           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
      71           0 :     return rv;
      72             :   }
      73             : 
      74           0 :   if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
      75           0 :       aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
      76           0 :     return NS_ERROR_UNEXPECTED;
      77             :   }
      78             : 
      79           0 :   return NS_OK;
      80             : }
      81             : 
      82           0 : class AbortOperationsRunnable final
      83             :   : public Runnable
      84             : {
      85             :   ContentParentId mContentParentId;
      86             : 
      87             : public:
      88           0 :   explicit AbortOperationsRunnable(ContentParentId aContentParentId)
      89           0 :     : Runnable("dom::quota::AbortOperationsRunnable")
      90           0 :     , mContentParentId(aContentParentId)
      91           0 :   { }
      92             : 
      93             : private:
      94             :   NS_DECL_NSIRUNNABLE
      95             : };
      96             : 
      97             : } // namespace
      98             : 
      99             : class QuotaManagerService::BackgroundCreateCallback final
     100             :   : public nsIIPCBackgroundChildCreateCallback
     101             : {
     102             :   RefPtr<QuotaManagerService> mService;
     103             : 
     104             : public:
     105             :   explicit
     106           0 :   BackgroundCreateCallback(QuotaManagerService* aService)
     107           0 :     : mService(aService)
     108             :   {
     109           0 :     MOZ_ASSERT(aService);
     110           0 :   }
     111             : 
     112             :   NS_DECL_ISUPPORTS
     113             : 
     114             : private:
     115           0 :   ~BackgroundCreateCallback()
     116           0 :   { }
     117             : 
     118             :   NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
     119             : };
     120             : 
     121             : class QuotaManagerService::PendingRequestInfo
     122             : {
     123             : protected:
     124             :   RefPtr<RequestBase> mRequest;
     125             : 
     126             : public:
     127           0 :   explicit PendingRequestInfo(RequestBase* aRequest)
     128           0 :     : mRequest(aRequest)
     129           0 :   { }
     130             : 
     131           0 :   virtual ~PendingRequestInfo()
     132           0 :   { }
     133             : 
     134             :   RequestBase*
     135           0 :   GetRequest() const
     136             :   {
     137           0 :     return mRequest;
     138             :   }
     139             : 
     140             :   virtual nsresult
     141             :   InitiateRequest(QuotaChild* aActor) = 0;
     142             : };
     143             : 
     144           0 : class QuotaManagerService::UsageRequestInfo
     145             :   : public PendingRequestInfo
     146             : {
     147             :   UsageRequestParams mParams;
     148             : 
     149             : public:
     150           0 :   UsageRequestInfo(UsageRequest* aRequest,
     151             :                    const UsageRequestParams& aParams)
     152           0 :     : PendingRequestInfo(aRequest)
     153           0 :     , mParams(aParams)
     154             :   {
     155           0 :     MOZ_ASSERT(aRequest);
     156           0 :     MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
     157           0 :   }
     158             : 
     159             :   virtual nsresult
     160             :   InitiateRequest(QuotaChild* aActor) override;
     161             : };
     162             : 
     163           0 : class QuotaManagerService::RequestInfo
     164             :   : public PendingRequestInfo
     165             : {
     166             :   RequestParams mParams;
     167             : 
     168             : public:
     169           0 :   RequestInfo(Request* aRequest,
     170             :               const RequestParams& aParams)
     171           0 :     : PendingRequestInfo(aRequest)
     172           0 :     , mParams(aParams)
     173             :   {
     174           0 :     MOZ_ASSERT(aRequest);
     175           0 :     MOZ_ASSERT(aParams.type() != RequestParams::T__None);
     176           0 :   }
     177             : 
     178             :   virtual nsresult
     179             :   InitiateRequest(QuotaChild* aActor) override;
     180             : };
     181             : 
     182           0 : class QuotaManagerService::IdleMaintenanceInfo
     183             :   : public PendingRequestInfo
     184             : {
     185             :   const bool mStart;
     186             : 
     187             : public:
     188           0 :   explicit IdleMaintenanceInfo(bool aStart)
     189           0 :     : PendingRequestInfo(nullptr)
     190           0 :     , mStart(aStart)
     191           0 :   { }
     192             : 
     193             :   virtual nsresult
     194             :   InitiateRequest(QuotaChild* aActor) override;
     195             : };
     196             : 
     197           0 : QuotaManagerService::QuotaManagerService()
     198             :   : mBackgroundActor(nullptr)
     199             :   , mBackgroundActorFailed(false)
     200           0 :   , mIdleObserverRegistered(false)
     201             : {
     202           0 :   MOZ_ASSERT(NS_IsMainThread());
     203           0 : }
     204             : 
     205           0 : QuotaManagerService::~QuotaManagerService()
     206             : {
     207           0 :   MOZ_ASSERT(NS_IsMainThread());
     208           0 :   MOZ_ASSERT(!mIdleObserverRegistered);
     209           0 : }
     210             : 
     211             : // static
     212             : QuotaManagerService*
     213           0 : QuotaManagerService::GetOrCreate()
     214             : {
     215           0 :   MOZ_ASSERT(NS_IsMainThread());
     216             : 
     217           0 :   if (gClosed) {
     218           0 :     MOZ_ASSERT(false, "Calling GetOrCreate() after shutdown!");
     219             :     return nullptr;
     220             :   }
     221             : 
     222           0 :   if (!gQuotaManagerService) {
     223           0 :     RefPtr<QuotaManagerService> instance(new QuotaManagerService());
     224             : 
     225           0 :     nsresult rv = instance->Init();
     226           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     227           0 :       return nullptr;
     228             :     }
     229             : 
     230           0 :     if (gInitialized.exchange(true)) {
     231           0 :       MOZ_ASSERT(false, "Initialized more than once?!");
     232             :     }
     233             : 
     234           0 :     gQuotaManagerService = instance;
     235             : 
     236           0 :     ClearOnShutdown(&gQuotaManagerService);
     237             :   }
     238             : 
     239           0 :   return gQuotaManagerService;
     240             : }
     241             : 
     242             : // static
     243             : QuotaManagerService*
     244           0 : QuotaManagerService::Get()
     245             : {
     246             :   // Does not return an owning reference.
     247           0 :   return gQuotaManagerService;
     248             : }
     249             : 
     250             : // static
     251             : QuotaManagerService*
     252           0 : QuotaManagerService::FactoryCreate()
     253             : {
     254             :   // Returns a raw pointer that carries an owning reference! Lame, but the
     255             :   // singleton factory macros force this.
     256           0 :   QuotaManagerService* quotaManagerService = GetOrCreate();
     257           0 :   NS_IF_ADDREF(quotaManagerService);
     258           0 :   return quotaManagerService;
     259             : }
     260             : 
     261             : void
     262           0 : QuotaManagerService::ClearBackgroundActor()
     263             : {
     264           0 :   MOZ_ASSERT(NS_IsMainThread());
     265             : 
     266           0 :   mBackgroundActor = nullptr;
     267           0 : }
     268             : 
     269             : void
     270           0 : QuotaManagerService::NoteLiveManager(QuotaManager* aManager)
     271             : {
     272           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     273           0 :   MOZ_ASSERT(NS_IsMainThread());
     274           0 :   MOZ_ASSERT(aManager);
     275             : 
     276           0 :   mBackgroundThread = aManager->OwningThread();
     277           0 : }
     278             : 
     279             : void
     280           0 : QuotaManagerService::NoteShuttingDownManager()
     281             : {
     282           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     283           0 :   MOZ_ASSERT(NS_IsMainThread());
     284             : 
     285           0 :   mBackgroundThread = nullptr;
     286           0 : }
     287             : 
     288             : void
     289           0 : QuotaManagerService::AbortOperationsForProcess(ContentParentId aContentParentId)
     290             : {
     291           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     292           0 :   MOZ_ASSERT(NS_IsMainThread());
     293             : 
     294           0 :   if (!mBackgroundThread) {
     295           0 :     return;
     296             :   }
     297             : 
     298             :   RefPtr<AbortOperationsRunnable> runnable =
     299           0 :     new AbortOperationsRunnable(aContentParentId);
     300             : 
     301           0 :   MOZ_ALWAYS_SUCCEEDS(
     302             :     mBackgroundThread->Dispatch(runnable, NS_DISPATCH_NORMAL));
     303             : }
     304             : 
     305             : nsresult
     306           0 : QuotaManagerService::Init()
     307             : {
     308           0 :   MOZ_ASSERT(NS_IsMainThread());
     309             : 
     310           0 :   if (XRE_IsParentProcess()) {
     311             :     nsCOMPtr<nsIObserverService> observerService =
     312           0 :       mozilla::services::GetObserverService();
     313           0 :     if (NS_WARN_IF(!observerService)) {
     314           0 :       return NS_ERROR_FAILURE;
     315             :     }
     316             : 
     317             :     nsresult rv =
     318           0 :       observerService->AddObserver(this,
     319             :                                    PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID,
     320           0 :                                    false);
     321           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     322           0 :       return rv;
     323             :     }
     324             :   }
     325             : 
     326             :   Preferences::RegisterCallbackAndCall(TestingPrefChangedCallback,
     327           0 :                                        kTestingPref);
     328             : 
     329           0 :   return NS_OK;
     330             : }
     331             : 
     332             : void
     333           0 : QuotaManagerService::Destroy()
     334             : {
     335             :   // Setting the closed flag prevents the service from being recreated.
     336             :   // Don't set it though if there's no real instance created.
     337           0 :   if (gInitialized && gClosed.exchange(true)) {
     338           0 :     MOZ_ASSERT(false, "Shutdown more than once?!");
     339             :   }
     340             : 
     341           0 :   Preferences::UnregisterCallback(TestingPrefChangedCallback, kTestingPref);
     342             : 
     343           0 :   delete this;
     344           0 : }
     345             : 
     346             : nsresult
     347           0 : QuotaManagerService::InitiateRequest(nsAutoPtr<PendingRequestInfo>& aInfo)
     348             : {
     349             :   // Nothing can be done here if we have previously failed to create a
     350             :   // background actor.
     351           0 :   if (mBackgroundActorFailed) {
     352           0 :     return NS_ERROR_FAILURE;
     353             :   }
     354             : 
     355           0 :   if (!mBackgroundActor && mPendingRequests.IsEmpty()) {
     356           0 :     if (PBackgroundChild* actor = BackgroundChild::GetForCurrentThread()) {
     357           0 :       BackgroundActorCreated(actor);
     358             :     } else {
     359             :       // We need to start the sequence to create a background actor for this
     360             :       // thread.
     361           0 :       RefPtr<BackgroundCreateCallback> cb = new BackgroundCreateCallback(this);
     362           0 :       if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) {
     363           0 :         return NS_ERROR_FAILURE;
     364             :       }
     365             :     }
     366             :   }
     367             : 
     368             :   // If we already have a background actor then we can start this request now.
     369           0 :   if (mBackgroundActor) {
     370           0 :     nsresult rv = aInfo->InitiateRequest(mBackgroundActor);
     371           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     372           0 :       return rv;
     373             :     }
     374             :   } else {
     375           0 :     mPendingRequests.AppendElement(aInfo.forget());
     376             :   }
     377             : 
     378           0 :   return NS_OK;
     379             : }
     380             : 
     381             : nsresult
     382           0 : QuotaManagerService::BackgroundActorCreated(PBackgroundChild* aBackgroundActor)
     383             : {
     384           0 :   MOZ_ASSERT(NS_IsMainThread());
     385           0 :   MOZ_ASSERT(aBackgroundActor);
     386           0 :   MOZ_ASSERT(!mBackgroundActor);
     387           0 :   MOZ_ASSERT(!mBackgroundActorFailed);
     388             : 
     389             :   {
     390           0 :     QuotaChild* actor = new QuotaChild(this);
     391             : 
     392           0 :     mBackgroundActor =
     393           0 :       static_cast<QuotaChild*>(aBackgroundActor->SendPQuotaConstructor(actor));
     394             :   }
     395             : 
     396           0 :   if (NS_WARN_IF(!mBackgroundActor)) {
     397           0 :     BackgroundActorFailed();
     398           0 :     return NS_ERROR_FAILURE;
     399             :   }
     400             : 
     401           0 :   nsresult rv = NS_OK;
     402             : 
     403           0 :   for (uint32_t index = 0, count = mPendingRequests.Length();
     404           0 :        index < count;
     405             :        index++) {
     406           0 :     nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
     407             : 
     408           0 :     nsresult rv2 = info->InitiateRequest(mBackgroundActor);
     409             : 
     410             :     // Warn for every failure, but just return the first failure if there are
     411             :     // multiple failures.
     412           0 :     if (NS_WARN_IF(NS_FAILED(rv2)) && NS_SUCCEEDED(rv)) {
     413           0 :       rv = rv2;
     414             :     }
     415             :   }
     416             : 
     417           0 :   mPendingRequests.Clear();
     418             : 
     419           0 :   return rv;
     420             : }
     421             : 
     422             : void
     423           0 : QuotaManagerService::BackgroundActorFailed()
     424             : {
     425           0 :   MOZ_ASSERT(NS_IsMainThread());
     426           0 :   MOZ_ASSERT(!mPendingRequests.IsEmpty());
     427           0 :   MOZ_ASSERT(!mBackgroundActor);
     428           0 :   MOZ_ASSERT(!mBackgroundActorFailed);
     429             : 
     430           0 :   mBackgroundActorFailed = true;
     431             : 
     432           0 :   for (uint32_t index = 0, count = mPendingRequests.Length();
     433           0 :        index < count;
     434             :        index++) {
     435           0 :     nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
     436             : 
     437           0 :     RequestBase* request = info->GetRequest();
     438           0 :     if (request) {
     439           0 :       request->SetError(NS_ERROR_FAILURE);
     440             :     }
     441             :   }
     442             : 
     443           0 :   mPendingRequests.Clear();
     444           0 : }
     445             : 
     446             : void
     447           0 : QuotaManagerService::PerformIdleMaintenance()
     448             : {
     449             :   using namespace mozilla::hal;
     450             : 
     451           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     452           0 :   MOZ_ASSERT(NS_IsMainThread());
     453             : 
     454             :   // If we're running on battery power then skip all idle maintenance since we
     455             :   // would otherwise be doing lots of disk I/O.
     456           0 :   BatteryInformation batteryInfo;
     457             : 
     458             : #ifdef MOZ_WIDGET_ANDROID
     459             :   // Android XPCShell doesn't load the AndroidBridge that is needed to make
     460             :   // GetCurrentBatteryInformation work...
     461             :   if (!QuotaManager::IsRunningXPCShellTests())
     462             : #endif
     463             :   {
     464             :     // In order to give the correct battery level, hal must have registered
     465             :     // battery observers.
     466           0 :     RegisterBatteryObserver(this);
     467           0 :     GetCurrentBatteryInformation(&batteryInfo);
     468           0 :     UnregisterBatteryObserver(this);
     469             :   }
     470             : 
     471             :   // If we're running XPCShell because we always want to be able to test this
     472             :   // code so pretend that we're always charging.
     473           0 :   if (QuotaManager::IsRunningXPCShellTests()) {
     474           0 :     batteryInfo.level() = 100;
     475           0 :     batteryInfo.charging() = true;
     476             :   }
     477             : 
     478           0 :   if (NS_WARN_IF(!batteryInfo.charging())) {
     479           0 :     return;
     480             :   }
     481             : 
     482           0 :   if (QuotaManager::IsRunningXPCShellTests()) {
     483             :     // We don't want user activity to impact this code if we're running tests.
     484           0 :     Unused << Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
     485           0 :   } else if (!mIdleObserverRegistered) {
     486             :     nsCOMPtr<nsIIdleService> idleService =
     487           0 :       do_GetService(kIdleServiceContractId);
     488           0 :     MOZ_ASSERT(idleService);
     489             : 
     490           0 :     MOZ_ALWAYS_SUCCEEDS(
     491             :       idleService->AddIdleObserver(this, kIdleObserverTimeSec));
     492             : 
     493           0 :     mIdleObserverRegistered = true;
     494             :   }
     495             : }
     496             : 
     497             : void
     498           0 : QuotaManagerService::RemoveIdleObserver()
     499             : {
     500           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     501           0 :   MOZ_ASSERT(NS_IsMainThread());
     502             : 
     503           0 :   if (mIdleObserverRegistered) {
     504             :     nsCOMPtr<nsIIdleService> idleService =
     505           0 :       do_GetService(kIdleServiceContractId);
     506           0 :     MOZ_ASSERT(idleService);
     507             : 
     508             :     // Ignore the return value of RemoveIdleObserver, it may fail if the
     509             :     // observer has already been unregistered during shutdown.
     510             :     Unused <<
     511           0 :       idleService->RemoveIdleObserver(this, kIdleObserverTimeSec);
     512             : 
     513           0 :     mIdleObserverRegistered = false;
     514             :   }
     515           0 : }
     516             : 
     517           0 : NS_IMPL_ADDREF(QuotaManagerService)
     518           0 : NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
     519           0 : NS_IMPL_QUERY_INTERFACE(QuotaManagerService,
     520             :                         nsIQuotaManagerService,
     521             :                         nsIObserver)
     522             : 
     523             : NS_IMETHODIMP
     524           0 : QuotaManagerService::Init(nsIQuotaRequest** _retval)
     525             : {
     526           0 :   MOZ_ASSERT(NS_IsMainThread());
     527           0 :   MOZ_ASSERT(nsContentUtils::IsCallerChrome());
     528             : 
     529           0 :   if (NS_WARN_IF(!gTestingMode)) {
     530           0 :     return NS_ERROR_UNEXPECTED;
     531             :   }
     532             : 
     533           0 :   RefPtr<Request> request = new Request();
     534             : 
     535           0 :   InitParams params;
     536             : 
     537           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     538             : 
     539           0 :   nsresult rv = InitiateRequest(info);
     540           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     541           0 :     return rv;
     542             :   }
     543             : 
     544           0 :   request.forget(_retval);
     545           0 :   return NS_OK;
     546             : }
     547             : 
     548             : NS_IMETHODIMP
     549           0 : QuotaManagerService::InitStoragesForPrincipal(
     550             :                                              nsIPrincipal* aPrincipal,
     551             :                                              const nsACString& aPersistenceType,
     552             :                                              nsIQuotaRequest** _retval)
     553             : {
     554           0 :   MOZ_ASSERT(NS_IsMainThread());
     555           0 :   MOZ_ASSERT(nsContentUtils::IsCallerChrome());
     556             : 
     557           0 :   if (NS_WARN_IF(!gTestingMode)) {
     558           0 :     return NS_ERROR_UNEXPECTED;
     559             :   }
     560             : 
     561           0 :   RefPtr<Request> request = new Request();
     562             : 
     563           0 :   InitOriginParams params;
     564             : 
     565             :   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
     566           0 :                                                 params.principalInfo());
     567           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     568           0 :     return rv;
     569             :   }
     570             : 
     571           0 :   Nullable<PersistenceType> persistenceType;
     572           0 :   rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
     573           0 :   if (NS_WARN_IF(NS_FAILED(rv)) || persistenceType.IsNull()) {
     574           0 :     return NS_ERROR_INVALID_ARG;
     575             :   }
     576             : 
     577           0 :   params.persistenceType() = persistenceType.Value();
     578             : 
     579           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     580             : 
     581           0 :   rv = InitiateRequest(info);
     582           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     583           0 :     return rv;
     584             :   }
     585             : 
     586           0 :   request.forget(_retval);
     587           0 :   return NS_OK;
     588             : }
     589             : 
     590             : NS_IMETHODIMP
     591           0 : QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback,
     592             :                               bool aGetAll,
     593             :                               nsIQuotaUsageRequest** _retval)
     594             : {
     595           0 :   MOZ_ASSERT(NS_IsMainThread());
     596           0 :   MOZ_ASSERT(aCallback);
     597             : 
     598           0 :   RefPtr<UsageRequest> request = new UsageRequest(aCallback);
     599             : 
     600           0 :   AllUsageParams params;
     601             : 
     602           0 :   params.getAll() = aGetAll;
     603             : 
     604           0 :   nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
     605             : 
     606           0 :   nsresult rv = InitiateRequest(info);
     607           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     608           0 :     return rv;
     609             :   }
     610             : 
     611           0 :   request.forget(_retval);
     612           0 :   return NS_OK;
     613             : }
     614             : 
     615             : NS_IMETHODIMP
     616           0 : QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
     617             :                                           nsIQuotaUsageCallback* aCallback,
     618             :                                           bool aGetGroupUsage,
     619             :                                           nsIQuotaUsageRequest** _retval)
     620             : {
     621           0 :   MOZ_ASSERT(NS_IsMainThread());
     622           0 :   MOZ_ASSERT(aPrincipal);
     623           0 :   MOZ_ASSERT(aCallback);
     624             : 
     625           0 :   RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
     626             : 
     627           0 :   OriginUsageParams params;
     628             : 
     629             :   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
     630           0 :                                                 params.principalInfo());
     631           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     632           0 :     return rv;
     633             :   }
     634             : 
     635           0 :   params.getGroupUsage() = aGetGroupUsage;
     636             : 
     637           0 :   nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
     638             : 
     639           0 :   rv = InitiateRequest(info);
     640           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     641           0 :     return rv;
     642             :   }
     643             : 
     644           0 :   request.forget(_retval);
     645           0 :   return NS_OK;
     646             : }
     647             : 
     648             : NS_IMETHODIMP
     649           0 : QuotaManagerService::Clear(nsIQuotaRequest** _retval)
     650             : {
     651           0 :   MOZ_ASSERT(NS_IsMainThread());
     652             : 
     653           0 :   if (NS_WARN_IF(!gTestingMode)) {
     654           0 :     return NS_ERROR_UNEXPECTED;
     655             :   }
     656             : 
     657           0 :   RefPtr<Request> request = new Request();
     658             : 
     659           0 :   ClearAllParams params;
     660             : 
     661           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     662             : 
     663           0 :   nsresult rv = InitiateRequest(info);
     664           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     665           0 :     return rv;
     666             :   }
     667             : 
     668           0 :   request.forget(_retval);
     669           0 :   return NS_OK;
     670             : }
     671             : 
     672             : NS_IMETHODIMP
     673           0 : QuotaManagerService::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
     674             :                                                const nsACString& aPersistenceType,
     675             :                                                bool aClearAll,
     676             :                                                nsIQuotaRequest** _retval)
     677             : {
     678           0 :   MOZ_ASSERT(NS_IsMainThread());
     679           0 :   MOZ_ASSERT(aPrincipal);
     680             : 
     681           0 :   nsCString suffix;
     682           0 :   aPrincipal->OriginAttributesRef().CreateSuffix(suffix);
     683             : 
     684           0 :   if (NS_WARN_IF(aClearAll && !suffix.IsEmpty())) {
     685             :     // The originAttributes should be default originAttributes when the
     686             :     // aClearAll flag is set.
     687           0 :     return NS_ERROR_INVALID_ARG;
     688             :   }
     689             : 
     690           0 :   RefPtr<Request> request = new Request(aPrincipal);
     691             : 
     692           0 :   ClearOriginParams params;
     693             : 
     694             :   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
     695           0 :                                                 params.principalInfo());
     696           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     697           0 :     return rv;
     698             :   }
     699             : 
     700           0 :   Nullable<PersistenceType> persistenceType;
     701           0 :   rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
     702           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     703           0 :     return NS_ERROR_INVALID_ARG;
     704             :   }
     705             : 
     706           0 :   if (persistenceType.IsNull()) {
     707           0 :     params.persistenceTypeIsExplicit() = false;
     708             :   } else {
     709           0 :     params.persistenceType() = persistenceType.Value();
     710           0 :     params.persistenceTypeIsExplicit() = true;
     711             :   }
     712             : 
     713           0 :   params.clearAll() = aClearAll;
     714             : 
     715           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     716             : 
     717           0 :   rv = InitiateRequest(info);
     718           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     719           0 :     return rv;
     720             :   }
     721             : 
     722           0 :   request.forget(_retval);
     723           0 :   return NS_OK;
     724             : }
     725             : 
     726             : NS_IMETHODIMP
     727           0 : QuotaManagerService::Reset(nsIQuotaRequest** _retval)
     728             : {
     729           0 :   MOZ_ASSERT(NS_IsMainThread());
     730             : 
     731           0 :   if (NS_WARN_IF(!gTestingMode)) {
     732           0 :     return NS_ERROR_UNEXPECTED;
     733             :   }
     734             : 
     735           0 :   RefPtr<Request> request = new Request();
     736             : 
     737           0 :   ResetAllParams params;
     738             : 
     739           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     740             : 
     741           0 :   nsresult rv = InitiateRequest(info);
     742           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     743           0 :     return rv;
     744             :   }
     745             : 
     746           0 :   request.forget(_retval);
     747           0 :   return NS_OK;
     748             : }
     749             : 
     750             : NS_IMETHODIMP
     751           0 : QuotaManagerService::Persisted(nsIPrincipal* aPrincipal,
     752             :                                nsIQuotaRequest** _retval)
     753             : {
     754           0 :   MOZ_ASSERT(NS_IsMainThread());
     755           0 :   MOZ_ASSERT(aPrincipal);
     756           0 :   MOZ_ASSERT(_retval);
     757             : 
     758           0 :   RefPtr<Request> request = new Request(aPrincipal);
     759             : 
     760           0 :   PersistedParams params;
     761             : 
     762             :   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
     763           0 :                                                 params.principalInfo());
     764           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     765           0 :     return rv;
     766             :   }
     767             : 
     768           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     769             : 
     770           0 :   rv = InitiateRequest(info);
     771           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     772           0 :     return rv;
     773             :   }
     774             : 
     775           0 :   request.forget(_retval);
     776           0 :   return NS_OK;
     777             : }
     778             : 
     779             : NS_IMETHODIMP
     780           0 : QuotaManagerService::Persist(nsIPrincipal* aPrincipal,
     781             :                              nsIQuotaRequest** _retval)
     782             : {
     783           0 :   MOZ_ASSERT(NS_IsMainThread());
     784           0 :   MOZ_ASSERT(aPrincipal);
     785           0 :   MOZ_ASSERT(_retval);
     786             : 
     787           0 :   RefPtr<Request> request = new Request(aPrincipal);
     788             : 
     789           0 :   PersistParams params;
     790             : 
     791             :   nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
     792           0 :                                                 params.principalInfo());
     793           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     794           0 :     return rv;
     795             :   }
     796             : 
     797           0 :   nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     798             : 
     799           0 :   rv = InitiateRequest(info);
     800           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     801           0 :     return rv;
     802             :   }
     803             : 
     804           0 :   request.forget(_retval);
     805           0 :   return NS_OK;
     806             : }
     807             : 
     808             : NS_IMETHODIMP
     809           0 : QuotaManagerService::Observe(nsISupports* aSubject,
     810             :                              const char* aTopic,
     811             :                              const char16_t* aData)
     812             : {
     813           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     814           0 :   MOZ_ASSERT(NS_IsMainThread());
     815             : 
     816           0 :   if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID)) {
     817           0 :     RemoveIdleObserver();
     818           0 :     return NS_OK;
     819             :   }
     820             : 
     821           0 :   if (!strcmp(aTopic, "clear-origin-attributes-data")) {
     822           0 :     RefPtr<Request> request = new Request();
     823             : 
     824           0 :     ClearDataParams params;
     825           0 :     params.pattern() = nsDependentString(aData);
     826             : 
     827           0 :     nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
     828             : 
     829           0 :     nsresult rv = InitiateRequest(info);
     830           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     831           0 :       return rv;
     832             :     }
     833             : 
     834           0 :     return NS_OK;
     835             :   }
     836             : 
     837           0 :   if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
     838           0 :     PerformIdleMaintenance();
     839           0 :     return NS_OK;
     840             :   }
     841             : 
     842           0 :   if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
     843             :     nsAutoPtr<PendingRequestInfo> info(
     844           0 :       new IdleMaintenanceInfo(/* aStart */ true));
     845             : 
     846           0 :     nsresult rv = InitiateRequest(info);
     847           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     848           0 :       return rv;
     849             :     }
     850             : 
     851           0 :     return NS_OK;
     852             :   }
     853             : 
     854           0 :   if (!strcmp(aTopic, OBSERVER_TOPIC_ACTIVE)) {
     855           0 :     RemoveIdleObserver();
     856             : 
     857             :     nsAutoPtr<PendingRequestInfo> info(
     858           0 :       new IdleMaintenanceInfo(/* aStart */ false));
     859             : 
     860           0 :     nsresult rv = InitiateRequest(info);
     861           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     862           0 :       return rv;
     863             :     }
     864             : 
     865           0 :     return NS_OK;
     866             :   }
     867             : 
     868           0 :   MOZ_ASSERT_UNREACHABLE("Should never get here!");
     869             :   return NS_OK;
     870             : }
     871             : 
     872             : void
     873           0 : QuotaManagerService::Notify(const hal::BatteryInformation& aBatteryInfo)
     874             : {
     875             :   // This notification is received when battery data changes. We don't need to
     876             :   // deal with this notification.
     877           0 : }
     878             : 
     879             : NS_IMETHODIMP
     880           0 : AbortOperationsRunnable::Run()
     881             : {
     882           0 :   AssertIsOnBackgroundThread();
     883             : 
     884           0 :   if (QuotaManager::IsShuttingDown()) {
     885           0 :     return NS_OK;
     886             :   }
     887             : 
     888           0 :   QuotaManager* quotaManager = QuotaManager::Get();
     889           0 :   if (!quotaManager) {
     890           0 :     return NS_OK;
     891             :   }
     892             : 
     893           0 :   quotaManager->AbortOperationsForProcess(mContentParentId);
     894             : 
     895           0 :   return NS_OK;
     896             : }
     897             : 
     898           0 : NS_IMPL_ISUPPORTS(QuotaManagerService::BackgroundCreateCallback,
     899             :                   nsIIPCBackgroundChildCreateCallback)
     900             : 
     901             : void
     902           0 : QuotaManagerService::
     903             : BackgroundCreateCallback::ActorCreated(PBackgroundChild* aActor)
     904             : {
     905           0 :   MOZ_ASSERT(NS_IsMainThread());
     906           0 :   MOZ_ASSERT(aActor);
     907           0 :   MOZ_ASSERT(mService);
     908             : 
     909           0 :   RefPtr<QuotaManagerService> service;
     910           0 :   mService.swap(service);
     911             : 
     912           0 :   service->BackgroundActorCreated(aActor);
     913           0 : }
     914             : 
     915             : void
     916           0 : QuotaManagerService::
     917             : BackgroundCreateCallback::ActorFailed()
     918             : {
     919           0 :   MOZ_ASSERT(NS_IsMainThread());
     920           0 :   MOZ_ASSERT(mService);
     921             : 
     922           0 :   RefPtr<QuotaManagerService> service;
     923           0 :   mService.swap(service);
     924             : 
     925           0 :   service->BackgroundActorFailed();
     926           0 : }
     927             : 
     928             : nsresult
     929           0 : QuotaManagerService::
     930             : UsageRequestInfo::InitiateRequest(QuotaChild* aActor)
     931             : {
     932           0 :   MOZ_ASSERT(aActor);
     933             : 
     934           0 :   auto request = static_cast<UsageRequest*>(mRequest.get());
     935             : 
     936           0 :   auto actor = new QuotaUsageRequestChild(request);
     937             : 
     938           0 :   if (!aActor->SendPQuotaUsageRequestConstructor(actor, mParams)) {
     939           0 :     request->SetError(NS_ERROR_FAILURE);
     940           0 :     return NS_ERROR_FAILURE;
     941             :   }
     942             : 
     943           0 :   request->SetBackgroundActor(actor);
     944             : 
     945           0 :   return NS_OK;
     946             : }
     947             : 
     948             : nsresult
     949           0 : QuotaManagerService::
     950             : RequestInfo::InitiateRequest(QuotaChild* aActor)
     951             : {
     952           0 :   MOZ_ASSERT(aActor);
     953             : 
     954           0 :   auto request = static_cast<Request*>(mRequest.get());
     955             : 
     956           0 :   auto actor = new QuotaRequestChild(request);
     957             : 
     958           0 :   if (!aActor->SendPQuotaRequestConstructor(actor, mParams)) {
     959           0 :     request->SetError(NS_ERROR_FAILURE);
     960           0 :     return NS_ERROR_FAILURE;
     961             :   }
     962             : 
     963           0 :   return NS_OK;
     964             : }
     965             : 
     966             : nsresult
     967           0 : QuotaManagerService::
     968             : IdleMaintenanceInfo::InitiateRequest(QuotaChild* aActor)
     969             : {
     970           0 :   MOZ_ASSERT(aActor);
     971             : 
     972             :   bool result;
     973             : 
     974           0 :   if (mStart) {
     975           0 :     result = aActor->SendStartIdleMaintenance();
     976             :   } else {
     977           0 :     result = aActor->SendStopIdleMaintenance();
     978             :   }
     979             : 
     980           0 :   if (!result) {
     981           0 :     return NS_ERROR_FAILURE;
     982             :   }
     983             : 
     984           0 :   return NS_OK;
     985             : }
     986             : 
     987             : } // namespace quota
     988             : } // namespace dom
     989             : } // namespace mozilla

Generated by: LCOV version 1.13