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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "StorageIPC.h"
9 #include "StorageCommon.h"
10 #include "StorageUtils.h"
11 #include "LocalStorageManager.h"
12 #include "SessionStorageObserver.h"
13 #include "SessionStorageManager.h"
14 #include "SessionStorageCache.h"
16 #include "mozilla/dom/LocalStorageCommon.h"
17 #include "mozilla/ipc/BackgroundChild.h"
18 #include "mozilla/ipc/BackgroundParent.h"
19 #include "mozilla/ipc/PBackgroundChild.h"
20 #include "mozilla/ipc/PBackgroundParent.h"
21 #include "mozilla/dom/ContentParent.h"
22 #include "mozilla/StoragePrincipalHelper.h"
23 #include "mozilla/Unused.h"
25 #include "nsIPrincipal.h"
26 #include "nsThreadUtils.h"
28 namespace mozilla::dom
{
32 using LocalStorageCacheParentHashtable
=
33 nsClassHashtable
<nsCStringHashKey
, nsTArray
<LocalStorageCacheParent
*>>;
35 StaticAutoPtr
<LocalStorageCacheParentHashtable
> gLocalStorageCacheParents
;
37 StorageDBChild
* sStorageChild
[kPrivateBrowsingIdCount
] = {nullptr, nullptr};
39 // False until we shut the storage child down.
40 bool sStorageChildDown
[kPrivateBrowsingIdCount
] = {false, false};
44 LocalStorageCacheChild::LocalStorageCacheChild(LocalStorageCache
* aCache
)
46 AssertIsOnOwningThread();
48 aCache
->AssertIsOnOwningThread();
50 MOZ_COUNT_CTOR(LocalStorageCacheChild
);
53 LocalStorageCacheChild::~LocalStorageCacheChild() {
54 AssertIsOnOwningThread();
56 MOZ_COUNT_DTOR(LocalStorageCacheChild
);
59 void LocalStorageCacheChild::SendDeleteMeInternal() {
60 AssertIsOnOwningThread();
66 MOZ_ALWAYS_TRUE(PBackgroundLocalStorageCacheChild::SendDeleteMe());
70 void LocalStorageCacheChild::ActorDestroy(ActorDestroyReason aWhy
) {
71 AssertIsOnOwningThread();
79 mozilla::ipc::IPCResult
LocalStorageCacheChild::RecvObserve(
80 const PrincipalInfo
& aPrincipalInfo
,
81 const PrincipalInfo
& aCachePrincipalInfo
,
82 const uint32_t& aPrivateBrowsingId
, const nsString
& aDocumentURI
,
83 const nsString
& aKey
, const nsString
& aOldValue
,
84 const nsString
& aNewValue
) {
85 AssertIsOnOwningThread();
87 auto principalOrErr
= PrincipalInfoToPrincipal(aPrincipalInfo
);
88 if (NS_WARN_IF(principalOrErr
.isErr())) {
89 return IPC_FAIL_NO_REASON(this);
92 auto cachePrincipalOrErr
= PrincipalInfoToPrincipal(aCachePrincipalInfo
);
93 if (NS_WARN_IF(cachePrincipalOrErr
.isErr())) {
94 return IPC_FAIL_NO_REASON(this);
97 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
98 nsCOMPtr
<nsIPrincipal
> cachePrincipal
= cachePrincipalOrErr
.unwrap();
100 if (StorageUtils::PrincipalsEqual(principal
, cachePrincipal
)) {
101 Storage::NotifyChange(/* aStorage */ nullptr, principal
, aKey
, aOldValue
,
103 /* aStorageType */ u
"localStorage", aDocumentURI
,
104 /* aIsPrivate */ !!aPrivateBrowsingId
,
105 /* aImmediateDispatch */ true);
111 // ----------------------------------------------------------------------------
113 // ----------------------------------------------------------------------------
115 class StorageDBChild::ShutdownObserver final
: public nsIObserver
{
116 // Expected to be only 0 or 1.
117 const uint32_t mPrivateBrowsingId
;
120 explicit ShutdownObserver(const uint32_t aPrivateBrowsingId
)
121 : mPrivateBrowsingId(aPrivateBrowsingId
) {
122 MOZ_ASSERT(NS_IsMainThread());
123 MOZ_RELEASE_ASSERT(aPrivateBrowsingId
< kPrivateBrowsingIdCount
);
130 ~ShutdownObserver() { MOZ_ASSERT(NS_IsMainThread()); }
133 void StorageDBChild::AddIPDLReference() {
134 MOZ_ASSERT(!mIPCOpen
, "Attempting to retain multiple IPDL references");
139 void StorageDBChild::ReleaseIPDLReference() {
140 MOZ_ASSERT(mIPCOpen
, "Attempting to release non-existent IPDL reference");
145 StorageDBChild::StorageDBChild(LocalStorageManager
* aManager
,
146 const uint32_t aPrivateBrowsingId
)
147 : mManager(aManager
),
148 mPrivateBrowsingId(aPrivateBrowsingId
),
151 MOZ_RELEASE_ASSERT(aPrivateBrowsingId
< kPrivateBrowsingIdCount
);
152 MOZ_ASSERT(!NextGenLocalStorageEnabled());
155 StorageDBChild::~StorageDBChild() = default;
158 StorageDBChild
* StorageDBChild::Get(const uint32_t aPrivateBrowsingId
) {
159 MOZ_ASSERT(NS_IsMainThread());
160 MOZ_RELEASE_ASSERT(aPrivateBrowsingId
< kPrivateBrowsingIdCount
);
161 MOZ_ASSERT(!NextGenLocalStorageEnabled());
163 return sStorageChild
[aPrivateBrowsingId
];
167 StorageDBChild
* StorageDBChild::GetOrCreate(const uint32_t aPrivateBrowsingId
) {
168 MOZ_ASSERT(NS_IsMainThread());
169 MOZ_RELEASE_ASSERT(aPrivateBrowsingId
< kPrivateBrowsingIdCount
);
170 MOZ_ASSERT(!NextGenLocalStorageEnabled());
172 StorageDBChild
*& storageChild
= sStorageChild
[aPrivateBrowsingId
];
173 if (storageChild
|| sStorageChildDown
[aPrivateBrowsingId
]) {
174 // When sStorageChildDown is at true, sStorageChild is null.
175 // Checking sStorageChildDown flag here prevents reinitialization of
176 // the storage child after shutdown.
180 // Use LocalStorageManager::Ensure in case we're called from
181 // DOMSessionStorageManager's initializer and we haven't yet initialized the
182 // local storage manager.
183 RefPtr
<StorageDBChild
> newStorageChild
=
184 new StorageDBChild(LocalStorageManager::Ensure(), aPrivateBrowsingId
);
186 nsresult rv
= newStorageChild
->Init();
187 if (NS_WARN_IF(NS_FAILED(rv
))) {
191 newStorageChild
.forget(&storageChild
);
196 nsTHashSet
<nsCString
>& StorageDBChild::OriginsHavingData() {
197 if (!mOriginsHavingData
) {
198 mOriginsHavingData
= MakeUnique
<nsTHashSet
<nsCString
>>();
201 return *mOriginsHavingData
;
204 nsresult
StorageDBChild::Init() {
205 MOZ_ASSERT(NS_IsMainThread());
207 ::mozilla::ipc::PBackgroundChild
* actor
=
208 ::mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
209 if (NS_WARN_IF(!actor
)) {
210 return NS_ERROR_FAILURE
;
213 nsString profilePath
;
214 if (XRE_IsParentProcess() && mPrivateBrowsingId
== 0) {
215 nsresult rv
= StorageDBThread::GetProfilePath(profilePath
);
216 if (NS_WARN_IF(NS_FAILED(rv
))) {
223 actor
->SendPBackgroundStorageConstructor(this, profilePath
,
226 nsCOMPtr
<nsIObserverService
> observerService
= services::GetObserverService();
227 MOZ_ASSERT(observerService
);
229 nsCOMPtr
<nsIObserver
> observer
= new ShutdownObserver(mPrivateBrowsingId
);
232 observerService
->AddObserver(observer
, "xpcom-shutdown", false));
237 nsresult
StorageDBChild::Shutdown() {
238 // There is nothing to do here, IPC will release automatically and
239 // the actual thread running on the parent process will also stop
240 // automatically in profile-before-change topic observer.
244 void StorageDBChild::AsyncPreload(LocalStorageCacheBridge
* aCache
,
247 // Adding ref to cache for the time of preload. This ensures a reference to
248 // to the cache and that all keys will load into this cache object.
249 mLoadingCaches
.Insert(aCache
);
250 SendAsyncPreload(aCache
->OriginSuffix(), aCache
->OriginNoSuffix(),
253 // No IPC, no love. But the LoadDone call is expected.
254 aCache
->LoadDone(NS_ERROR_UNEXPECTED
);
258 void StorageDBChild::AsyncGetUsage(StorageUsageBridge
* aUsage
) {
260 SendAsyncGetUsage(aUsage
->OriginScope());
264 void StorageDBChild::SyncPreload(LocalStorageCacheBridge
* aCache
,
266 if (NS_FAILED(mStatus
)) {
267 aCache
->LoadDone(mStatus
);
272 aCache
->LoadDone(NS_ERROR_UNEXPECTED
);
276 // There is no way to put the child process to a wait state to receive all
277 // incoming async responses from the parent, hence we have to do a sync
278 // preload instead. We are smart though, we only demand keys that are left to
279 // load in case the async preload has already loaded some keys.
280 nsTArray
<nsString
> keys
, values
;
282 SendPreload(aCache
->OriginSuffix(), aCache
->OriginNoSuffix(),
283 aCache
->LoadedCount(), &keys
, &values
, &rv
);
285 for (uint32_t i
= 0; i
< keys
.Length(); ++i
) {
286 aCache
->LoadItem(keys
[i
], values
[i
]);
289 aCache
->LoadDone(rv
);
292 nsresult
StorageDBChild::AsyncAddItem(LocalStorageCacheBridge
* aCache
,
293 const nsAString
& aKey
,
294 const nsAString
& aValue
) {
295 if (NS_FAILED(mStatus
) || !mIPCOpen
) {
299 SendAsyncAddItem(aCache
->OriginSuffix(), aCache
->OriginNoSuffix(),
300 nsString(aKey
), nsString(aValue
));
301 OriginsHavingData().Insert(aCache
->Origin());
305 nsresult
StorageDBChild::AsyncUpdateItem(LocalStorageCacheBridge
* aCache
,
306 const nsAString
& aKey
,
307 const nsAString
& aValue
) {
308 if (NS_FAILED(mStatus
) || !mIPCOpen
) {
312 SendAsyncUpdateItem(aCache
->OriginSuffix(), aCache
->OriginNoSuffix(),
313 nsString(aKey
), nsString(aValue
));
314 OriginsHavingData().Insert(aCache
->Origin());
318 nsresult
StorageDBChild::AsyncRemoveItem(LocalStorageCacheBridge
* aCache
,
319 const nsAString
& aKey
) {
320 if (NS_FAILED(mStatus
) || !mIPCOpen
) {
324 SendAsyncRemoveItem(aCache
->OriginSuffix(), aCache
->OriginNoSuffix(),
329 nsresult
StorageDBChild::AsyncClear(LocalStorageCacheBridge
* aCache
) {
330 if (NS_FAILED(mStatus
) || !mIPCOpen
) {
334 SendAsyncClear(aCache
->OriginSuffix(), aCache
->OriginNoSuffix());
335 OriginsHavingData().Remove(aCache
->Origin());
339 bool StorageDBChild::ShouldPreloadOrigin(const nsACString
& aOrigin
) {
340 // Return true if we didn't receive the origins list yet.
341 // I tend to rather preserve a bit of early-after-start performance
342 // than a bit of memory here.
343 return !mOriginsHavingData
|| mOriginsHavingData
->Contains(aOrigin
);
346 mozilla::ipc::IPCResult
StorageDBChild::RecvObserve(
347 const nsCString
& aTopic
, const nsString
& aOriginAttributesPattern
,
348 const nsCString
& aOriginScope
) {
349 MOZ_ASSERT(!XRE_IsParentProcess());
351 StorageObserver
* obs
= StorageObserver::Self();
353 obs
->Notify(aTopic
.get(), aOriginAttributesPattern
, aOriginScope
);
359 mozilla::ipc::IPCResult
StorageDBChild::RecvOriginsHavingData(
360 nsTArray
<nsCString
>&& aOrigins
) {
361 // Force population of mOriginsHavingData even if there are no origins so that
362 // ShouldPreloadOrigin does not generate false positives for all origins.
363 if (!aOrigins
.Length()) {
364 Unused
<< OriginsHavingData();
367 for (uint32_t i
= 0; i
< aOrigins
.Length(); ++i
) {
368 OriginsHavingData().Insert(aOrigins
[i
]);
374 mozilla::ipc::IPCResult
StorageDBChild::RecvLoadItem(
375 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
376 const nsString
& aKey
, const nsString
& aValue
) {
377 LocalStorageCache
* aCache
=
378 mManager
->GetCache(aOriginSuffix
, aOriginNoSuffix
);
380 aCache
->LoadItem(aKey
, aValue
);
386 mozilla::ipc::IPCResult
StorageDBChild::RecvLoadDone(
387 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
388 const nsresult
& aRv
) {
389 LocalStorageCache
* aCache
=
390 mManager
->GetCache(aOriginSuffix
, aOriginNoSuffix
);
392 aCache
->LoadDone(aRv
);
394 // Just drop reference to this cache now since the load is done.
395 mLoadingCaches
.Remove(static_cast<LocalStorageCacheBridge
*>(aCache
));
401 mozilla::ipc::IPCResult
StorageDBChild::RecvLoadUsage(
402 const nsCString
& aOriginNoSuffix
, const int64_t& aUsage
) {
403 RefPtr
<StorageUsageBridge
> scopeUsage
=
404 mManager
->GetOriginUsage(aOriginNoSuffix
, mPrivateBrowsingId
);
405 scopeUsage
->LoadUsage(aUsage
);
409 mozilla::ipc::IPCResult
StorageDBChild::RecvError(const nsresult
& aRv
) {
414 NS_IMPL_ISUPPORTS(StorageDBChild::ShutdownObserver
, nsIObserver
)
417 StorageDBChild::ShutdownObserver::Observe(nsISupports
* aSubject
,
419 const char16_t
* aData
) {
420 MOZ_ASSERT(NS_IsMainThread());
421 MOZ_ASSERT(!strcmp(aTopic
, "xpcom-shutdown"));
423 nsCOMPtr
<nsIObserverService
> observerService
=
424 mozilla::services::GetObserverService();
425 if (NS_WARN_IF(!observerService
)) {
426 return NS_ERROR_FAILURE
;
429 Unused
<< observerService
->RemoveObserver(this, "xpcom-shutdown");
431 StorageDBChild
*& storageChild
= sStorageChild
[mPrivateBrowsingId
];
433 sStorageChildDown
[mPrivateBrowsingId
] = true;
435 MOZ_ALWAYS_TRUE(storageChild
->PBackgroundStorageChild::SendDeleteMe());
437 NS_RELEASE(storageChild
);
438 storageChild
= nullptr;
444 SessionStorageObserverChild::SessionStorageObserverChild(
445 SessionStorageObserver
* aObserver
)
446 : mObserver(aObserver
) {
447 AssertIsOnOwningThread();
448 MOZ_ASSERT(NextGenLocalStorageEnabled());
449 MOZ_ASSERT(aObserver
);
450 aObserver
->AssertIsOnOwningThread();
452 MOZ_COUNT_CTOR(SessionStorageObserverChild
);
455 SessionStorageObserverChild::~SessionStorageObserverChild() {
456 AssertIsOnOwningThread();
458 MOZ_COUNT_DTOR(SessionStorageObserverChild
);
461 void SessionStorageObserverChild::SendDeleteMeInternal() {
462 AssertIsOnOwningThread();
465 mObserver
->ClearActor();
468 // Don't check result here since IPC may no longer be available due to
469 // SessionStorageManager (which holds a strong reference to
470 // SessionStorageObserver) being destroyed very late in the game.
471 PSessionStorageObserverChild::SendDeleteMe();
475 void SessionStorageObserverChild::ActorDestroy(ActorDestroyReason aWhy
) {
476 AssertIsOnOwningThread();
479 mObserver
->ClearActor();
484 mozilla::ipc::IPCResult
SessionStorageObserverChild::RecvObserve(
485 const nsCString
& aTopic
, const nsString
& aOriginAttributesPattern
,
486 const nsCString
& aOriginScope
) {
487 AssertIsOnOwningThread();
489 StorageObserver
* obs
= StorageObserver::Self();
491 obs
->Notify(aTopic
.get(), aOriginAttributesPattern
, aOriginScope
);
497 SessionStorageCacheChild::SessionStorageCacheChild(SessionStorageCache
* aCache
)
499 AssertIsOnOwningThread();
502 MOZ_COUNT_CTOR(SessionStorageCacheChild
);
505 SessionStorageCacheChild::~SessionStorageCacheChild() {
506 AssertIsOnOwningThread();
508 MOZ_COUNT_DTOR(SessionStorageCacheChild
);
511 void SessionStorageCacheChild::SendDeleteMeInternal() {
512 AssertIsOnOwningThread();
515 mCache
->ClearActor();
518 MOZ_ALWAYS_TRUE(PBackgroundSessionStorageCacheChild::SendDeleteMe());
522 void SessionStorageCacheChild::ActorDestroy(ActorDestroyReason aWhy
) {
523 AssertIsOnOwningThread();
526 mCache
->ClearActor();
531 SessionStorageManagerChild::SessionStorageManagerChild(
532 SessionStorageManager
* aSSManager
)
533 : mSSManager(aSSManager
) {
534 AssertIsOnOwningThread();
535 MOZ_ASSERT(mSSManager
);
537 MOZ_COUNT_CTOR(SessionStorageManagerChild
);
540 SessionStorageManagerChild::~SessionStorageManagerChild() {
541 AssertIsOnOwningThread();
543 MOZ_COUNT_DTOR(SessionStorageManagerChild
);
546 void SessionStorageManagerChild::SendDeleteMeInternal() {
547 AssertIsOnOwningThread();
550 mSSManager
->ClearActor();
551 mSSManager
= nullptr;
553 MOZ_ALWAYS_TRUE(PBackgroundSessionStorageManagerChild::SendDeleteMe());
557 void SessionStorageManagerChild::ActorDestroy(ActorDestroyReason aWhy
) {
558 AssertIsOnOwningThread();
561 mSSManager
->ClearActor();
562 mSSManager
= nullptr;
566 mozilla::ipc::IPCResult
SessionStorageManagerChild::RecvClearStoragesForOrigin(
567 const nsCString
& aOriginAttrs
, const nsCString
& aOriginKey
) {
568 AssertIsOnOwningThread();
571 mSSManager
->ClearStoragesForOrigin(aOriginAttrs
, aOriginKey
);
577 LocalStorageCacheParent::LocalStorageCacheParent(
578 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
579 const nsACString
& aOriginKey
, uint32_t aPrivateBrowsingId
)
580 : mPrincipalInfo(aPrincipalInfo
),
581 mOriginKey(aOriginKey
),
582 mPrivateBrowsingId(aPrivateBrowsingId
),
583 mActorDestroyed(false) {
584 ::mozilla::ipc::AssertIsOnBackgroundThread();
587 LocalStorageCacheParent::~LocalStorageCacheParent() {
588 MOZ_ASSERT(mActorDestroyed
);
591 void LocalStorageCacheParent::ActorDestroy(ActorDestroyReason aWhy
) {
592 ::mozilla::ipc::AssertIsOnBackgroundThread();
593 MOZ_ASSERT(!mActorDestroyed
);
595 mActorDestroyed
= true;
597 MOZ_ASSERT(gLocalStorageCacheParents
);
599 nsTArray
<LocalStorageCacheParent
*>* array
;
600 gLocalStorageCacheParents
->Get(mOriginKey
, &array
);
603 array
->RemoveElement(this);
605 if (array
->IsEmpty()) {
606 gLocalStorageCacheParents
->Remove(mOriginKey
);
609 if (!gLocalStorageCacheParents
->Count()) {
610 gLocalStorageCacheParents
= nullptr;
614 mozilla::ipc::IPCResult
LocalStorageCacheParent::RecvDeleteMe() {
615 ::mozilla::ipc::AssertIsOnBackgroundThread();
616 MOZ_ASSERT(!mActorDestroyed
);
618 IProtocol
* mgr
= Manager();
619 if (!PBackgroundLocalStorageCacheParent::Send__delete__(this)) {
620 return IPC_FAIL_NO_REASON(mgr
);
625 mozilla::ipc::IPCResult
LocalStorageCacheParent::RecvNotify(
626 const nsString
& aDocumentURI
, const nsString
& aKey
,
627 const nsString
& aOldValue
, const nsString
& aNewValue
) {
628 ::mozilla::ipc::AssertIsOnBackgroundThread();
629 MOZ_ASSERT(gLocalStorageCacheParents
);
631 nsTArray
<LocalStorageCacheParent
*>* array
;
632 gLocalStorageCacheParents
->Get(mOriginKey
, &array
);
635 for (LocalStorageCacheParent
* localStorageCacheParent
: *array
) {
636 if (localStorageCacheParent
!= this) {
637 // When bug 1443925 is fixed, we can compare mPrincipalInfo against
638 // localStorageCacheParent->PrincipalInfo() here on the background thread
639 // instead of posting it to the main thread. The advantage of doing so is
640 // that it would save an IPC message in the case where the principals do
642 Unused
<< localStorageCacheParent
->SendObserve(
643 mPrincipalInfo
, localStorageCacheParent
->PrincipalInfo(),
644 mPrivateBrowsingId
, aDocumentURI
, aKey
, aOldValue
, aNewValue
);
651 // ----------------------------------------------------------------------------
653 // ----------------------------------------------------------------------------
655 class StorageDBParent::ObserverSink
: public StorageObserverSink
{
656 nsCOMPtr
<nsIEventTarget
> mOwningEventTarget
;
658 // Only touched on the PBackground thread.
659 StorageDBParent
* MOZ_NON_OWNING_REF mActor
;
662 explicit ObserverSink(StorageDBParent
* aActor
)
663 : mOwningEventTarget(GetCurrentEventTarget()), mActor(aActor
) {
664 ::mozilla::ipc::AssertIsOnBackgroundThread();
668 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StorageDBParent::ObserverSink
);
675 ~ObserverSink() = default;
681 void Notify(const nsCString
& aTopic
, const nsString
& aOriginAttributesPattern
,
682 const nsCString
& aOriginScope
);
684 // StorageObserverSink
685 nsresult
Observe(const char* aTopic
, const nsAString
& aOriginAttrPattern
,
686 const nsACString
& aOriginScope
) override
;
689 NS_IMPL_ADDREF(StorageDBParent
)
690 NS_IMPL_RELEASE(StorageDBParent
)
692 void StorageDBParent::AddIPDLReference() {
693 MOZ_ASSERT(!mIPCOpen
, "Attempting to retain multiple IPDL references");
698 void StorageDBParent::ReleaseIPDLReference() {
699 MOZ_ASSERT(mIPCOpen
, "Attempting to release non-existent IPDL reference");
704 namespace {} // namespace
706 StorageDBParent::StorageDBParent(const nsString
& aProfilePath
,
707 const uint32_t aPrivateBrowsingId
)
708 : mProfilePath(aProfilePath
),
709 mPrivateBrowsingId(aPrivateBrowsingId
),
711 ::mozilla::ipc::AssertIsOnBackgroundThread();
713 // We are always open by IPC only
717 StorageDBParent::~StorageDBParent() {
718 ::mozilla::ipc::AssertIsOnBackgroundThread();
721 mObserverSink
->Stop();
722 mObserverSink
= nullptr;
726 void StorageDBParent::Init() {
727 ::mozilla::ipc::AssertIsOnBackgroundThread();
729 PBackgroundParent
* actor
= Manager();
732 if (::mozilla::ipc::BackgroundParent::IsOtherProcessActor(actor
)) {
733 mObserverSink
= new ObserverSink(this);
734 mObserverSink
->Start();
737 StorageDBThread
* storageThread
= StorageDBThread::Get(mPrivateBrowsingId
);
739 nsTArray
<nsCString
> scopes
;
740 storageThread
->GetOriginsHavingData(&scopes
);
741 mozilla::Unused
<< SendOriginsHavingData(scopes
);
745 StorageDBParent::CacheParentBridge
* StorageDBParent::NewCache(
746 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
) {
747 return new CacheParentBridge(this, aOriginSuffix
, aOriginNoSuffix
);
750 void StorageDBParent::ActorDestroy(ActorDestroyReason aWhy
) {
751 // Implement me! Bug 1005169
754 mozilla::ipc::IPCResult
StorageDBParent::RecvDeleteMe() {
755 ::mozilla::ipc::AssertIsOnBackgroundThread();
757 IProtocol
* mgr
= Manager();
758 if (!PBackgroundStorageParent::Send__delete__(this)) {
759 return IPC_FAIL_NO_REASON(mgr
);
764 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncPreload(
765 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
766 const bool& aPriority
) {
767 StorageDBThread
* storageThread
=
768 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
769 if (!storageThread
) {
770 return IPC_FAIL_NO_REASON(this);
773 storageThread
->AsyncPreload(NewCache(aOriginSuffix
, aOriginNoSuffix
),
779 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncGetUsage(
780 const nsCString
& aOriginNoSuffix
) {
781 StorageDBThread
* storageThread
=
782 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
783 if (!storageThread
) {
784 return IPC_FAIL_NO_REASON(this);
787 // The object releases it self in LoadUsage method
788 RefPtr
<UsageParentBridge
> usage
=
789 new UsageParentBridge(this, aOriginNoSuffix
);
791 storageThread
->AsyncGetUsage(usage
);
798 // We need another implementation of LocalStorageCacheBridge to do
799 // synchronous IPC preload. This class just receives Load* notifications
800 // and fills the returning arguments of RecvPreload with the database
802 class SyncLoadCacheHelper
: public LocalStorageCacheBridge
{
804 SyncLoadCacheHelper(const nsCString
& aOriginSuffix
,
805 const nsCString
& aOriginNoSuffix
,
806 uint32_t aAlreadyLoadedCount
, nsTArray
<nsString
>* aKeys
,
807 nsTArray
<nsString
>* aValues
, nsresult
* rv
)
808 : mMonitor("DOM Storage SyncLoad IPC"),
809 mSuffix(aOriginSuffix
),
810 mOrigin(aOriginNoSuffix
),
815 mLoadedCount(aAlreadyLoadedCount
) {
817 *mRv
= NS_ERROR_UNEXPECTED
;
820 virtual const nsCString
Origin() const override
{
821 return LocalStorageManager::CreateOrigin(mSuffix
, mOrigin
);
823 virtual const nsCString
& OriginNoSuffix() const override
{ return mOrigin
; }
824 virtual const nsCString
& OriginSuffix() const override
{ return mSuffix
; }
825 virtual bool Loaded() override
{ return mLoaded
; }
826 virtual uint32_t LoadedCount() override
{ return mLoadedCount
; }
827 virtual bool LoadItem(const nsAString
& aKey
,
828 const nsString
& aValue
) override
{
829 // Called on the aCache background thread
830 MOZ_ASSERT(!mLoaded
);
836 mKeys
->AppendElement(aKey
);
837 mValues
->AppendElement(aValue
);
841 virtual void LoadDone(nsresult aRv
) override
{
842 // Called on the aCache background thread
843 MonitorAutoLock
monitor(mMonitor
);
844 MOZ_ASSERT(!mLoaded
&& mRv
);
853 virtual void LoadWait() override
{
854 // Called on the main thread, exits after LoadDone() call
855 MonitorAutoLock
monitor(mMonitor
);
862 Monitor mMonitor MOZ_UNANNOTATED
;
863 nsCString mSuffix
, mOrigin
;
864 nsTArray
<nsString
>* mKeys
;
865 nsTArray
<nsString
>* mValues
;
868 uint32_t mLoadedCount
;
873 mozilla::ipc::IPCResult
StorageDBParent::RecvPreload(
874 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
875 const uint32_t& aAlreadyLoadedCount
, nsTArray
<nsString
>* aKeys
,
876 nsTArray
<nsString
>* aValues
, nsresult
* aRv
) {
877 StorageDBThread
* storageThread
=
878 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
879 if (!storageThread
) {
880 return IPC_FAIL_NO_REASON(this);
883 RefPtr
<SyncLoadCacheHelper
> cache(
884 new SyncLoadCacheHelper(aOriginSuffix
, aOriginNoSuffix
,
885 aAlreadyLoadedCount
, aKeys
, aValues
, aRv
));
887 storageThread
->SyncPreload(cache
, true);
892 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncAddItem(
893 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
894 const nsString
& aKey
, const nsString
& aValue
) {
895 StorageDBThread
* storageThread
=
896 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
897 if (!storageThread
) {
898 return IPC_FAIL_NO_REASON(this);
901 nsresult rv
= storageThread
->AsyncAddItem(
902 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
, aValue
);
903 if (NS_FAILED(rv
) && mIPCOpen
) {
904 mozilla::Unused
<< SendError(rv
);
910 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncUpdateItem(
911 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
912 const nsString
& aKey
, const nsString
& aValue
) {
913 StorageDBThread
* storageThread
=
914 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
915 if (!storageThread
) {
916 return IPC_FAIL_NO_REASON(this);
919 nsresult rv
= storageThread
->AsyncUpdateItem(
920 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
, aValue
);
921 if (NS_FAILED(rv
) && mIPCOpen
) {
922 mozilla::Unused
<< SendError(rv
);
928 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncRemoveItem(
929 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
,
930 const nsString
& aKey
) {
931 StorageDBThread
* storageThread
=
932 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
933 if (!storageThread
) {
934 return IPC_FAIL_NO_REASON(this);
937 nsresult rv
= storageThread
->AsyncRemoveItem(
938 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
);
939 if (NS_FAILED(rv
) && mIPCOpen
) {
940 mozilla::Unused
<< SendError(rv
);
946 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncClear(
947 const nsCString
& aOriginSuffix
, const nsCString
& aOriginNoSuffix
) {
948 StorageDBThread
* storageThread
=
949 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
950 if (!storageThread
) {
951 return IPC_FAIL_NO_REASON(this);
955 storageThread
->AsyncClear(NewCache(aOriginSuffix
, aOriginNoSuffix
));
956 if (NS_FAILED(rv
) && mIPCOpen
) {
957 mozilla::Unused
<< SendError(rv
);
963 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncFlush() {
964 StorageDBThread
* storageThread
= StorageDBThread::Get(mPrivateBrowsingId
);
965 if (!storageThread
) {
966 return IPC_FAIL_NO_REASON(this);
969 storageThread
->AsyncFlush();
974 mozilla::ipc::IPCResult
StorageDBParent::RecvStartup() {
975 StorageDBThread
* storageThread
=
976 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
977 if (!storageThread
) {
978 return IPC_FAIL_NO_REASON(this);
984 mozilla::ipc::IPCResult
StorageDBParent::RecvClearAll() {
985 StorageDBThread
* storageThread
=
986 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
987 if (!storageThread
) {
988 return IPC_FAIL_NO_REASON(this);
991 storageThread
->AsyncClearAll();
996 mozilla::ipc::IPCResult
StorageDBParent::RecvClearMatchingOrigin(
997 const nsCString
& aOriginNoSuffix
) {
998 StorageDBThread
* storageThread
=
999 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
1000 if (!storageThread
) {
1001 return IPC_FAIL_NO_REASON(this);
1004 storageThread
->AsyncClearMatchingOrigin(aOriginNoSuffix
);
1009 mozilla::ipc::IPCResult
StorageDBParent::RecvClearMatchingOriginAttributes(
1010 const OriginAttributesPattern
& aPattern
) {
1011 StorageDBThread
* storageThread
=
1012 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
1013 if (!storageThread
) {
1014 return IPC_FAIL_NO_REASON(this);
1017 storageThread
->AsyncClearMatchingOriginAttributes(aPattern
);
1022 void StorageDBParent::Observe(const nsCString
& aTopic
,
1023 const nsString
& aOriginAttributesPattern
,
1024 const nsCString
& aOriginScope
) {
1026 mozilla::Unused
<< SendObserve(aTopic
, aOriginAttributesPattern
,
1033 // Results must be sent back on the main thread
1034 class LoadRunnable
: public Runnable
{
1036 enum TaskType
{ loadItem
, loadDone
};
1038 LoadRunnable(StorageDBParent
* aParent
, TaskType aType
,
1039 const nsACString
& aOriginSuffix
,
1040 const nsACString
& aOriginNoSuffix
,
1041 const nsAString
& aKey
= u
""_ns
, const nsAString
& aValue
= u
""_ns
)
1042 : Runnable("dom::LoadRunnable"),
1045 mSuffix(aOriginSuffix
),
1046 mOrigin(aOriginNoSuffix
),
1049 mRv(NS_ERROR_NOT_INITIALIZED
) {}
1051 LoadRunnable(StorageDBParent
* aParent
, TaskType aType
,
1052 const nsACString
& aOriginSuffix
,
1053 const nsACString
& aOriginNoSuffix
, nsresult aRv
)
1054 : Runnable("dom::LoadRunnable"),
1057 mSuffix(aOriginSuffix
),
1058 mOrigin(aOriginNoSuffix
),
1062 RefPtr
<StorageDBParent
> mParent
;
1064 nsCString mSuffix
, mOrigin
;
1069 NS_IMETHOD
Run() override
{
1070 if (!mParent
->IPCOpen()) {
1076 mozilla::Unused
<< mParent
->SendLoadItem(mSuffix
, mOrigin
, mKey
,
1080 mozilla::Unused
<< mParent
->SendLoadDone(mSuffix
, mOrigin
, mRv
);
1092 // StorageDBParent::CacheParentBridge
1094 const nsCString
StorageDBParent::CacheParentBridge::Origin() const {
1095 return LocalStorageManager::CreateOrigin(mOriginSuffix
, mOriginNoSuffix
);
1098 bool StorageDBParent::CacheParentBridge::LoadItem(const nsAString
& aKey
,
1099 const nsString
& aValue
) {
1106 RefPtr
<LoadRunnable
> r
=
1107 new LoadRunnable(mParent
, LoadRunnable::loadItem
, mOriginSuffix
,
1108 mOriginNoSuffix
, aKey
, aValue
);
1110 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1115 void StorageDBParent::CacheParentBridge::LoadDone(nsresult aRv
) {
1116 // Prevent send of duplicate LoadDone.
1123 RefPtr
<LoadRunnable
> r
= new LoadRunnable(
1124 mParent
, LoadRunnable::loadDone
, mOriginSuffix
, mOriginNoSuffix
, aRv
);
1126 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1129 void StorageDBParent::CacheParentBridge::LoadWait() {
1130 // Should never be called on this implementation
1135 // This should be just:
1136 // NS_IMPL_RELEASE_WITH_DESTROY(StorageDBParent::CacheParentBridge, Destroy)
1137 // But due to different strings used for refcount logging and different return
1138 // types, this is done manually for now.
1139 NS_IMETHODIMP_(void)
1140 StorageDBParent::CacheParentBridge::Release(void) {
1141 MOZ_ASSERT(int32_t(mRefCnt
) > 0, "dup release");
1142 nsrefcnt count
= --mRefCnt
;
1143 NS_LOG_RELEASE(this, count
, "LocalStorageCacheBridge");
1145 mRefCnt
= 1; /* stabilize */
1146 /* enable this to find non-threadsafe destructors: */
1147 /* NS_ASSERT_OWNINGTHREAD(_class); */
1152 void StorageDBParent::CacheParentBridge::Destroy() {
1153 if (mOwningEventTarget
->IsOnCurrentThread()) {
1158 RefPtr
<Runnable
> destroyRunnable
= NewNonOwningRunnableMethod(
1159 "CacheParentBridge::Destroy", this, &CacheParentBridge::Destroy
);
1161 MOZ_ALWAYS_SUCCEEDS(
1162 mOwningEventTarget
->Dispatch(destroyRunnable
, NS_DISPATCH_NORMAL
));
1165 // StorageDBParent::UsageParentBridge
1169 class UsageRunnable
: public Runnable
{
1171 UsageRunnable(StorageDBParent
* aParent
, const nsACString
& aOriginScope
,
1172 const int64_t& aUsage
)
1173 : Runnable("dom::UsageRunnable"),
1175 mOriginScope(aOriginScope
),
1179 NS_IMETHOD
Run() override
{
1180 if (!mParent
->IPCOpen()) {
1184 mozilla::Unused
<< mParent
->SendLoadUsage(mOriginScope
, mUsage
);
1191 RefPtr
<StorageDBParent
> mParent
;
1192 nsCString mOriginScope
;
1198 void StorageDBParent::UsageParentBridge::LoadUsage(const int64_t aUsage
) {
1199 RefPtr
<UsageRunnable
> r
= new UsageRunnable(mParent
, mOriginScope
, aUsage
);
1201 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1205 // This should be just:
1206 // NS_IMPL_RELEASE_WITH_DESTROY(StorageDBParent::UsageParentBridge, Destroy)
1207 // But due to different strings used for refcount logging, this is done manually
1209 NS_IMETHODIMP_(MozExternalRefCountType
)
1210 StorageDBParent::UsageParentBridge::Release(void) {
1211 MOZ_ASSERT(int32_t(mRefCnt
) > 0, "dup release");
1212 nsrefcnt count
= --mRefCnt
;
1213 NS_LOG_RELEASE(this, count
, "StorageUsageBridge");
1221 void StorageDBParent::UsageParentBridge::Destroy() {
1222 if (mOwningEventTarget
->IsOnCurrentThread()) {
1227 RefPtr
<Runnable
> destroyRunnable
= NewNonOwningRunnableMethod(
1228 "UsageParentBridge::Destroy", this, &UsageParentBridge::Destroy
);
1230 MOZ_ALWAYS_SUCCEEDS(
1231 mOwningEventTarget
->Dispatch(destroyRunnable
, NS_DISPATCH_NORMAL
));
1234 void StorageDBParent::ObserverSink::Start() {
1235 ::mozilla::ipc::AssertIsOnBackgroundThread();
1237 RefPtr
<Runnable
> runnable
=
1238 NewRunnableMethod("StorageDBParent::ObserverSink::AddSink", this,
1239 &StorageDBParent::ObserverSink::AddSink
);
1241 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable
));
1244 void StorageDBParent::ObserverSink::Stop() {
1245 ::mozilla::ipc::AssertIsOnBackgroundThread();
1249 RefPtr
<Runnable
> runnable
=
1250 NewRunnableMethod("StorageDBParent::ObserverSink::RemoveSink", this,
1251 &StorageDBParent::ObserverSink::RemoveSink
);
1253 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable
));
1256 void StorageDBParent::ObserverSink::AddSink() {
1257 MOZ_ASSERT(NS_IsMainThread());
1259 StorageObserver
* observer
= StorageObserver::Self();
1261 observer
->AddSink(this);
1265 void StorageDBParent::ObserverSink::RemoveSink() {
1266 MOZ_ASSERT(NS_IsMainThread());
1268 StorageObserver
* observer
= StorageObserver::Self();
1270 observer
->RemoveSink(this);
1274 void StorageDBParent::ObserverSink::Notify(
1275 const nsCString
& aTopic
, const nsString
& aOriginAttributesPattern
,
1276 const nsCString
& aOriginScope
) {
1277 ::mozilla::ipc::AssertIsOnBackgroundThread();
1280 mActor
->Observe(aTopic
, aOriginAttributesPattern
, aOriginScope
);
1284 nsresult
StorageDBParent::ObserverSink::Observe(
1285 const char* aTopic
, const nsAString
& aOriginAttributesPattern
,
1286 const nsACString
& aOriginScope
) {
1287 MOZ_ASSERT(NS_IsMainThread());
1289 RefPtr
<Runnable
> runnable
= NewRunnableMethod
<nsCString
, nsString
, nsCString
>(
1290 "StorageDBParent::ObserverSink::Observe2", this,
1291 &StorageDBParent::ObserverSink::Notify
, aTopic
, aOriginAttributesPattern
,
1294 MOZ_ALWAYS_SUCCEEDS(
1295 mOwningEventTarget
->Dispatch(runnable
, NS_DISPATCH_NORMAL
));
1300 SessionStorageObserverParent::SessionStorageObserverParent()
1301 : mActorDestroyed(false) {
1302 MOZ_ASSERT(NS_IsMainThread());
1304 StorageObserver
* observer
= StorageObserver::Self();
1306 observer
->AddSink(this);
1310 SessionStorageObserverParent::~SessionStorageObserverParent() {
1311 MOZ_ASSERT(mActorDestroyed
);
1313 StorageObserver
* observer
= StorageObserver::Self();
1315 observer
->RemoveSink(this);
1319 void SessionStorageObserverParent::ActorDestroy(ActorDestroyReason aWhy
) {
1320 MOZ_ASSERT(NS_IsMainThread());
1321 MOZ_ASSERT(!mActorDestroyed
);
1323 mActorDestroyed
= true;
1326 mozilla::ipc::IPCResult
SessionStorageObserverParent::RecvDeleteMe() {
1327 MOZ_ASSERT(NS_IsMainThread());
1328 MOZ_ASSERT(!mActorDestroyed
);
1330 IProtocol
* mgr
= Manager();
1331 if (!PSessionStorageObserverParent::Send__delete__(this)) {
1332 return IPC_FAIL_NO_REASON(mgr
);
1337 nsresult
SessionStorageObserverParent::Observe(
1338 const char* aTopic
, const nsAString
& aOriginAttributesPattern
,
1339 const nsACString
& aOriginScope
) {
1340 MOZ_ASSERT(NS_IsMainThread());
1342 if (!mActorDestroyed
) {
1343 mozilla::Unused
<< SendObserve(nsCString(aTopic
),
1344 nsString(aOriginAttributesPattern
),
1345 nsCString(aOriginScope
));
1350 SessionStorageCacheParent::SessionStorageCacheParent(
1351 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
1352 const nsCString
& aOriginKey
, SessionStorageManagerParent
* aActor
)
1353 : mPrincipalInfo(aPrincipalInfo
),
1354 mOriginKey(aOriginKey
),
1355 mManagerActor(aActor
) {
1356 ::mozilla::ipc::AssertIsOnBackgroundThread();
1357 MOZ_ASSERT(mManagerActor
);
1360 SessionStorageCacheParent::~SessionStorageCacheParent() = default;
1362 void SessionStorageCacheParent::ActorDestroy(ActorDestroyReason aWhy
) {
1363 ::mozilla::ipc::AssertIsOnBackgroundThread();
1365 mManagerActor
= nullptr;
1368 mozilla::ipc::IPCResult
SessionStorageCacheParent::RecvLoad(
1369 nsTArray
<SSSetItemInfo
>* aData
) {
1370 ::mozilla::ipc::AssertIsOnBackgroundThread();
1371 MOZ_ASSERT(mManagerActor
);
1373 mLoadReceived
.Flip();
1375 RefPtr
<BackgroundSessionStorageManager
> manager
= mManagerActor
->GetManager();
1376 MOZ_ASSERT(manager
);
1378 OriginAttributes attrs
;
1380 StoragePrincipalHelper::GetOriginAttributes(mPrincipalInfo
, attrs
));
1382 nsAutoCString originAttrs
;
1383 attrs
.CreateSuffix(originAttrs
);
1385 manager
->CopyDataToContentProcess(originAttrs
, mOriginKey
, *aData
);
1390 mozilla::ipc::IPCResult
SessionStorageCacheParent::RecvCheckpoint(
1391 nsTArray
<SSWriteInfo
>&& aWriteInfos
) {
1392 ::mozilla::ipc::AssertIsOnBackgroundThread();
1393 MOZ_ASSERT(mManagerActor
);
1395 RefPtr
<BackgroundSessionStorageManager
> manager
= mManagerActor
->GetManager();
1396 MOZ_ASSERT(manager
);
1398 OriginAttributes attrs
;
1399 StoragePrincipalHelper::GetOriginAttributes(mPrincipalInfo
, attrs
);
1401 nsAutoCString originAttrs
;
1402 attrs
.CreateSuffix(originAttrs
);
1404 manager
->UpdateData(originAttrs
, mOriginKey
, aWriteInfos
);
1409 mozilla::ipc::IPCResult
SessionStorageCacheParent::RecvDeleteMe() {
1410 ::mozilla::ipc::AssertIsOnBackgroundThread();
1411 MOZ_ASSERT(mManagerActor
);
1413 mManagerActor
= nullptr;
1415 IProtocol
* mgr
= Manager();
1416 if (!PBackgroundSessionStorageCacheParent::Send__delete__(this)) {
1418 mgr
, "Failed to delete PBackgroundSessionStorageCacheParent actor");
1423 SessionStorageManagerParent::SessionStorageManagerParent(uint64_t aTopContextId
)
1424 : mBackgroundManager(
1425 BackgroundSessionStorageManager::GetOrCreate(aTopContextId
)) {
1426 ::mozilla::ipc::AssertIsOnBackgroundThread();
1427 MOZ_ASSERT(mBackgroundManager
);
1428 mBackgroundManager
->AddParticipatingActor(this);
1431 SessionStorageManagerParent::~SessionStorageManagerParent() = default;
1433 void SessionStorageManagerParent::ActorDestroy(ActorDestroyReason aWhy
) {
1434 ::mozilla::ipc::AssertIsOnBackgroundThread();
1436 if (mBackgroundManager
) {
1437 mBackgroundManager
->RemoveParticipatingActor(this);
1440 mBackgroundManager
= nullptr;
1443 already_AddRefed
<PBackgroundSessionStorageCacheParent
>
1444 SessionStorageManagerParent::AllocPBackgroundSessionStorageCacheParent(
1445 const PrincipalInfo
& aPrincipalInfo
, const nsCString
& aOriginKey
) {
1446 return MakeAndAddRef
<SessionStorageCacheParent
>(aPrincipalInfo
, aOriginKey
,
1450 BackgroundSessionStorageManager
* SessionStorageManagerParent::GetManager()
1452 return mBackgroundManager
;
1455 mozilla::ipc::IPCResult
SessionStorageManagerParent::RecvClearStorages(
1456 const OriginAttributesPattern
& aPattern
, const nsCString
& aOriginScope
) {
1457 ::mozilla::ipc::AssertIsOnBackgroundThread();
1458 mBackgroundManager
->ClearStorages(aPattern
, aOriginScope
);
1462 mozilla::ipc::IPCResult
SessionStorageManagerParent::RecvDeleteMe() {
1463 ::mozilla::ipc::AssertIsOnBackgroundThread();
1464 MOZ_ASSERT(mBackgroundManager
);
1466 mBackgroundManager
->RemoveParticipatingActor(this);
1468 mBackgroundManager
= nullptr;
1470 IProtocol
* mgr
= Manager();
1471 if (!PBackgroundSessionStorageManagerParent::Send__delete__(this)) {
1473 mgr
, "Failed to delete PBackgroundSessionStorageManagerParent actor");
1478 /*******************************************************************************
1479 * Exported functions
1480 ******************************************************************************/
1482 PBackgroundLocalStorageCacheParent
* AllocPBackgroundLocalStorageCacheParent(
1483 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
1484 const nsCString
& aOriginKey
, const uint32_t& aPrivateBrowsingId
) {
1485 ::mozilla::ipc::AssertIsOnBackgroundThread();
1487 RefPtr
<LocalStorageCacheParent
> actor
= new LocalStorageCacheParent(
1488 aPrincipalInfo
, aOriginKey
, aPrivateBrowsingId
);
1490 // Transfer ownership to IPDL.
1491 return actor
.forget().take();
1494 mozilla::ipc::IPCResult
RecvPBackgroundLocalStorageCacheConstructor(
1495 mozilla::ipc::PBackgroundParent
* aBackgroundActor
,
1496 PBackgroundLocalStorageCacheParent
* aActor
,
1497 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
1498 const nsCString
& aOriginKey
, const uint32_t& aPrivateBrowsingId
) {
1499 ::mozilla::ipc::AssertIsOnBackgroundThread();
1502 auto* actor
= static_cast<LocalStorageCacheParent
*>(aActor
);
1504 if (!gLocalStorageCacheParents
) {
1505 gLocalStorageCacheParents
= new LocalStorageCacheParentHashtable();
1508 gLocalStorageCacheParents
->GetOrInsertNew(aOriginKey
)->AppendElement(actor
);
1510 // We are currently trusting the content process not to lie to us. It is
1511 // future work to consult the ClientManager to determine whether this is a
1512 // legitimate origin for the content process.
1517 bool DeallocPBackgroundLocalStorageCacheParent(
1518 PBackgroundLocalStorageCacheParent
* aActor
) {
1519 ::mozilla::ipc::AssertIsOnBackgroundThread();
1522 // Transfer ownership back from IPDL.
1523 RefPtr
<LocalStorageCacheParent
> actor
=
1524 dont_AddRef(static_cast<LocalStorageCacheParent
*>(aActor
));
1529 PBackgroundStorageParent
* AllocPBackgroundStorageParent(
1530 const nsString
& aProfilePath
, const uint32_t& aPrivateBrowsingId
) {
1531 ::mozilla::ipc::AssertIsOnBackgroundThread();
1533 if (NS_WARN_IF(NextGenLocalStorageEnabled()) ||
1534 NS_WARN_IF(aPrivateBrowsingId
>= kPrivateBrowsingIdCount
)) {
1538 return new StorageDBParent(aProfilePath
, aPrivateBrowsingId
);
1541 mozilla::ipc::IPCResult
RecvPBackgroundStorageConstructor(
1542 PBackgroundStorageParent
* aActor
, const nsString
& aProfilePath
,
1543 const uint32_t& aPrivateBrowsingId
) {
1544 ::mozilla::ipc::AssertIsOnBackgroundThread();
1546 MOZ_ASSERT(aPrivateBrowsingId
< kPrivateBrowsingIdCount
);
1547 MOZ_ASSERT(!NextGenLocalStorageEnabled());
1549 auto* actor
= static_cast<StorageDBParent
*>(aActor
);
1554 bool DeallocPBackgroundStorageParent(PBackgroundStorageParent
* aActor
) {
1555 ::mozilla::ipc::AssertIsOnBackgroundThread();
1558 StorageDBParent
* actor
= static_cast<StorageDBParent
*>(aActor
);
1559 actor
->ReleaseIPDLReference();
1563 PSessionStorageObserverParent
* AllocPSessionStorageObserverParent() {
1564 MOZ_ASSERT(NS_IsMainThread());
1566 RefPtr
<SessionStorageObserverParent
> actor
=
1567 new SessionStorageObserverParent();
1569 // Transfer ownership to IPDL.
1570 return actor
.forget().take();
1573 bool RecvPSessionStorageObserverConstructor(
1574 PSessionStorageObserverParent
* aActor
) {
1575 MOZ_ASSERT(NS_IsMainThread());
1581 bool DeallocPSessionStorageObserverParent(
1582 PSessionStorageObserverParent
* aActor
) {
1583 MOZ_ASSERT(NS_IsMainThread());
1586 // Transfer ownership back from IPDL.
1587 RefPtr
<SessionStorageObserverParent
> actor
=
1588 dont_AddRef(static_cast<SessionStorageObserverParent
*>(aActor
));
1593 already_AddRefed
<PBackgroundSessionStorageManagerParent
>
1594 AllocPBackgroundSessionStorageManagerParent(const uint64_t& aTopContextId
) {
1595 return MakeAndAddRef
<SessionStorageManagerParent
>(aTopContextId
);
1598 } // namespace mozilla::dom