Bug 1839170 - Refactor Snap pulling, Add Firefox Snap Core22 and GNOME 42 SDK symbols...
[gecko.git] / dom / localstorage / LSObject.h
blobd394816fa49dd83be8b68b4e2244b2a5f57515e1
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 #ifndef mozilla_dom_localstorage_LSObject_h
8 #define mozilla_dom_localstorage_LSObject_h
10 #include <cstdint>
11 #include "ErrorList.h"
12 #include "mozilla/AlreadyAddRefed.h"
13 #include "mozilla/Assertions.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/RefPtr.h"
16 #include "mozilla/UniquePtr.h"
17 #include "mozilla/dom/Storage.h"
18 #include "mozilla/ipc/PBackgroundSharedTypes.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsID.h"
21 #include "nsISupports.h"
22 #include "nsStringFwd.h"
23 #include "nsTArrayForwardDeclare.h"
25 class nsGlobalWindowInner;
26 class nsIEventTarget;
27 class nsIPrincipal;
28 class nsISerialEventTarget;
29 class nsPIDOMWindowInner;
31 namespace mozilla {
33 class ErrorResult;
35 namespace dom {
37 class LSDatabase;
38 class LSObjectChild;
39 class LSObserver;
40 class LSRequestChild;
41 class LSRequestChildCallback;
42 class LSRequestParams;
43 class LSRequestResponse;
45 /**
46 * Backs the WebIDL `Storage` binding; all content LocalStorage calls are
47 * handled by this class.
49 * ## Semantics under e10s / multi-process ##
51 * A snapshot mechanism used in conjuction with stable points ensures that JS
52 * run-to-completion semantics are experienced even if the same origin is
53 * concurrently accessing LocalStorage across multiple content processes.
55 * ### Snapshot Consistency ###
57 * An LSSnapshot is created locally whenever the contents of LocalStorage are
58 * about to be read or written (including length). This synchronously
59 * establishes a corresponding Snapshot in PBackground in the parent process.
60 * An effort is made to send as much data from the parent process as possible,
61 * so sites using a small/reasonable amount of LocalStorage data will have it
62 * sent to the content process for immediate access. Sites with greater
63 * LocalStorage usage may only have some of the information relayed. In that
64 * case, the parent Snapshot will ensure that it retains the exact state of the
65 * parent Datastore at the moment the Snapshot was created.
67 class LSObject final : public Storage {
68 using PrincipalInfo = mozilla::ipc::PrincipalInfo;
70 friend nsGlobalWindowInner;
72 UniquePtr<PrincipalInfo> mPrincipalInfo;
73 UniquePtr<PrincipalInfo> mStoragePrincipalInfo;
75 RefPtr<LSDatabase> mDatabase;
76 RefPtr<LSObserver> mObserver;
78 uint32_t mPrivateBrowsingId;
79 Maybe<nsID> mClientId;
80 Maybe<PrincipalInfo> mClientPrincipalInfo;
81 nsCString mOrigin;
82 nsCString mOriginKey;
83 nsString mDocumentURI;
85 bool mInExplicitSnapshot;
87 public:
88 /**
89 * The normal creation path invoked by nsGlobalWindowInner.
91 static nsresult CreateForWindow(nsPIDOMWindowInner* aWindow,
92 Storage** aStorage);
94 /**
95 * nsIDOMStorageManager creation path for use in testing logic. Supports the
96 * system principal where CreateForWindow does not. This is also why aPrivate
97 * exists separate from the principal; because the system principal can never
98 * be mutated to have a private browsing id even though it can be used in a
99 * window/document marked as private browsing. That's a legacy issue that is
100 * being dealt with, but it's why it exists here.
102 static nsresult CreateForPrincipal(nsPIDOMWindowInner* aWindow,
103 nsIPrincipal* aPrincipal,
104 nsIPrincipal* aStoragePrincipal,
105 const nsAString& aDocumentURI,
106 bool aPrivate, LSObject** aObject);
108 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSObject); }
110 const RefPtr<LSDatabase>& DatabaseStrongRef() const { return mDatabase; }
112 const nsString& DocumentURI() const { return mDocumentURI; }
114 bool InExplicitSnapshot() const { return mInExplicitSnapshot; }
116 LSRequestChild* StartRequest(const LSRequestParams& aParams,
117 LSRequestChildCallback* aCallback);
119 // Storage overrides.
120 StorageType Type() const override;
122 bool IsForkOf(const Storage* aStorage) const override;
124 int64_t GetOriginQuotaUsage() const override;
126 void Disconnect() override;
128 uint32_t GetLength(nsIPrincipal& aSubjectPrincipal,
129 ErrorResult& aError) override;
131 void Key(uint32_t aIndex, nsAString& aResult, nsIPrincipal& aSubjectPrincipal,
132 ErrorResult& aError) override;
134 void GetItem(const nsAString& aKey, nsAString& aResult,
135 nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
137 void GetSupportedNames(nsTArray<nsString>& aNames) override;
139 void SetItem(const nsAString& aKey, const nsAString& aValue,
140 nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
142 void RemoveItem(const nsAString& aKey, nsIPrincipal& aSubjectPrincipal,
143 ErrorResult& aError) override;
145 void Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
147 //////////////////////////////////////////////////////////////////////////////
148 // Testing Methods: See Storage.h
149 void Open(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
151 void Close(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
153 void BeginExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
154 ErrorResult& aError) override;
156 void CheckpointExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
157 ErrorResult& aError) override;
159 void EndExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
160 ErrorResult& aError) override;
162 bool GetHasSnapshot(nsIPrincipal& aSubjectPrincipal,
163 ErrorResult& aError) override;
165 int64_t GetSnapshotUsage(nsIPrincipal& aSubjectPrincipal,
166 ErrorResult& aError) override;
168 //////////////////////////////////////////////////////////////////////////////
170 NS_DECL_ISUPPORTS_INHERITED
171 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(LSObject, Storage)
173 private:
174 LSObject(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
175 nsIPrincipal* aStoragePrincipal);
177 ~LSObject();
179 nsresult DoRequestSynchronously(const LSRequestParams& aParams,
180 LSRequestResponse& aResponse);
182 nsresult EnsureDatabase();
184 void DropDatabase();
187 * Invoked by nsGlobalWindowInner whenever a new "storage" event listener is
188 * added to the window in order to ensure that "storage" events are received
189 * from other processes. (`LSObject::OnChange` directly invokes
190 * `Storage::NotifyChange` to notify in-process listeners.)
192 * If this is the first request in the process for an observer for this
193 * origin, this will trigger a RequestHelper-mediated synchronous LSRequest
194 * to prepare a new observer in the parent process and also construction of
195 * corresponding actors, which will result in the observer being fully
196 * registered in the parent process.
198 nsresult EnsureObserver();
201 * Invoked by nsGlobalWindowInner whenever its last "storage" event listener
202 * is removed.
204 void DropObserver();
207 * Internal helper method used by mutation methods that wraps the call to
208 * Storage::NotifyChange to generate same-process "storage" events.
210 void OnChange(const nsAString& aKey, const nsAString& aOldValue,
211 const nsAString& aNewValue);
213 // Storage overrides.
214 void LastRelease() override;
217 } // namespace dom
218 } // namespace mozilla
220 #endif // mozilla_dom_localstorage_LSObject_h