QuotaManagerService.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "QuotaManagerService.h"
  6. #include "ActorsChild.h"
  7. #include "mozilla/BasePrincipal.h"
  8. #include "mozilla/ClearOnShutdown.h"
  9. #include "mozilla/Hal.h"
  10. #include "mozilla/Preferences.h"
  11. #include "mozilla/Unused.h"
  12. #include "mozilla/ipc/BackgroundChild.h"
  13. #include "mozilla/ipc/BackgroundParent.h"
  14. #include "mozilla/ipc/BackgroundUtils.h"
  15. #include "mozilla/ipc/PBackgroundChild.h"
  16. #include "nsContentUtils.h"
  17. #include "nsIIdleService.h"
  18. #include "nsIIPCBackgroundChildCreateCallback.h"
  19. #include "nsIObserverService.h"
  20. #include "nsIScriptSecurityManager.h"
  21. #include "nsXULAppAPI.h"
  22. #include "QuotaManager.h"
  23. #include "QuotaRequests.h"
  24. #define PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID "profile-before-change-qm"
  25. namespace mozilla {
  26. namespace dom {
  27. namespace quota {
  28. using namespace mozilla::ipc;
  29. namespace {
  30. // Preference that is used to enable testing features.
  31. const char kTestingPref[] = "dom.quotaManager.testing";
  32. const char kIdleServiceContractId[] = "@mozilla.org/widget/idleservice;1";
  33. // The number of seconds we will wait after receiving the idle-daily
  34. // notification before beginning maintenance.
  35. const uint32_t kIdleObserverTimeSec = 1;
  36. mozilla::StaticRefPtr<QuotaManagerService> gQuotaManagerService;
  37. mozilla::Atomic<bool> gInitialized(false);
  38. mozilla::Atomic<bool> gClosed(false);
  39. mozilla::Atomic<bool> gTestingMode(false);
  40. void
  41. TestingPrefChangedCallback(const char* aPrefName,
  42. void* aClosure)
  43. {
  44. MOZ_ASSERT(NS_IsMainThread());
  45. MOZ_ASSERT(!strcmp(aPrefName, kTestingPref));
  46. MOZ_ASSERT(!aClosure);
  47. gTestingMode = Preferences::GetBool(aPrefName);
  48. }
  49. class AbortOperationsRunnable final
  50. : public Runnable
  51. {
  52. ContentParentId mContentParentId;
  53. public:
  54. explicit AbortOperationsRunnable(ContentParentId aContentParentId)
  55. : mContentParentId(aContentParentId)
  56. { }
  57. private:
  58. NS_DECL_NSIRUNNABLE
  59. };
  60. } // namespace
  61. class QuotaManagerService::BackgroundCreateCallback final
  62. : public nsIIPCBackgroundChildCreateCallback
  63. {
  64. RefPtr<QuotaManagerService> mService;
  65. public:
  66. explicit
  67. BackgroundCreateCallback(QuotaManagerService* aService)
  68. : mService(aService)
  69. {
  70. MOZ_ASSERT(aService);
  71. }
  72. NS_DECL_ISUPPORTS
  73. private:
  74. ~BackgroundCreateCallback()
  75. { }
  76. NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
  77. };
  78. class QuotaManagerService::PendingRequestInfo
  79. {
  80. protected:
  81. RefPtr<RequestBase> mRequest;
  82. public:
  83. explicit PendingRequestInfo(RequestBase* aRequest)
  84. : mRequest(aRequest)
  85. { }
  86. virtual ~PendingRequestInfo()
  87. { }
  88. RequestBase*
  89. GetRequest() const
  90. {
  91. return mRequest;
  92. }
  93. virtual nsresult
  94. InitiateRequest(QuotaChild* aActor) = 0;
  95. };
  96. class QuotaManagerService::UsageRequestInfo
  97. : public PendingRequestInfo
  98. {
  99. UsageRequestParams mParams;
  100. public:
  101. UsageRequestInfo(UsageRequest* aRequest,
  102. const UsageRequestParams& aParams)
  103. : PendingRequestInfo(aRequest)
  104. , mParams(aParams)
  105. {
  106. MOZ_ASSERT(aRequest);
  107. MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
  108. }
  109. virtual nsresult
  110. InitiateRequest(QuotaChild* aActor) override;
  111. };
  112. class QuotaManagerService::RequestInfo
  113. : public PendingRequestInfo
  114. {
  115. RequestParams mParams;
  116. public:
  117. RequestInfo(Request* aRequest,
  118. const RequestParams& aParams)
  119. : PendingRequestInfo(aRequest)
  120. , mParams(aParams)
  121. {
  122. MOZ_ASSERT(aRequest);
  123. MOZ_ASSERT(aParams.type() != RequestParams::T__None);
  124. }
  125. virtual nsresult
  126. InitiateRequest(QuotaChild* aActor) override;
  127. };
  128. class QuotaManagerService::IdleMaintenanceInfo
  129. : public PendingRequestInfo
  130. {
  131. const bool mStart;
  132. public:
  133. explicit IdleMaintenanceInfo(bool aStart)
  134. : PendingRequestInfo(nullptr)
  135. , mStart(aStart)
  136. { }
  137. virtual nsresult
  138. InitiateRequest(QuotaChild* aActor) override;
  139. };
  140. QuotaManagerService::QuotaManagerService()
  141. : mBackgroundActor(nullptr)
  142. , mBackgroundActorFailed(false)
  143. , mIdleObserverRegistered(false)
  144. {
  145. MOZ_ASSERT(NS_IsMainThread());
  146. }
  147. QuotaManagerService::~QuotaManagerService()
  148. {
  149. MOZ_ASSERT(NS_IsMainThread());
  150. MOZ_ASSERT(!mIdleObserverRegistered);
  151. }
  152. // static
  153. QuotaManagerService*
  154. QuotaManagerService::GetOrCreate()
  155. {
  156. MOZ_ASSERT(NS_IsMainThread());
  157. if (gClosed) {
  158. MOZ_ASSERT(false, "Calling GetOrCreate() after shutdown!");
  159. return nullptr;
  160. }
  161. if (!gQuotaManagerService) {
  162. RefPtr<QuotaManagerService> instance(new QuotaManagerService());
  163. nsresult rv = instance->Init();
  164. if (NS_WARN_IF(NS_FAILED(rv))) {
  165. return nullptr;
  166. }
  167. if (gInitialized.exchange(true)) {
  168. MOZ_ASSERT(false, "Initialized more than once?!");
  169. }
  170. gQuotaManagerService = instance;
  171. ClearOnShutdown(&gQuotaManagerService);
  172. }
  173. return gQuotaManagerService;
  174. }
  175. // static
  176. QuotaManagerService*
  177. QuotaManagerService::Get()
  178. {
  179. // Does not return an owning reference.
  180. return gQuotaManagerService;
  181. }
  182. // static
  183. QuotaManagerService*
  184. QuotaManagerService::FactoryCreate()
  185. {
  186. // Returns a raw pointer that carries an owning reference! Lame, but the
  187. // singleton factory macros force this.
  188. QuotaManagerService* quotaManagerService = GetOrCreate();
  189. NS_IF_ADDREF(quotaManagerService);
  190. return quotaManagerService;
  191. }
  192. void
  193. QuotaManagerService::ClearBackgroundActor()
  194. {
  195. MOZ_ASSERT(NS_IsMainThread());
  196. mBackgroundActor = nullptr;
  197. }
  198. void
  199. QuotaManagerService::NoteLiveManager(QuotaManager* aManager)
  200. {
  201. MOZ_ASSERT(XRE_IsParentProcess());
  202. MOZ_ASSERT(NS_IsMainThread());
  203. MOZ_ASSERT(aManager);
  204. mBackgroundThread = aManager->OwningThread();
  205. }
  206. void
  207. QuotaManagerService::NoteShuttingDownManager()
  208. {
  209. MOZ_ASSERT(XRE_IsParentProcess());
  210. MOZ_ASSERT(NS_IsMainThread());
  211. mBackgroundThread = nullptr;
  212. }
  213. void
  214. QuotaManagerService::AbortOperationsForProcess(ContentParentId aContentParentId)
  215. {
  216. MOZ_ASSERT(XRE_IsParentProcess());
  217. MOZ_ASSERT(NS_IsMainThread());
  218. if (!mBackgroundThread) {
  219. return;
  220. }
  221. RefPtr<AbortOperationsRunnable> runnable =
  222. new AbortOperationsRunnable(aContentParentId);
  223. MOZ_ALWAYS_SUCCEEDS(
  224. mBackgroundThread->Dispatch(runnable, NS_DISPATCH_NORMAL));
  225. }
  226. nsresult
  227. QuotaManagerService::Init()
  228. {
  229. MOZ_ASSERT(NS_IsMainThread());
  230. if (XRE_IsParentProcess()) {
  231. nsCOMPtr<nsIObserverService> observerService =
  232. mozilla::services::GetObserverService();
  233. if (NS_WARN_IF(!observerService)) {
  234. return NS_ERROR_FAILURE;
  235. }
  236. nsresult rv =
  237. observerService->AddObserver(this,
  238. PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID,
  239. false);
  240. if (NS_WARN_IF(NS_FAILED(rv))) {
  241. return rv;
  242. }
  243. }
  244. Preferences::RegisterCallbackAndCall(TestingPrefChangedCallback,
  245. kTestingPref);
  246. return NS_OK;
  247. }
  248. void
  249. QuotaManagerService::Destroy()
  250. {
  251. // Setting the closed flag prevents the service from being recreated.
  252. // Don't set it though if there's no real instance created.
  253. if (gInitialized && gClosed.exchange(true)) {
  254. MOZ_ASSERT(false, "Shutdown more than once?!");
  255. }
  256. Preferences::UnregisterCallback(TestingPrefChangedCallback, kTestingPref);
  257. delete this;
  258. }
  259. nsresult
  260. QuotaManagerService::InitiateRequest(nsAutoPtr<PendingRequestInfo>& aInfo)
  261. {
  262. // Nothing can be done here if we have previously failed to create a
  263. // background actor.
  264. if (mBackgroundActorFailed) {
  265. return NS_ERROR_FAILURE;
  266. }
  267. if (!mBackgroundActor && mPendingRequests.IsEmpty()) {
  268. if (PBackgroundChild* actor = BackgroundChild::GetForCurrentThread()) {
  269. BackgroundActorCreated(actor);
  270. } else {
  271. // We need to start the sequence to create a background actor for this
  272. // thread.
  273. RefPtr<BackgroundCreateCallback> cb = new BackgroundCreateCallback(this);
  274. if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) {
  275. return NS_ERROR_FAILURE;
  276. }
  277. }
  278. }
  279. // If we already have a background actor then we can start this request now.
  280. if (mBackgroundActor) {
  281. nsresult rv = aInfo->InitiateRequest(mBackgroundActor);
  282. if (NS_WARN_IF(NS_FAILED(rv))) {
  283. return rv;
  284. }
  285. } else {
  286. mPendingRequests.AppendElement(aInfo.forget());
  287. }
  288. return NS_OK;
  289. }
  290. nsresult
  291. QuotaManagerService::BackgroundActorCreated(PBackgroundChild* aBackgroundActor)
  292. {
  293. MOZ_ASSERT(NS_IsMainThread());
  294. MOZ_ASSERT(aBackgroundActor);
  295. MOZ_ASSERT(!mBackgroundActor);
  296. MOZ_ASSERT(!mBackgroundActorFailed);
  297. {
  298. QuotaChild* actor = new QuotaChild(this);
  299. mBackgroundActor =
  300. static_cast<QuotaChild*>(aBackgroundActor->SendPQuotaConstructor(actor));
  301. }
  302. if (NS_WARN_IF(!mBackgroundActor)) {
  303. BackgroundActorFailed();
  304. return NS_ERROR_FAILURE;
  305. }
  306. nsresult rv = NS_OK;
  307. for (uint32_t index = 0, count = mPendingRequests.Length();
  308. index < count;
  309. index++) {
  310. nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
  311. nsresult rv2 = info->InitiateRequest(mBackgroundActor);
  312. // Warn for every failure, but just return the first failure if there are
  313. // multiple failures.
  314. if (NS_WARN_IF(NS_FAILED(rv2)) && NS_SUCCEEDED(rv)) {
  315. rv = rv2;
  316. }
  317. }
  318. mPendingRequests.Clear();
  319. return rv;
  320. }
  321. void
  322. QuotaManagerService::BackgroundActorFailed()
  323. {
  324. MOZ_ASSERT(NS_IsMainThread());
  325. MOZ_ASSERT(!mPendingRequests.IsEmpty());
  326. MOZ_ASSERT(!mBackgroundActor);
  327. MOZ_ASSERT(!mBackgroundActorFailed);
  328. mBackgroundActorFailed = true;
  329. for (uint32_t index = 0, count = mPendingRequests.Length();
  330. index < count;
  331. index++) {
  332. nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
  333. RequestBase* request = info->GetRequest();
  334. if (request) {
  335. request->SetError(NS_ERROR_FAILURE);
  336. }
  337. }
  338. mPendingRequests.Clear();
  339. }
  340. void
  341. QuotaManagerService::PerformIdleMaintenance()
  342. {
  343. using namespace mozilla::hal;
  344. MOZ_ASSERT(XRE_IsParentProcess());
  345. MOZ_ASSERT(NS_IsMainThread());
  346. if (QuotaManager::IsRunningXPCShellTests()) {
  347. // We don't want user activity to impact this code if we're running tests.
  348. Unused << Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
  349. } else if (!mIdleObserverRegistered) {
  350. nsCOMPtr<nsIIdleService> idleService =
  351. do_GetService(kIdleServiceContractId);
  352. MOZ_ASSERT(idleService);
  353. MOZ_ALWAYS_SUCCEEDS(
  354. idleService->AddIdleObserver(this, kIdleObserverTimeSec));
  355. mIdleObserverRegistered = true;
  356. }
  357. }
  358. void
  359. QuotaManagerService::RemoveIdleObserver()
  360. {
  361. MOZ_ASSERT(XRE_IsParentProcess());
  362. MOZ_ASSERT(NS_IsMainThread());
  363. if (mIdleObserverRegistered) {
  364. nsCOMPtr<nsIIdleService> idleService =
  365. do_GetService(kIdleServiceContractId);
  366. MOZ_ASSERT(idleService);
  367. MOZ_ALWAYS_SUCCEEDS(
  368. idleService->RemoveIdleObserver(this, kIdleObserverTimeSec));
  369. mIdleObserverRegistered = false;
  370. }
  371. }
  372. NS_IMPL_ADDREF(QuotaManagerService)
  373. NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
  374. NS_IMPL_QUERY_INTERFACE(QuotaManagerService,
  375. nsIQuotaManagerService,
  376. nsIObserver)
  377. NS_IMETHODIMP
  378. QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback,
  379. bool aGetAll,
  380. nsIQuotaUsageRequest** _retval)
  381. {
  382. MOZ_ASSERT(NS_IsMainThread());
  383. MOZ_ASSERT(aCallback);
  384. RefPtr<UsageRequest> request = new UsageRequest(aCallback);
  385. AllUsageParams params;
  386. params.getAll() = aGetAll;
  387. nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
  388. nsresult rv = InitiateRequest(info);
  389. if (NS_WARN_IF(NS_FAILED(rv))) {
  390. return rv;
  391. }
  392. request.forget(_retval);
  393. return NS_OK;
  394. }
  395. NS_IMETHODIMP
  396. QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
  397. nsIQuotaUsageCallback* aCallback,
  398. bool aGetGroupUsage,
  399. nsIQuotaUsageRequest** _retval)
  400. {
  401. MOZ_ASSERT(NS_IsMainThread());
  402. MOZ_ASSERT(aPrincipal);
  403. MOZ_ASSERT(aCallback);
  404. RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
  405. OriginUsageParams params;
  406. PrincipalInfo& principalInfo = params.principalInfo();
  407. nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
  408. if (NS_WARN_IF(NS_FAILED(rv))) {
  409. return rv;
  410. }
  411. if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
  412. principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
  413. return NS_ERROR_UNEXPECTED;
  414. }
  415. params.getGroupUsage() = aGetGroupUsage;
  416. nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
  417. rv = InitiateRequest(info);
  418. if (NS_WARN_IF(NS_FAILED(rv))) {
  419. return rv;
  420. }
  421. request.forget(_retval);
  422. return NS_OK;
  423. }
  424. NS_IMETHODIMP
  425. QuotaManagerService::Clear(nsIQuotaRequest** _retval)
  426. {
  427. MOZ_ASSERT(NS_IsMainThread());
  428. MOZ_ASSERT(nsContentUtils::IsCallerChrome());
  429. if (NS_WARN_IF(!gTestingMode)) {
  430. return NS_ERROR_UNEXPECTED;
  431. }
  432. RefPtr<Request> request = new Request();
  433. ClearAllParams params;
  434. nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
  435. nsresult rv = InitiateRequest(info);
  436. if (NS_WARN_IF(NS_FAILED(rv))) {
  437. return rv;
  438. }
  439. request.forget(_retval);
  440. return NS_OK;
  441. }
  442. NS_IMETHODIMP
  443. QuotaManagerService::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
  444. const nsACString& aPersistenceType,
  445. bool aClearAll,
  446. nsIQuotaRequest** _retval)
  447. {
  448. MOZ_ASSERT(NS_IsMainThread());
  449. MOZ_ASSERT(aPrincipal);
  450. MOZ_ASSERT(nsContentUtils::IsCallerChrome());
  451. nsCString suffix;
  452. BasePrincipal::Cast(aPrincipal)->OriginAttributesRef().CreateSuffix(suffix);
  453. if (NS_WARN_IF(aClearAll && !suffix.IsEmpty())) {
  454. // The originAttributes should be default originAttributes when the
  455. // aClearAll flag is set.
  456. return NS_ERROR_INVALID_ARG;
  457. }
  458. RefPtr<Request> request = new Request(aPrincipal);
  459. ClearOriginParams params;
  460. PrincipalInfo& principalInfo = params.principalInfo();
  461. nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
  462. if (NS_WARN_IF(NS_FAILED(rv))) {
  463. return rv;
  464. }
  465. if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
  466. principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
  467. return NS_ERROR_UNEXPECTED;
  468. }
  469. Nullable<PersistenceType> persistenceType;
  470. rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
  471. if (NS_WARN_IF(NS_FAILED(rv))) {
  472. return NS_ERROR_INVALID_ARG;
  473. }
  474. if (persistenceType.IsNull()) {
  475. params.persistenceTypeIsExplicit() = false;
  476. } else {
  477. params.persistenceType() = persistenceType.Value();
  478. params.persistenceTypeIsExplicit() = true;
  479. }
  480. params.clearAll() = aClearAll;
  481. nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
  482. rv = InitiateRequest(info);
  483. if (NS_WARN_IF(NS_FAILED(rv))) {
  484. return rv;
  485. }
  486. request.forget(_retval);
  487. return NS_OK;
  488. }
  489. NS_IMETHODIMP
  490. QuotaManagerService::Reset(nsIQuotaRequest** _retval)
  491. {
  492. MOZ_ASSERT(NS_IsMainThread());
  493. MOZ_ASSERT(nsContentUtils::IsCallerChrome());
  494. if (NS_WARN_IF(!gTestingMode)) {
  495. return NS_ERROR_UNEXPECTED;
  496. }
  497. RefPtr<Request> request = new Request();
  498. ResetAllParams params;
  499. nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
  500. nsresult rv = InitiateRequest(info);
  501. if (NS_WARN_IF(NS_FAILED(rv))) {
  502. return rv;
  503. }
  504. request.forget(_retval);
  505. return NS_OK;
  506. }
  507. NS_IMETHODIMP
  508. QuotaManagerService::Observe(nsISupports* aSubject,
  509. const char* aTopic,
  510. const char16_t* aData)
  511. {
  512. MOZ_ASSERT(XRE_IsParentProcess());
  513. MOZ_ASSERT(NS_IsMainThread());
  514. if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_QM_OBSERVER_ID)) {
  515. RemoveIdleObserver();
  516. return NS_OK;
  517. }
  518. if (!strcmp(aTopic, "clear-origin-attributes-data")) {
  519. RefPtr<Request> request = new Request();
  520. ClearOriginsParams requestParams;
  521. requestParams.pattern() = nsDependentString(aData);
  522. nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, requestParams));
  523. nsresult rv = InitiateRequest(info);
  524. if (NS_WARN_IF(NS_FAILED(rv))) {
  525. return rv;
  526. }
  527. return NS_OK;
  528. }
  529. if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
  530. PerformIdleMaintenance();
  531. return NS_OK;
  532. }
  533. if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
  534. nsAutoPtr<PendingRequestInfo> info(
  535. new IdleMaintenanceInfo(/* aStart */ true));
  536. nsresult rv = InitiateRequest(info);
  537. if (NS_WARN_IF(NS_FAILED(rv))) {
  538. return rv;
  539. }
  540. return NS_OK;
  541. }
  542. if (!strcmp(aTopic, OBSERVER_TOPIC_ACTIVE)) {
  543. RemoveIdleObserver();
  544. nsAutoPtr<PendingRequestInfo> info(
  545. new IdleMaintenanceInfo(/* aStart */ false));
  546. nsresult rv = InitiateRequest(info);
  547. if (NS_WARN_IF(NS_FAILED(rv))) {
  548. return rv;
  549. }
  550. return NS_OK;
  551. }
  552. MOZ_ASSERT_UNREACHABLE("Should never get here!");
  553. return NS_OK;
  554. }
  555. NS_IMETHODIMP
  556. AbortOperationsRunnable::Run()
  557. {
  558. AssertIsOnBackgroundThread();
  559. if (QuotaManager::IsShuttingDown()) {
  560. return NS_OK;
  561. }
  562. QuotaManager* quotaManager = QuotaManager::Get();
  563. if (!quotaManager) {
  564. return NS_OK;
  565. }
  566. quotaManager->AbortOperationsForProcess(mContentParentId);
  567. return NS_OK;
  568. }
  569. NS_IMPL_ISUPPORTS(QuotaManagerService::BackgroundCreateCallback,
  570. nsIIPCBackgroundChildCreateCallback)
  571. void
  572. QuotaManagerService::
  573. BackgroundCreateCallback::ActorCreated(PBackgroundChild* aActor)
  574. {
  575. MOZ_ASSERT(NS_IsMainThread());
  576. MOZ_ASSERT(aActor);
  577. MOZ_ASSERT(mService);
  578. RefPtr<QuotaManagerService> service;
  579. mService.swap(service);
  580. service->BackgroundActorCreated(aActor);
  581. }
  582. void
  583. QuotaManagerService::
  584. BackgroundCreateCallback::ActorFailed()
  585. {
  586. MOZ_ASSERT(NS_IsMainThread());
  587. MOZ_ASSERT(mService);
  588. RefPtr<QuotaManagerService> service;
  589. mService.swap(service);
  590. service->BackgroundActorFailed();
  591. }
  592. nsresult
  593. QuotaManagerService::
  594. UsageRequestInfo::InitiateRequest(QuotaChild* aActor)
  595. {
  596. MOZ_ASSERT(aActor);
  597. auto request = static_cast<UsageRequest*>(mRequest.get());
  598. auto actor = new QuotaUsageRequestChild(request);
  599. if (!aActor->SendPQuotaUsageRequestConstructor(actor, mParams)) {
  600. request->SetError(NS_ERROR_FAILURE);
  601. return NS_ERROR_FAILURE;
  602. }
  603. request->SetBackgroundActor(actor);
  604. return NS_OK;
  605. }
  606. nsresult
  607. QuotaManagerService::
  608. RequestInfo::InitiateRequest(QuotaChild* aActor)
  609. {
  610. MOZ_ASSERT(aActor);
  611. auto request = static_cast<Request*>(mRequest.get());
  612. auto actor = new QuotaRequestChild(request);
  613. if (!aActor->SendPQuotaRequestConstructor(actor, mParams)) {
  614. request->SetError(NS_ERROR_FAILURE);
  615. return NS_ERROR_FAILURE;
  616. }
  617. return NS_OK;
  618. }
  619. nsresult
  620. QuotaManagerService::
  621. IdleMaintenanceInfo::InitiateRequest(QuotaChild* aActor)
  622. {
  623. MOZ_ASSERT(aActor);
  624. bool result;
  625. if (mStart) {
  626. result = aActor->SendStartIdleMaintenance();
  627. } else {
  628. result = aActor->SendStopIdleMaintenance();
  629. }
  630. if (!result) {
  631. return NS_ERROR_FAILURE;
  632. }
  633. return NS_OK;
  634. }
  635. } // namespace quota
  636. } // namespace dom
  637. } // namespace mozilla