services/sync/modules/engines/prefs.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 this.EXPORTED_SYMBOLS = ['PrefsEngine', 'PrefRec'];
     7 const Cc = Components.classes;
     8 const Ci = Components.interfaces;
     9 const Cu = Components.utils;
    11 const WEAVE_SYNC_PREFS = "services.sync.prefs.sync.";
    13 Cu.import("resource://services-sync/engines.js");
    14 Cu.import("resource://services-sync/record.js");
    15 Cu.import("resource://services-sync/util.js");
    16 Cu.import("resource://services-sync/constants.js");
    17 Cu.import("resource://services-common/utils.js");
    18 Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
    19 Cu.import("resource://gre/modules/Preferences.jsm");
    21 const PREFS_GUID = CommonUtils.encodeBase64URL(Services.appinfo.ID);
    23 this.PrefRec = function PrefRec(collection, id) {
    24   CryptoWrapper.call(this, collection, id);
    25 }
    26 PrefRec.prototype = {
    27   __proto__: CryptoWrapper.prototype,
    28   _logName: "Sync.Record.Pref",
    29 };
    31 Utils.deferGetSet(PrefRec, "cleartext", ["value"]);
    34 this.PrefsEngine = function PrefsEngine(service) {
    35   SyncEngine.call(this, "Prefs", service);
    36 }
    37 PrefsEngine.prototype = {
    38   __proto__: SyncEngine.prototype,
    39   _storeObj: PrefStore,
    40   _trackerObj: PrefTracker,
    41   _recordObj: PrefRec,
    42   version: 2,
    44   getChangedIDs: function getChangedIDs() {
    45     // No need for a proper timestamp (no conflict resolution needed).
    46     let changedIDs = {};
    47     if (this._tracker.modified)
    48       changedIDs[PREFS_GUID] = 0;
    49     return changedIDs;
    50   },
    52   _wipeClient: function _wipeClient() {
    53     SyncEngine.prototype._wipeClient.call(this);
    54     this.justWiped = true;
    55   },
    57   _reconcile: function _reconcile(item) {
    58     // Apply the incoming item if we don't care about the local data
    59     if (this.justWiped) {
    60       this.justWiped = false;
    61       return true;
    62     }
    63     return SyncEngine.prototype._reconcile.call(this, item);
    64   }
    65 };
    68 function PrefStore(name, engine) {
    69   Store.call(this, name, engine);
    70   Svc.Obs.add("profile-before-change", function () {
    71     this.__prefs = null;
    72   }, this);
    73 }
    74 PrefStore.prototype = {
    75   __proto__: Store.prototype,
    77  __prefs: null,
    78   get _prefs() {
    79     if (!this.__prefs)
    80       this.__prefs = new Preferences();
    81     return this.__prefs;
    82   },
    84   _getSyncPrefs: function _getSyncPrefs() {
    85     let syncPrefs = Cc["@mozilla.org/preferences-service;1"]
    86                       .getService(Ci.nsIPrefService)
    87                       .getBranch(WEAVE_SYNC_PREFS)
    88                       .getChildList("", {});
    89     // Also sync preferences that determine which prefs get synced.
    90     return syncPrefs.concat(
    91       syncPrefs.map(function (pref) { return WEAVE_SYNC_PREFS + pref; }));
    92   },
    94   _isSynced: function _isSyncedPref(pref) {
    95     return (pref.indexOf(WEAVE_SYNC_PREFS) == 0)
    96             || this._prefs.get(WEAVE_SYNC_PREFS + pref, false);
    97   },
    99   _getAllPrefs: function () {
   100     let values = {};
   101     for each (let pref in this._getSyncPrefs()) {
   102       if (this._isSynced(pref)) {
   103         // Missing prefs get the null value.
   104         values[pref] = this._prefs.get(pref, null);
   105       }
   106     }
   107     return values;
   108   },
   110   _setAllPrefs: function PrefStore__setAllPrefs(values) {
   111     let enabledPref = "lightweightThemes.isThemeSelected";
   112     let enabledBefore = this._prefs.get(enabledPref, false);
   113     let prevTheme = LightweightThemeManager.currentTheme;
   115     for (let [pref, value] in Iterator(values)) {
   116       if (!this._isSynced(pref))
   117         continue;
   119       // Pref has gone missing, best we can do is reset it.
   120       if (value == null) {
   121         this._prefs.reset(pref);
   122         continue;
   123       }
   125       try {
   126         this._prefs.set(pref, value);
   127       } catch(ex) {
   128         this._log.trace("Failed to set pref: " + pref + ": " + ex);
   129       } 
   130     }
   132     // Notify the lightweight theme manager of all the new values
   133     let enabledNow = this._prefs.get(enabledPref, false);
   134     if (enabledBefore && !enabledNow) {
   135       LightweightThemeManager.currentTheme = null;
   136     } else if (enabledNow && LightweightThemeManager.usedThemes[0] != prevTheme) {
   137       LightweightThemeManager.currentTheme = null;
   138       LightweightThemeManager.currentTheme = LightweightThemeManager.usedThemes[0];
   139     }
   140   },
   142   getAllIDs: function PrefStore_getAllIDs() {
   143     /* We store all prefs in just one WBO, with just one GUID */
   144     let allprefs = {};
   145     allprefs[PREFS_GUID] = true;
   146     return allprefs;
   147   },
   149   changeItemID: function PrefStore_changeItemID(oldID, newID) {
   150     this._log.trace("PrefStore GUID is constant!");
   151   },
   153   itemExists: function FormStore_itemExists(id) {
   154     return (id === PREFS_GUID);
   155   },
   157   createRecord: function createRecord(id, collection) {
   158     let record = new PrefRec(collection, id);
   160     if (id == PREFS_GUID) {
   161       record.value = this._getAllPrefs();
   162     } else {
   163       record.deleted = true;
   164     }
   166     return record;
   167   },
   169   create: function PrefStore_create(record) {
   170     this._log.trace("Ignoring create request");
   171   },
   173   remove: function PrefStore_remove(record) {
   174     this._log.trace("Ignoring remove request");
   175   },
   177   update: function PrefStore_update(record) {
   178     // Silently ignore pref updates that are for other apps.
   179     if (record.id != PREFS_GUID)
   180       return;
   182     this._log.trace("Received pref updates, applying...");
   183     this._setAllPrefs(record.value);
   184   },
   186   wipe: function PrefStore_wipe() {
   187     this._log.trace("Ignoring wipe request");
   188   }
   189 };
   191 function PrefTracker(name, engine) {
   192   Tracker.call(this, name, engine);
   193   Svc.Obs.add("profile-before-change", this);
   194   Svc.Obs.add("weave:engine:start-tracking", this);
   195   Svc.Obs.add("weave:engine:stop-tracking", this);
   196 }
   197 PrefTracker.prototype = {
   198   __proto__: Tracker.prototype,
   200   get modified() {
   201     return Svc.Prefs.get("engine.prefs.modified", false);
   202   },
   203   set modified(value) {
   204     Svc.Prefs.set("engine.prefs.modified", value);
   205   },
   207   loadChangedIDs: function loadChangedIDs() {
   208     // Don't read changed IDs from disk at start up.
   209   },
   211   clearChangedIDs: function clearChangedIDs() {
   212     this.modified = false;
   213   },
   215  __prefs: null,
   216   get _prefs() {
   217     if (!this.__prefs) {
   218       this.__prefs = new Preferences();
   219     }
   220     return this.__prefs;
   221   },
   223   startTracking: function () {
   224     Services.prefs.addObserver("", this, false);
   225   },
   227   stopTracking: function () {
   228     this.__prefs = null;
   229     Services.prefs.removeObserver("", this);
   230   },
   232   observe: function (subject, topic, data) {
   233     Tracker.prototype.observe.call(this, subject, topic, data);
   235     switch (topic) {
   236       case "profile-before-change":
   237         this.stopTracking();
   238         break;
   239       case "nsPref:changed":
   240         // Trigger a sync for MULTI-DEVICE for a change that determines
   241         // which prefs are synced or a regular pref change.
   242         if (data.indexOf(WEAVE_SYNC_PREFS) == 0 ||
   243             this._prefs.get(WEAVE_SYNC_PREFS + data, false)) {
   244           this.score += SCORE_INCREMENT_XLARGE;
   245           this.modified = true;
   246           this._log.trace("Preference " + data + " changed");
   247         }
   248         break;
   249     }
   250   }
   251 };

mercurial