mobile/android/modules/SharedPreferences.jsm

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 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 "use strict";
     8 this.EXPORTED_SYMBOLS = ["SharedPreferences"];
    10 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
    12 // For adding observers.
    13 Cu.import("resource://gre/modules/Services.jsm");
    14 Cu.import("resource://gre/modules/Messaging.jsm");
    16 /**
    17  * Create an interface to an Android SharedPreferences branch.
    18  *
    19  * branch {String} should be a string describing a preferences branch,
    20  * like "UpdateService" or "background.data", or null to access the
    21  * default preferences branch for the application.
    22  */
    23 function SharedPreferences(branch) {
    24   if (!(this instanceof SharedPreferences)) {
    25     return new SharedPreferences(branch);
    26   }
    27   this._branch = branch || null;
    28   this._observers = {};
    29 };
    31 SharedPreferences.prototype = Object.freeze({
    32   _set: function _set(prefs) {
    33     sendMessageToJava({
    34       type: "SharedPreferences:Set",
    35       preferences: prefs,
    36       branch: this._branch,
    37     });
    38   },
    40   _setOne: function _setOne(prefName, value, type) {
    41     let prefs = [];
    42     prefs.push({
    43       name: prefName,
    44       value: value,
    45       type: type,
    46     });
    47     this._set(prefs);
    48   },
    50   setBoolPref: function setBoolPref(prefName, value) {
    51     this._setOne(prefName, value, "bool");
    52   },
    54   setCharPref: function setCharPref(prefName, value) {
    55     this._setOne(prefName, value, "string");
    56   },
    58   setIntPref: function setIntPref(prefName, value) {
    59     this._setOne(prefName, value, "int");
    60   },
    62   _get: function _get(prefs, callback) {
    63     let result = null;
    64     sendMessageToJava({
    65       type: "SharedPreferences:Get",
    66       preferences: prefs,
    67       branch: this._branch,
    68     }, (data) => {
    69       result = data.values;
    70     });
    72     let thread = Services.tm.currentThread;
    73     while (result == null)
    74       thread.processNextEvent(true);
    76     return result;
    77   },
    79   _getOne: function _getOne(prefName, type) {
    80     let prefs = [];
    81     prefs.push({
    82       name: prefName,
    83       type: type,
    84     });
    85     let values = this._get(prefs);
    86     if (values.length != 1) {
    87       throw new Error("Got too many values: " + values.length);
    88     }
    89     return values[0].value;
    90   },
    92   getBoolPref: function getBoolPref(prefName) {
    93     return this._getOne(prefName, "bool");
    94   },
    96   getCharPref: function getCharPref(prefName) {
    97     return this._getOne(prefName, "string");
    98   },
   100   getIntPref: function getIntPref(prefName) {
   101     return this._getOne(prefName, "int");
   102   },
   104   /**
   105    * Invoke `observer` after a change to the preference `domain` in
   106    * the current branch.
   107    *
   108    * `observer` should implement the nsIObserver.observe interface.
   109    */
   110   addObserver: function addObserver(domain, observer, holdWeak) {
   111     if (!domain)
   112       throw new Error("domain must not be null");
   113     if (!observer)
   114       throw new Error("observer must not be null");
   115     if (holdWeak)
   116       throw new Error("Weak references not yet implemented.");
   118     if (!this._observers.hasOwnProperty(domain))
   119       this._observers[domain] = [];
   120     if (this._observers[domain].indexOf(observer) > -1)
   121       return;
   123     this._observers[domain].push(observer);
   125     this._updateAndroidListener();
   126   },
   128   /**
   129    * Do not invoke `observer` after a change to the preference
   130    * `domain` in the current branch.
   131    */
   132   removeObserver: function removeObserver(domain, observer) {
   133     if (!this._observers.hasOwnProperty(domain))
   134       return;
   135     let index = this._observers[domain].indexOf(observer);
   136     if (index < 0)
   137       return;
   139     this._observers[domain].splice(index, 1);
   140     if (this._observers[domain].length < 1)
   141       delete this._observers[domain];
   143     this._updateAndroidListener();
   144   },
   146   _updateAndroidListener: function _updateAndroidListener() {
   147     if (this._listening && Object.keys(this._observers).length < 1)
   148       this._uninstallAndroidListener();
   149     if (!this._listening && Object.keys(this._observers).length > 0)
   150       this._installAndroidListener();
   151   },
   153   _installAndroidListener: function _installAndroidListener() {
   154     if (this._listening)
   155       return;
   156     this._listening = true;
   158     Services.obs.addObserver(this, "SharedPreferences:Changed", false);
   159     sendMessageToJava({
   160       type: "SharedPreferences:Observe",
   161       enable: true,
   162       branch: this._branch,
   163     });
   164   },
   166   observe: function observe(subject, topic, data) {
   167     if (topic != "SharedPreferences:Changed") {
   168       return;
   169     }
   171     let msg = JSON.parse(data);
   172     if (msg.branch != this._branch) {
   173       return;
   174     }
   176     if (!this._observers.hasOwnProperty(msg.key)) {
   177       return;
   178     }
   180     let observers = this._observers[msg.key];
   181     for (let obs of observers) {
   182       obs.observe(obs, msg.key, msg.value);
   183     }
   184   },
   186   _uninstallAndroidListener: function _uninstallAndroidListener() {
   187     if (!this._listening)
   188       return;
   189     this._listening = false;
   191     Services.obs.removeObserver(this, "SharedPreferences:Changed");
   192     sendMessageToJava({
   193       type: "SharedPreferences:Observe",
   194       enable: false,
   195       branch: this._branch,
   196     });
   197   },
   198 });

mercurial