||Minimal glue actor with standard IPC-managed new/delete existence that exists
primarily to track the continued existence of the LSDatabase in the child.
Most of the interesting bits happen via PBackgroundLSSnapshot.
Mutual raw pointers are maintained between LSDatabase and this class that are
cleared at either (expected) when the child starts the deletion process
(SendDeleteMeInternal) or unexpected actor death (ActorDestroy).
See `PBackgroundLSDatabase.ipdl` for more information.
## Low-Level Lifecycle ##
- Created by LSObject::EnsureDatabase if it had to create a database.
- Deletion begun by LSDatabase's destructor invoking SendDeleteMeInternal
which will result in the parent sending __delete__ which destroys the
||The AsyncRequestHelper has been created and dispatched to the
||Under LSNG this exposes nsILocalStorageManager::Preload to ContentParent to
trigger preloading. Otherwise, this is basically just a place for test logic
that doesn't make sense to put directly on the Storage WebIDL interface.
Previously, the nsIDOMStorageManager XPCOM interface was also used by
nsGlobalWindowInner to interact with LocalStorage, but in these de-XPCOM
days, we've moved to just directly reference the relevant concrete classes
(ex: LSObject) directly.
Note that testing methods are now also directly exposed on the Storage WebIDL
interface for simplicity/sanity.
||Automatically cancel and abort synchronous LocalStorage requests (for example
datastore preparation) if they take this long. We've chosen a value that is
long enough that it is unlikely for the problem to be falsely triggered by
slow system I/O. We've also chosen a value long enough so that automated
tests should time out and fail if LocalStorage hangs. Also, this value is
long enough so that testers can notice the (content process) hang; we want to
know about the hangs, not hide them. On the other hand this value is less
than 60 seconds which is used by nsTerminator to crash a hung main process.
||Backs the WebIDL `Storage` binding; all content LocalStorage calls are
handled by this class.
## Semantics under e10s / multi-process ##
A snapshot mechanism used in conjuction with stable points ensures that JS
run-to-completion semantics are experienced even if the same origin is
concurrently accessing LocalStorage across multiple content processes.
### Snapshot Consistency ###
An LSSnapshot is created locally whenever the contents of LocalStorage are
about to be read or written (including length). This synchronously
establishes a corresponding Snapshot in PBackground in the parent process.
An effort is made to send as much data from the parent process as possible,
so sites using a small/reasonable amount of LocalStorage data will have it
sent to the content process for immediate access. Sites with greater
LocalStorage usage may only have some of the information relayed. In that
case, the parent Snapshot will ensure that it retains the exact state of the
parent Datastore at the moment the Snapshot was created.
||Effectively just a refcounted life-cycle management wrapper around
LSObserverChild which exists to receive "storage" event information from
other processes. (Same-process events are handled within the process, see
## Lifecycle ##
- Created by LSObject::EnsureObserver via synchronous LSRequest idiom
whenever the first window's origin adds a "storage" event. Placed in the
gLSObservers LSObserverHashtable for subsequent LSObject's via
- The LSObserverChild directly handles "Observe" messages, shunting them
directly to Storage::NotifyChange which does all the legwork of notifying
windows about "storage" events.
- Destroyed when refcount goes to zero due to all owning LSObjects being
destroyed or having their `LSObject::DropObserver` methods invoked due to
the last "storage" event listener being removed from the owning window.
||Coalescing manipulation queue used by `LSSnapshot`. Used by `LSSnapshot` to
buffer and coalesce manipulations before they are sent to the parent process,
when a Snapshot Checkpoints. (This can only be done when there are no
observers for other content processes.)
||The LoadState expresses what subset of information a snapshot has from the
authoritative Datastore in the parent process. The initial snapshot is
populated heuristically based on the size of the keys and size of the items
(inclusive of the key value; item is key+value, not just value) of the
entire datastore relative to the configured prefill limit (via pref
"dom.storage.snapshot_prefill" exposed as gSnapshotPrefill in bytes).
If there's less data than the limit, we send both keys and values and end
up as AllOrderedItems. If there's enough room for all the keys but not
all the values, we end up as AllOrderedKeys with as many values present as
would fit. If there's not enough room for all the keys, then we end up as
Partial with as many key-value pairs as will fit.
The state AllUnorderedItems can only be reached by code getting items one
||Represents a LocalStorage value. From content's perspective, values (if
present) are always DOMStrings. This is also true from a quota-tracking
perspective. However, for memory and disk efficiency it's preferable to store
the value in alternate compressed or utf-8 encoding representations. The
LSValue type exists to support these alternate representations, dynamically
decompressing/re-encoding to utf-16 while still tracking value size on a
utf-16 basis for quota purposes.
||Base class for coalescing manipulation queue.
||Methods specific to LocalStorage, see nsIDOMStorageManager for methods shared
with SessionStorage. Methods may migrate there as SessionStorage is
||Initial LSSnapshot state as produced by Datastore::GetSnapshotLoadInfo. See
`LSSnapshot::LoadState` for more details about the possible states and a
high level overview.
||The observer protocol sends "storage" event notifications for changes to
LocalStorage that take place in other processes as their Snapshots are
Checkpointed to the canonical Datastore in the parent process. Same-process
notifications are generated as mutations happen.
Note that mutations are never generated for redundant mutations. Setting the
key "foo" to have value "bar" when it already has value "bar" will never
result in a "storage" event.
||Discriminated union which can contain an error code (`nsresult`) or
particular request response.
||In order to validate the principal with the client, we need to provide an
additional principalInfo for the client. The client is using the foreign
principal, see StoragePrincipalHelper.h for details, which is different from
the principalInfo. So, we need to pass the principalInfo from the client So
that we can verify it with the given client Id.
Note that the storagePrincipalInfo is used to access the right cookie jar
according to the Storage Access. This is passed in order to access the
correct local storage. Essentially, the storage principal and the client
principal are using the PartitionKey in their OriginAttributes. But, the
existence of the PartitionKey between them is depending on different
conditions. Namely, the storage principal depends on the Storage Access but
the client principal depends on whether it's in a third party.
||Response to a `LSSimpleRequestPreloadedParams` request indicating whether the
origin was preloaded.
||Union of LocalStorage mutation types.
||Internal errors are chrome context only