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 nsAString
& aDocumentURI
,
83 const nsAString
& aKey
, const nsAString
& aOldValue
,
84 const nsAString
& 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 nsACString
& aTopic
, const nsAString
& aOriginAttributesPattern
,
348 const nsACString
& aOriginScope
) {
349 MOZ_ASSERT(!XRE_IsParentProcess());
351 if (StorageObserver
* obs
= StorageObserver::Self()) {
352 obs
->Notify(PromiseFlatCString(aTopic
).get(), aOriginAttributesPattern
,
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 nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
376 const nsAString
& aKey
, const nsAString
& aValue
) {
377 LocalStorageCache
* aCache
=
378 mManager
->GetCache(aOriginSuffix
, aOriginNoSuffix
);
380 aCache
->LoadItem(aKey
, aValue
);
386 mozilla::ipc::IPCResult
StorageDBChild::RecvLoadDone(
387 const nsACString
& aOriginSuffix
, const nsACString
& 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 nsACString
& 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 nsACString
& aTopic
, const nsAString
& aOriginAttributesPattern
,
486 const nsACString
& aOriginScope
) {
487 AssertIsOnOwningThread();
489 if (StorageObserver
* obs
= StorageObserver::Self()) {
490 obs
->Notify(PromiseFlatCString(aTopic
).get(), aOriginAttributesPattern
,
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 nsACString
& aOriginAttrs
, const nsACString
& 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 nsAString
& aDocumentURI
, const nsAString
& aKey
,
627 const nsAString
& aOldValue
, const nsAString
& 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(GetCurrentSerialEventTarget()), mActor(aActor
) {
664 ::mozilla::ipc::AssertIsOnBackgroundThread();
668 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StorageDBParent::ObserverSink
);
675 ~ObserverSink() = default;
681 void Notify(const nsACString
& aTopic
,
682 const nsAString
& aOriginAttributesPattern
,
683 const nsACString
& aOriginScope
);
685 // StorageObserverSink
686 nsresult
Observe(const char* aTopic
, const nsAString
& aOriginAttrPattern
,
687 const nsACString
& aOriginScope
) override
;
690 NS_IMPL_ADDREF(StorageDBParent
)
691 NS_IMPL_RELEASE(StorageDBParent
)
693 void StorageDBParent::AddIPDLReference() {
694 MOZ_ASSERT(!mIPCOpen
, "Attempting to retain multiple IPDL references");
699 void StorageDBParent::ReleaseIPDLReference() {
700 MOZ_ASSERT(mIPCOpen
, "Attempting to release non-existent IPDL reference");
705 namespace {} // namespace
707 StorageDBParent::StorageDBParent(const nsAString
& aProfilePath
,
708 const uint32_t aPrivateBrowsingId
)
709 : mProfilePath(aProfilePath
),
710 mPrivateBrowsingId(aPrivateBrowsingId
),
712 ::mozilla::ipc::AssertIsOnBackgroundThread();
714 // We are always open by IPC only
718 StorageDBParent::~StorageDBParent() {
719 ::mozilla::ipc::AssertIsOnBackgroundThread();
722 mObserverSink
->Stop();
723 mObserverSink
= nullptr;
727 void StorageDBParent::Init() {
728 ::mozilla::ipc::AssertIsOnBackgroundThread();
730 PBackgroundParent
* actor
= Manager();
733 if (::mozilla::ipc::BackgroundParent::IsOtherProcessActor(actor
)) {
734 mObserverSink
= new ObserverSink(this);
735 mObserverSink
->Start();
738 StorageDBThread
* storageThread
= StorageDBThread::Get(mPrivateBrowsingId
);
740 nsTArray
<nsCString
> scopes
;
741 storageThread
->GetOriginsHavingData(&scopes
);
742 mozilla::Unused
<< SendOriginsHavingData(scopes
);
746 StorageDBParent::CacheParentBridge
* StorageDBParent::NewCache(
747 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
) {
748 return new CacheParentBridge(this, aOriginSuffix
, aOriginNoSuffix
);
751 void StorageDBParent::ActorDestroy(ActorDestroyReason aWhy
) {
752 // Implement me! Bug 1005169
755 mozilla::ipc::IPCResult
StorageDBParent::RecvDeleteMe() {
756 ::mozilla::ipc::AssertIsOnBackgroundThread();
758 IProtocol
* mgr
= Manager();
759 if (!PBackgroundStorageParent::Send__delete__(this)) {
760 return IPC_FAIL_NO_REASON(mgr
);
765 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncPreload(
766 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
767 const bool& aPriority
) {
768 StorageDBThread
* storageThread
=
769 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
770 if (!storageThread
) {
771 return IPC_FAIL_NO_REASON(this);
774 storageThread
->AsyncPreload(NewCache(aOriginSuffix
, aOriginNoSuffix
),
780 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncGetUsage(
781 const nsACString
& aOriginNoSuffix
) {
782 StorageDBThread
* storageThread
=
783 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
784 if (!storageThread
) {
785 return IPC_FAIL_NO_REASON(this);
788 // The object releases it self in LoadUsage method
789 RefPtr
<UsageParentBridge
> usage
=
790 new UsageParentBridge(this, aOriginNoSuffix
);
792 storageThread
->AsyncGetUsage(usage
);
799 // We need another implementation of LocalStorageCacheBridge to do
800 // synchronous IPC preload. This class just receives Load* notifications
801 // and fills the returning arguments of RecvPreload with the database
803 class SyncLoadCacheHelper
: public LocalStorageCacheBridge
{
805 SyncLoadCacheHelper(const nsACString
& aOriginSuffix
,
806 const nsACString
& aOriginNoSuffix
,
807 uint32_t aAlreadyLoadedCount
, nsTArray
<nsString
>* aKeys
,
808 nsTArray
<nsString
>* aValues
, nsresult
* rv
)
809 : mMonitor("DOM Storage SyncLoad IPC"),
810 mSuffix(aOriginSuffix
),
811 mOrigin(aOriginNoSuffix
),
816 mLoadedCount(aAlreadyLoadedCount
) {
818 *mRv
= NS_ERROR_UNEXPECTED
;
821 virtual const nsCString
Origin() const override
{
822 return LocalStorageManager::CreateOrigin(mSuffix
, mOrigin
);
824 virtual const nsCString
& OriginNoSuffix() const override
{ return mOrigin
; }
825 virtual const nsCString
& OriginSuffix() const override
{ return mSuffix
; }
826 virtual bool Loaded() override
{ return mLoaded
; }
827 virtual uint32_t LoadedCount() override
{ return mLoadedCount
; }
828 virtual bool LoadItem(const nsAString
& aKey
,
829 const nsAString
& aValue
) override
{
830 // Called on the aCache background thread
831 MOZ_ASSERT(!mLoaded
);
837 mKeys
->AppendElement(aKey
);
838 mValues
->AppendElement(aValue
);
842 virtual void LoadDone(nsresult aRv
) override
{
843 // Called on the aCache background thread
844 MonitorAutoLock
monitor(mMonitor
);
845 MOZ_ASSERT(!mLoaded
&& mRv
);
854 virtual void LoadWait() override
{
855 // Called on the main thread, exits after LoadDone() call
856 MonitorAutoLock
monitor(mMonitor
);
863 Monitor mMonitor MOZ_UNANNOTATED
;
864 nsCString mSuffix
, mOrigin
;
865 nsTArray
<nsString
>* mKeys
;
866 nsTArray
<nsString
>* mValues
;
869 uint32_t mLoadedCount
;
874 mozilla::ipc::IPCResult
StorageDBParent::RecvPreload(
875 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
876 const uint32_t& aAlreadyLoadedCount
, nsTArray
<nsString
>* aKeys
,
877 nsTArray
<nsString
>* aValues
, nsresult
* aRv
) {
878 StorageDBThread
* storageThread
=
879 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
880 if (!storageThread
) {
881 return IPC_FAIL_NO_REASON(this);
884 RefPtr
<SyncLoadCacheHelper
> cache(
885 new SyncLoadCacheHelper(aOriginSuffix
, aOriginNoSuffix
,
886 aAlreadyLoadedCount
, aKeys
, aValues
, aRv
));
888 storageThread
->SyncPreload(cache
, true);
893 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncAddItem(
894 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
895 const nsAString
& aKey
, const nsAString
& aValue
) {
896 StorageDBThread
* storageThread
=
897 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
898 if (!storageThread
) {
899 return IPC_FAIL_NO_REASON(this);
902 nsresult rv
= storageThread
->AsyncAddItem(
903 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
, aValue
);
904 if (NS_FAILED(rv
) && mIPCOpen
) {
905 mozilla::Unused
<< SendError(rv
);
911 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncUpdateItem(
912 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
913 const nsAString
& aKey
, const nsAString
& aValue
) {
914 StorageDBThread
* storageThread
=
915 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
916 if (!storageThread
) {
917 return IPC_FAIL_NO_REASON(this);
920 nsresult rv
= storageThread
->AsyncUpdateItem(
921 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
, aValue
);
922 if (NS_FAILED(rv
) && mIPCOpen
) {
923 mozilla::Unused
<< SendError(rv
);
929 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncRemoveItem(
930 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
,
931 const nsAString
& aKey
) {
932 StorageDBThread
* storageThread
=
933 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
934 if (!storageThread
) {
935 return IPC_FAIL_NO_REASON(this);
938 nsresult rv
= storageThread
->AsyncRemoveItem(
939 NewCache(aOriginSuffix
, aOriginNoSuffix
), aKey
);
940 if (NS_FAILED(rv
) && mIPCOpen
) {
941 mozilla::Unused
<< SendError(rv
);
947 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncClear(
948 const nsACString
& aOriginSuffix
, const nsACString
& aOriginNoSuffix
) {
949 StorageDBThread
* storageThread
=
950 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
951 if (!storageThread
) {
952 return IPC_FAIL_NO_REASON(this);
956 storageThread
->AsyncClear(NewCache(aOriginSuffix
, aOriginNoSuffix
));
957 if (NS_FAILED(rv
) && mIPCOpen
) {
958 mozilla::Unused
<< SendError(rv
);
964 mozilla::ipc::IPCResult
StorageDBParent::RecvAsyncFlush() {
965 StorageDBThread
* storageThread
= StorageDBThread::Get(mPrivateBrowsingId
);
966 if (!storageThread
) {
967 return IPC_FAIL_NO_REASON(this);
970 storageThread
->AsyncFlush();
975 mozilla::ipc::IPCResult
StorageDBParent::RecvStartup() {
976 StorageDBThread
* storageThread
=
977 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
978 if (!storageThread
) {
979 return IPC_FAIL_NO_REASON(this);
985 mozilla::ipc::IPCResult
StorageDBParent::RecvClearAll() {
986 StorageDBThread
* storageThread
=
987 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
988 if (!storageThread
) {
989 return IPC_FAIL_NO_REASON(this);
992 storageThread
->AsyncClearAll();
997 mozilla::ipc::IPCResult
StorageDBParent::RecvClearMatchingOrigin(
998 const nsACString
& aOriginNoSuffix
) {
999 StorageDBThread
* storageThread
=
1000 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
1001 if (!storageThread
) {
1002 return IPC_FAIL_NO_REASON(this);
1005 storageThread
->AsyncClearMatchingOrigin(aOriginNoSuffix
);
1010 mozilla::ipc::IPCResult
StorageDBParent::RecvClearMatchingOriginAttributes(
1011 const OriginAttributesPattern
& aPattern
) {
1012 StorageDBThread
* storageThread
=
1013 StorageDBThread::GetOrCreate(mProfilePath
, mPrivateBrowsingId
);
1014 if (!storageThread
) {
1015 return IPC_FAIL_NO_REASON(this);
1018 storageThread
->AsyncClearMatchingOriginAttributes(aPattern
);
1023 void StorageDBParent::Observe(const nsACString
& aTopic
,
1024 const nsAString
& aOriginAttributesPattern
,
1025 const nsACString
& aOriginScope
) {
1027 mozilla::Unused
<< SendObserve(aTopic
, aOriginAttributesPattern
,
1034 // Results must be sent back on the main thread
1035 class LoadRunnable
: public Runnable
{
1037 enum TaskType
{ loadItem
, loadDone
};
1039 LoadRunnable(StorageDBParent
* aParent
, TaskType aType
,
1040 const nsACString
& aOriginSuffix
,
1041 const nsACString
& aOriginNoSuffix
,
1042 const nsAString
& aKey
= u
""_ns
, const nsAString
& aValue
= u
""_ns
)
1043 : Runnable("dom::LoadRunnable"),
1046 mSuffix(aOriginSuffix
),
1047 mOrigin(aOriginNoSuffix
),
1050 mRv(NS_ERROR_NOT_INITIALIZED
) {}
1052 LoadRunnable(StorageDBParent
* aParent
, TaskType aType
,
1053 const nsACString
& aOriginSuffix
,
1054 const nsACString
& aOriginNoSuffix
, nsresult aRv
)
1055 : Runnable("dom::LoadRunnable"),
1058 mSuffix(aOriginSuffix
),
1059 mOrigin(aOriginNoSuffix
),
1063 RefPtr
<StorageDBParent
> mParent
;
1065 nsCString mSuffix
, mOrigin
;
1070 NS_IMETHOD
Run() override
{
1071 if (!mParent
->IPCOpen()) {
1077 mozilla::Unused
<< mParent
->SendLoadItem(mSuffix
, mOrigin
, mKey
,
1081 mozilla::Unused
<< mParent
->SendLoadDone(mSuffix
, mOrigin
, mRv
);
1093 // StorageDBParent::CacheParentBridge
1095 const nsCString
StorageDBParent::CacheParentBridge::Origin() const {
1096 return LocalStorageManager::CreateOrigin(mOriginSuffix
, mOriginNoSuffix
);
1099 bool StorageDBParent::CacheParentBridge::LoadItem(const nsAString
& aKey
,
1100 const nsAString
& aValue
) {
1107 RefPtr
<LoadRunnable
> r
=
1108 new LoadRunnable(mParent
, LoadRunnable::loadItem
, mOriginSuffix
,
1109 mOriginNoSuffix
, aKey
, aValue
);
1111 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1116 void StorageDBParent::CacheParentBridge::LoadDone(nsresult aRv
) {
1117 // Prevent send of duplicate LoadDone.
1124 RefPtr
<LoadRunnable
> r
= new LoadRunnable(
1125 mParent
, LoadRunnable::loadDone
, mOriginSuffix
, mOriginNoSuffix
, aRv
);
1127 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1130 void StorageDBParent::CacheParentBridge::LoadWait() {
1131 // Should never be called on this implementation
1136 // This should be just:
1137 // NS_IMPL_RELEASE_WITH_DESTROY(StorageDBParent::CacheParentBridge, Destroy)
1138 // But due to different strings used for refcount logging and different return
1139 // types, this is done manually for now.
1140 NS_IMETHODIMP_(void)
1141 StorageDBParent::CacheParentBridge::Release(void) {
1142 MOZ_ASSERT(int32_t(mRefCnt
) > 0, "dup release");
1143 nsrefcnt count
= --mRefCnt
;
1144 NS_LOG_RELEASE(this, count
, "LocalStorageCacheBridge");
1146 mRefCnt
= 1; /* stabilize */
1147 /* enable this to find non-threadsafe destructors: */
1148 /* NS_ASSERT_OWNINGTHREAD(_class); */
1153 void StorageDBParent::CacheParentBridge::Destroy() {
1154 if (mOwningEventTarget
->IsOnCurrentThread()) {
1159 RefPtr
<Runnable
> destroyRunnable
= NewNonOwningRunnableMethod(
1160 "CacheParentBridge::Destroy", this, &CacheParentBridge::Destroy
);
1162 MOZ_ALWAYS_SUCCEEDS(
1163 mOwningEventTarget
->Dispatch(destroyRunnable
, NS_DISPATCH_NORMAL
));
1166 // StorageDBParent::UsageParentBridge
1170 class UsageRunnable
: public Runnable
{
1172 UsageRunnable(StorageDBParent
* aParent
, const nsACString
& aOriginScope
,
1173 const int64_t& aUsage
)
1174 : Runnable("dom::UsageRunnable"),
1176 mOriginScope(aOriginScope
),
1180 NS_IMETHOD
Run() override
{
1181 if (!mParent
->IPCOpen()) {
1185 mozilla::Unused
<< mParent
->SendLoadUsage(mOriginScope
, mUsage
);
1192 RefPtr
<StorageDBParent
> mParent
;
1193 nsCString mOriginScope
;
1199 void StorageDBParent::UsageParentBridge::LoadUsage(const int64_t aUsage
) {
1200 RefPtr
<UsageRunnable
> r
= new UsageRunnable(mParent
, mOriginScope
, aUsage
);
1202 MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget
->Dispatch(r
, NS_DISPATCH_NORMAL
));
1206 // This should be just:
1207 // NS_IMPL_RELEASE_WITH_DESTROY(StorageDBParent::UsageParentBridge, Destroy)
1208 // But due to different strings used for refcount logging, this is done manually
1210 NS_IMETHODIMP_(MozExternalRefCountType
)
1211 StorageDBParent::UsageParentBridge::Release(void) {
1212 MOZ_ASSERT(int32_t(mRefCnt
) > 0, "dup release");
1213 nsrefcnt count
= --mRefCnt
;
1214 NS_LOG_RELEASE(this, count
, "StorageUsageBridge");
1222 void StorageDBParent::UsageParentBridge::Destroy() {
1223 if (mOwningEventTarget
->IsOnCurrentThread()) {
1228 RefPtr
<Runnable
> destroyRunnable
= NewNonOwningRunnableMethod(
1229 "UsageParentBridge::Destroy", this, &UsageParentBridge::Destroy
);
1231 MOZ_ALWAYS_SUCCEEDS(
1232 mOwningEventTarget
->Dispatch(destroyRunnable
, NS_DISPATCH_NORMAL
));
1235 void StorageDBParent::ObserverSink::Start() {
1236 ::mozilla::ipc::AssertIsOnBackgroundThread();
1238 RefPtr
<Runnable
> runnable
=
1239 NewRunnableMethod("StorageDBParent::ObserverSink::AddSink", this,
1240 &StorageDBParent::ObserverSink::AddSink
);
1242 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable
));
1245 void StorageDBParent::ObserverSink::Stop() {
1246 ::mozilla::ipc::AssertIsOnBackgroundThread();
1250 RefPtr
<Runnable
> runnable
=
1251 NewRunnableMethod("StorageDBParent::ObserverSink::RemoveSink", this,
1252 &StorageDBParent::ObserverSink::RemoveSink
);
1254 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable
));
1257 void StorageDBParent::ObserverSink::AddSink() {
1258 MOZ_ASSERT(NS_IsMainThread());
1260 StorageObserver
* observer
= StorageObserver::Self();
1262 observer
->AddSink(this);
1266 void StorageDBParent::ObserverSink::RemoveSink() {
1267 MOZ_ASSERT(NS_IsMainThread());
1269 StorageObserver
* observer
= StorageObserver::Self();
1271 observer
->RemoveSink(this);
1275 void StorageDBParent::ObserverSink::Notify(
1276 const nsACString
& aTopic
, const nsAString
& aOriginAttributesPattern
,
1277 const nsACString
& aOriginScope
) {
1278 ::mozilla::ipc::AssertIsOnBackgroundThread();
1281 mActor
->Observe(aTopic
, aOriginAttributesPattern
, aOriginScope
);
1285 nsresult
StorageDBParent::ObserverSink::Observe(
1286 const char* aTopic
, const nsAString
& aOriginAttributesPattern
,
1287 const nsACString
& aOriginScope
) {
1288 MOZ_ASSERT(NS_IsMainThread());
1290 RefPtr
<Runnable
> runnable
= NewRunnableMethod
<nsCString
, nsString
, nsCString
>(
1291 "StorageDBParent::ObserverSink::Observe2", this,
1292 &StorageDBParent::ObserverSink::Notify
, aTopic
, aOriginAttributesPattern
,
1295 MOZ_ALWAYS_SUCCEEDS(
1296 mOwningEventTarget
->Dispatch(runnable
, NS_DISPATCH_NORMAL
));
1301 SessionStorageObserverParent::SessionStorageObserverParent()
1302 : mActorDestroyed(false) {
1303 MOZ_ASSERT(NS_IsMainThread());
1305 StorageObserver
* observer
= StorageObserver::Self();
1307 observer
->AddSink(this);
1311 SessionStorageObserverParent::~SessionStorageObserverParent() {
1312 MOZ_ASSERT(mActorDestroyed
);
1314 StorageObserver
* observer
= StorageObserver::Self();
1316 observer
->RemoveSink(this);
1320 void SessionStorageObserverParent::ActorDestroy(ActorDestroyReason aWhy
) {
1321 MOZ_ASSERT(NS_IsMainThread());
1322 MOZ_ASSERT(!mActorDestroyed
);
1324 mActorDestroyed
= true;
1327 mozilla::ipc::IPCResult
SessionStorageObserverParent::RecvDeleteMe() {
1328 MOZ_ASSERT(NS_IsMainThread());
1329 MOZ_ASSERT(!mActorDestroyed
);
1331 IProtocol
* mgr
= Manager();
1332 if (!PSessionStorageObserverParent::Send__delete__(this)) {
1333 return IPC_FAIL_NO_REASON(mgr
);
1338 nsresult
SessionStorageObserverParent::Observe(
1339 const char* aTopic
, const nsAString
& aOriginAttributesPattern
,
1340 const nsACString
& aOriginScope
) {
1341 MOZ_ASSERT(NS_IsMainThread());
1343 if (!mActorDestroyed
) {
1344 mozilla::Unused
<< SendObserve(nsDependentCString(aTopic
),
1345 aOriginAttributesPattern
, aOriginScope
);
1350 SessionStorageCacheParent::SessionStorageCacheParent(
1351 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
1352 const nsACString
& 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 nsACString
& 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 nsACString
& 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 nsACString
& 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 nsACString
& 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 nsAString
& 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 nsAString
& 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