Bug 1769952 - Fix running raptor on a Win10-64 VM r=sparky
[gecko.git] / dom / storage / Storage.cpp
blobdeda546fcaaae610fd699e3eaca8c86a1c6a7782
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 "Storage.h"
8 #include "StorageNotifierService.h"
10 #include "mozilla/dom/StorageBinding.h"
11 #include "mozilla/dom/StorageEvent.h"
12 #include "mozilla/dom/StorageEventBinding.h"
13 #include "mozilla/BasePrincipal.h"
14 #include "mozilla/Preferences.h"
15 #include "mozilla/SchedulerGroup.h"
16 #include "mozilla/Services.h"
17 #include "mozilla/StorageAccess.h"
18 #include "nsIObserverService.h"
19 #include "nsPIDOMWindow.h"
21 namespace mozilla::dom {
23 static const char kStorageEnabled[] = "dom.storage.enabled";
25 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Storage, mWindow, mPrincipal,
26 mStoragePrincipal)
28 NS_IMPL_CYCLE_COLLECTING_ADDREF(Storage)
29 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(Storage, LastRelease())
31 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Storage)
32 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
33 NS_INTERFACE_MAP_ENTRY(nsISupports)
34 NS_INTERFACE_MAP_END
36 Storage::Storage(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
37 nsIPrincipal* aStoragePrincipal)
38 : mWindow(aWindow),
39 mPrincipal(aPrincipal),
40 mStoragePrincipal(aStoragePrincipal),
41 mPrivateBrowsing(false),
42 mSessionScopedOrLess(false) {
43 MOZ_ASSERT(aPrincipal);
45 if (mPrincipal->IsSystemPrincipal()) {
46 mPrivateBrowsing = false;
47 mSessionScopedOrLess = false;
48 } else if (mWindow) {
49 uint32_t rejectedReason = 0;
50 StorageAccess access = StorageAllowedForWindow(mWindow, &rejectedReason);
52 mPrivateBrowsing = access == StorageAccess::ePrivateBrowsing;
53 mSessionScopedOrLess = access <= StorageAccess::eSessionScoped;
57 Storage::~Storage() = default;
59 /* static */
60 bool Storage::StoragePrefIsEnabled() {
61 return mozilla::Preferences::GetBool(kStorageEnabled);
64 int64_t Storage::GetSnapshotUsage(nsIPrincipal& aSubjectPrincipal,
65 ErrorResult& aRv) {
66 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
67 return 0;
70 bool Storage::CanUseStorage(nsIPrincipal& aSubjectPrincipal) {
71 if (!StoragePrefIsEnabled()) {
72 return false;
75 return aSubjectPrincipal.Subsumes(mPrincipal);
78 /* virtual */
79 JSObject* Storage::WrapObject(JSContext* aCx,
80 JS::Handle<JSObject*> aGivenProto) {
81 return Storage_Binding::Wrap(aCx, this, aGivenProto);
84 namespace {
86 class StorageNotifierRunnable : public Runnable {
87 public:
88 StorageNotifierRunnable(nsISupports* aSubject, const char16_t* aStorageType,
89 bool aPrivateBrowsing)
90 : Runnable("StorageNotifierRunnable"),
91 mSubject(aSubject),
92 mStorageType(aStorageType),
93 mPrivateBrowsing(aPrivateBrowsing) {}
95 NS_IMETHOD
96 Run() override {
97 nsCOMPtr<nsIObserverService> observerService =
98 mozilla::services::GetObserverService();
99 if (observerService) {
100 observerService->NotifyObservers(mSubject,
101 mPrivateBrowsing
102 ? "dom-private-storage2-changed"
103 : "dom-storage2-changed",
104 mStorageType);
106 return NS_OK;
109 private:
110 nsCOMPtr<nsISupports> mSubject;
111 const char16_t* mStorageType;
112 const bool mPrivateBrowsing;
115 } // namespace
117 /* static */
118 void Storage::NotifyChange(Storage* aStorage, nsIPrincipal* aPrincipal,
119 const nsAString& aKey, const nsAString& aOldValue,
120 const nsAString& aNewValue,
121 const char16_t* aStorageType,
122 const nsAString& aDocumentURI, bool aIsPrivate,
123 bool aImmediateDispatch) {
124 StorageEventInit dict;
125 dict.mBubbles = false;
126 dict.mCancelable = false;
127 dict.mKey = aKey;
128 dict.mNewValue = aNewValue;
129 dict.mOldValue = aOldValue;
130 dict.mStorageArea = aStorage;
131 dict.mUrl = aDocumentURI;
133 // Note, this DOM event should never reach JS. It is cloned later in
134 // nsGlobalWindow.
135 RefPtr<StorageEvent> event =
136 StorageEvent::Constructor(nullptr, u"storage"_ns, dict);
138 event->SetPrincipal(aPrincipal);
140 // This will send the event to any registered window.
141 StorageNotifierService::Broadcast(event, aStorageType, aIsPrivate,
142 aImmediateDispatch);
144 // This runnable is mainly used by devtools. Windows receive notification by
145 // StorageNotifierService.
147 RefPtr<StorageNotifierRunnable> r =
148 new StorageNotifierRunnable(event, aStorageType, aIsPrivate);
150 if (aImmediateDispatch) {
151 Unused << r->Run();
152 } else {
153 SchedulerGroup::Dispatch(TaskCategory::Other, r.forget());
157 } // namespace mozilla::dom