canmove, Confirmed users
409
edits
No edit summary |
No edit summary |
||
Line 21: | Line 21: | ||
|Feature overview=Add-ons are synchronized between sync clients. | |Feature overview=Add-ons are synchronized between sync clients. | ||
|Feature users and use cases=User installs an add-on on one browser. When a sync occurs, the add-on is automagically installed on other sync clients. | |Feature users and use cases=User installs an add-on on one browser. When a sync occurs, the add-on is automagically installed on other sync clients. | ||
|Feature functional spec=The Addon Manager maintainers would like to see Sync support all add-on providers so as to not introduce 1st and 2nd class providers | |Feature functional spec=The Addon Manager maintainers would like to see Sync support all add-on providers so as to not introduce 1st and 2nd class providers. | ||
The solution to this problem will consist of the following: | The solution to this problem will consist of the following: | ||
Line 38: | Line 38: | ||
The AddonManager will support the following APIs: | The AddonManager will support the following APIs: | ||
; getAddonBySyncGUID(syncGUID, callback) : Obtain an add-on from its Sync GUID. Calls the supplied function when that add-on is retrieved. The callback receives null on unknown add-on or the add-on object (generated from the underlying provider) on success. This API technically isn't required, but it makes the | ; getAddonBySyncGUID(syncGUID, callback) : Obtain an add-on from its Sync GUID. Calls the supplied function when that add-on is retrieved. The callback receives null on unknown add-on or the add-on object (generated from the underlying provider) on success. This API technically isn't required, but it makes the Sync code smaller by pushing out logic and possibly caching. | ||
; | ; applySyncRecords(records, callbackObj) : This applies an array of records that contain add-on metadata and makes the current state of the world agree with that data as much as possible. | ||
The callbackObj is an object containing the following optional keys: | The callbackObj is an object containing the following optional keys: | ||
Line 54: | Line 54: | ||
* isDeleted (optional) - If evaluates to true, indicates that the record was deleted. Application of this record should involve trying to delete this add-on if present or no-op if not present. | * isDeleted (optional) - If evaluates to true, indicates that the record was deleted. Application of this record should involve trying to delete this add-on if present or no-op if not present. | ||
The implementation of | The implementation of applySyncRecords() will resemble the following pseudocode: | ||
<pre> | <pre> | ||
Line 70: | Line 70: | ||
result = null | result = null | ||
if existing: | if existing: | ||
# ensure the Sync GUIDs agree. incoming records always win fight | |||
if existing.syncGUID != record.syncGUID: | |||
existing.syncGUID = record.syncGUID | |||
# TODO this probably requires additional API formalization. Each | |||
# provider likely has its own semantics. But, common operations would | |||
# likely include updating common add-on fields (like source and install | |||
# URLs) and upgrading the add-on version. | |||
result = existing.updateFromSyncData(record.syncData) | result = existing.updateFromSyncData(record.syncData) | ||
else: | else: | ||
Line 78: | Line 86: | ||
callbackObj.onFinished() | callbackObj.onFinished() | ||
</pre> | </pre> | ||
TODO: we should formalize how the Sync engine gets informed of whether a restart is required to finish the record application. Do we catch this in the tracker observers or install observers local to the sync method of the engine? | |||
The add-ons Sync engine will discover the set of add-ons that can be synced via the following procedure: | The add-ons Sync engine will discover the set of add-ons that can be synced via the following procedure: | ||
Line 96: | Line 106: | ||
When these are observed, the tracker will: | When these are observed, the tracker will: | ||
# Verify the changed add-on is in the set of Sync-able add-ons (using same heuristics as add-on discovery documented above) | # Verify the changed add-on is in the set of Sync-able add-ons (using same heuristics as add-on discovery documented above, if needed) | ||
# Mark the GUID as changed | # Mark the GUID as changed | ||
# This will result in a new record for that GUID being created automagically. The createRecord() procedure will create the necessary record which will be queued for upload to the Sync server. | # This will result in a new record for that GUID being created automagically. The createRecord() procedure will in turn create the necessary record by querying AddonManager which will be queued for upload to the Sync server. | ||
On start-up, the add-on engine will query AddonManager.getStartupChanges() for changes applied on application start-up. These are not observed by Sync because they occur before Sync is registered and running. Even if Sync does catch them in its tracker, it should be safe to mark records as changed. The only side-effect will be a slightly different modified time. | On start-up, the add-on engine will query AddonManager.getStartupChanges() for changes applied on application start-up. These are not observed by Sync because they occur before Sync is registered and running. Even if Sync does catch them in its tracker, it should be safe to mark records as changed. The only side-effect will be a slightly different modified time. | ||
Line 110: | Line 120: | ||
* STARTUP_CHANGE_ENABLED | * STARTUP_CHANGE_ENABLED | ||
TODO: Sync should catch all startup change types (the constants above) and react to them. We may need an API or some kind of verification/test to ensure newly-introduced startup changes/constants aren't missed by Sync. (This is all because getStartupChanges() | TODO: Sync should catch all startup change types (the constants above) and react to them. We may need an API or some kind of verification/test to ensure newly-introduced startup changes/constants aren't missed by Sync. (This is all because getStartupChanges() requires a type as a parameter.) | ||
}} | }} | ||
{{FeatureInfo | {{FeatureInfo |