diff options
Diffstat (limited to 'services/interfaces')
-rw-r--r-- | services/interfaces/moz.build | 19 | ||||
-rw-r--r-- | services/interfaces/mozIAppServicesLogger.idl | 11 | ||||
-rw-r--r-- | services/interfaces/mozIBridgedSyncEngine.idl | 160 | ||||
-rw-r--r-- | services/interfaces/mozIInterruptible.idl | 13 | ||||
-rw-r--r-- | services/interfaces/mozIServicesLogSink.idl | 26 |
5 files changed, 229 insertions, 0 deletions
diff --git a/services/interfaces/moz.build b/services/interfaces/moz.build new file mode 100644 index 0000000000..18b570f63c --- /dev/null +++ b/services/interfaces/moz.build @@ -0,0 +1,19 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +with Files("**"): + BUG_COMPONENT = ("Firefox", "Sync") + +# Services interfaces are shared with other components (like Places and +# WebExtension storage), so we keep them in a separate folder and build them for +# all configurations, regardless of whether we build Sync. + +XPIDL_MODULE = "services" + +XPIDL_SOURCES += [ + "mozIAppServicesLogger.idl", + "mozIBridgedSyncEngine.idl", + "mozIInterruptible.idl", + "mozIServicesLogSink.idl", +] diff --git a/services/interfaces/mozIAppServicesLogger.idl b/services/interfaces/mozIAppServicesLogger.idl new file mode 100644 index 0000000000..17d8c87c3a --- /dev/null +++ b/services/interfaces/mozIAppServicesLogger.idl @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "mozIServicesLogSink.idl" + +[scriptable, uuid(446dd837-fbb0-41e4-8221-f740f672b20d)] +interface mozIAppServicesLogger : nsISupports { + void register(in AString target, in mozIServicesLogSink logger); +}; diff --git a/services/interfaces/mozIBridgedSyncEngine.idl b/services/interfaces/mozIBridgedSyncEngine.idl new file mode 100644 index 0000000000..72683abf22 --- /dev/null +++ b/services/interfaces/mozIBridgedSyncEngine.idl @@ -0,0 +1,160 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozIServicesLogSink.idl" +#include "nsISupports.idl" + +interface nsIVariant; + +// A generic callback called with a result. Variants are automatically unboxed +// in JavaScript: for example, a `UTF8String` will be passed as a string +// argument; an `Int32` or `Int64` as a number. Methods that don't return a +// value, like `setLastSync` or `setUploaded`, will pass a `null` variant to +// `handleSuccess`. For all callback types in this file, either `handleSuccess` +// or `handleError` is guaranteed to be called once. +[scriptable, uuid(9b7dd2a3-df99-4469-9ea9-61b222098695)] +interface mozIBridgedSyncEngineCallback : nsISupports { + void handleSuccess(in nsIVariant result); + void handleError(in nsresult code, in AUTF8String message); +}; + +// A callback called after the engine applies incoming records. This is separate +// from `mozIBridgedSyncEngineCallback` because variants can't hold an +// `Array<T>` type. +[scriptable, uuid(2776cdd5-799a-4009-b2f3-356d940a5244)] +interface mozIBridgedSyncEngineApplyCallback : nsISupports { + // Notifies Sync that the bridged engine has finished applying incoming + // records, and has outgoing records. Sync encrypts and uploads these + // records, and notifies the engine that the upload succeeded by + // calling `engine.setUploaded(uploadedOutgoingRecordIds, ...)`. + void handleSuccess(in Array<AUTF8String> outgoingEnvelopesAsJSON); + + // Notifies Sync that the bridged engine failed to apply the staged records. + void handleError(in nsresult code, in AUTF8String message); +}; + +// A bridged engine is implemented in Rust. It handles storage internally, and +// exposes a minimal interface for the JS Sync code to control it. +[scriptable, uuid(3b2b80be-c30e-4498-8065-01809cfe8d47)] +interface mozIBridgedSyncEngine : nsISupports { + // The storage version for this engine's collection. If the version in the + // server's `meta/global` record is newer than ours, we'll refuse to sync, + // since we might not understand the data; if it's older, we'll wipe the + // collection on the server, and upload our data as if on a first sync. + readonly attribute long storageVersion; + + // Whether this engine tolerates skipped records, where a "skipped" record + // is one that would cause the server's published limits to be exceeded + // (for example, a single record where the payload is larger than the + // server accepts.) + // If this returns true, we will just skip the record without even attempting + // to upload. If this is false, we'll abort the entire batch. + // If the engine allows this, it will need to detect this scenario by noticing + // the ID is not in the 'success' records reported to `setUploaded`. + // (Note that this is not to be confused with the fact server's can currently + // reject records as part of a POST - but we hope to remove this ability from + // the server API. Note also that this is not bullet-proof - if the count of + // records is high, it's possible that we will have committed a previous + // batch before we hit the relevant limits, so things might have been written. + // We hope to fix this by ensuring batch limits are such that this is + // impossible) + readonly attribute boolean allowSkippedRecord; + + // Wires up the Sync logging machinery to the bridged engine. This can be + // `null`, in which case any logs from the engine will be discarded. + attribute mozIServicesLogSink logger; + + // Returns the last sync time, in milliseconds, for this engine's + // collection. This is used to build the collection URL for fetching + // incoming records, and as the initial value of the `X-I-U-S` header on + // upload. If the engine persists incoming records in a permanent (non-temp) + // table, `getLastSync` can return a "high water mark" that's the newer of + // the collection's last sync time, and the most recent record modification + // time. This avoids redownloading incoming records that were previously + // downloaded, but not applied. + void getLastSync(in mozIBridgedSyncEngineCallback callback); + + // Sets the last sync time, in milliseconds. This is used to fast-forward + // the last sync time for the engine's collection after fetching all + // records, and after each `setUploaded` call with the `X-L-M` header from + // the server. It may be called multiple times per sync. + void setLastSync(in long long lastSyncMillis, + in mozIBridgedSyncEngineCallback callback); + + // Returns the sync ID for this engine's collection. Used for testing; + // Sync only calls `ensureCurrentSyncId` and `resetSyncId`. On success, + // calls `callback.handleSuccess(in AUTF8String currentSyncId)`. + void getSyncId(in mozIBridgedSyncEngineCallback callback); + + // Generates a new sync ID for this engine, and resets all local Sync + // metadata, including the last sync time and any change flags, to start + // over as a first sync. On success, calls + // `callback.handleSuccess(newSyncId)`, where `newSyncId` is + // `AUTF8String` variant. Sync will upload the new sync ID in the + // `meta/global` record. + void resetSyncId(in mozIBridgedSyncEngineCallback callback); + + // Ensures that the local sync ID for the engine matches the sync ID for + // the collection on the server. On a mismatch, the engine can: + // 1. Reset all local Sync state, adopt `newSyncId` as the new sync ID, + // and call `callback.handleSuccess(newSyncId)`. Most engines should + // do this. + // 2. Ignore the given `newSyncId`, use its existing local sync ID + // without resetting any state, and call + // `callback.handleSuccess(existingSyncId)`. This is useful if, for + // example, the underlying database has been restored from a backup, + // and the engine would like to force a reset and first sync on all + // other devices. + // 3. Ignore the given `newSyncId`, reset all local Sync state, and + // generate a fresh sync ID, as if `resetSyncId`. This resets the + // engine's state everywhere, locally and on all other devices. + // If the callback is called with a different sync ID than `newSyncId`, + // Sync will reupload `meta/global` with the different ID. Otherwise, it + // will assume that the engine has adopted the `newSyncId`, and do nothing. + void ensureCurrentSyncId(in AUTF8String newSyncId, + in mozIBridgedSyncEngineCallback callback); + + // Notifies the engine that sync is starting. The engine can use this method + // to set up temp tables for merging, for example. This will only be called + // once per sync, and before any `storeIncoming` calls. + void syncStarted(in mozIBridgedSyncEngineCallback callback); + + // Stages a batch of incoming records, and calls the `callback` when + // done. This method may be called multiple times per sync, once per + // incoming batch, and always after `syncStarted`. Flushing incoming records + // more often incurs more writes to disk, but avoids redownloading and + // reapplying more records if syncing is interrupted. Typically, engines + // will stage incoming records in an SQLite temp table, and merge them with + // the local database when `apply` is called. + void storeIncoming(in Array<AUTF8String> incomingEnvelopesAsJSON, + in mozIBridgedSyncEngineCallback callback); + + // Applies all the staged records, and calls the `callback` with + // outgoing records to upload. This will always be called after + // `storeIncoming`, and only once per sync. Application should be atomic: + // either all incoming records apply successfully, or none. + void apply(in mozIBridgedSyncEngineApplyCallback callback); + + // Notifies the engine that Sync successfully uploaded the records with the + // given IDs. This method may be called multiple times per sync, once per + // batch upload. This will always be called after `apply`. + void setUploaded(in long long newTimestampMillis, + in Array<AUTF8String> uploadedIds, + in mozIBridgedSyncEngineCallback callback); + + // Notifies the engine that syncing has finished, and the engine shouldn't + // expect any more `setUploaded` calls. At this point, any outgoing records + // that weren't passed to `setUploaded` should be assumed failed. This is + // guaranteed to be called even if the sync fails. This will only be called + // once per sync. + void syncFinished(in mozIBridgedSyncEngineCallback callback); + + // Resets all local Sync metadata, including the sync ID, last sync time, + // and any change flags, but preserves all data. After a reset, the engine will + // sync as if for the first time. + void reset(in mozIBridgedSyncEngineCallback callback); + + // Erases all locally stored data and metadata for this engine. + void wipe(in mozIBridgedSyncEngineCallback callback); +}; diff --git a/services/interfaces/mozIInterruptible.idl b/services/interfaces/mozIInterruptible.idl new file mode 100644 index 0000000000..2894c428d6 --- /dev/null +++ b/services/interfaces/mozIInterruptible.idl @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +// Interrupts all pending operations on a data store, if possible. This is +// provided as a separate interface because the store may want to hide this +// implementation from callers, as interrupting a write can cause data loss. +[scriptable, uuid(1c06bfd3-76b1-46fa-a64a-db682d478374)] +interface mozIInterruptible : nsISupports { + void interrupt(); +}; diff --git a/services/interfaces/mozIServicesLogSink.idl b/services/interfaces/mozIServicesLogSink.idl new file mode 100644 index 0000000000..ea17750552 --- /dev/null +++ b/services/interfaces/mozIServicesLogSink.idl @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +// Adapts a `Log.sys.mjs` logger so that it can be used from native (Rust) code. +// The synced bookmarks mirror and bridged engines implement this interface +// to hook in to the services `LogManager` infrastructure. +[scriptable, uuid(c92bfe0d-50b7-4a7f-9686-fe5335a696b9)] +interface mozIServicesLogSink : nsISupports { + const short LEVEL_OFF = 0; + const short LEVEL_ERROR = 1; + const short LEVEL_WARN = 2; + const short LEVEL_INFO = 3; + const short LEVEL_DEBUG = 4; + const short LEVEL_TRACE = 5; + + attribute short maxLevel; + + void error(in AString message); + void warn(in AString message); + void debug(in AString message); + void trace(in AString message); + void info(in AString message); +}; |