Search code examples
androidfirefox-addonfirefox-addon-sdkxpcom

nsIPrefBranch for Firefox for android extension returns NS_ERROR_UNEXPECTED


I want to store a value in the preference of my extension (a firefox for android ext). So, in the prefs.js file (under defaults/preferences/) I write:

pref("extensions.trackdetect.idUser","nothing");

Then, in boostrap.js I get the preference branch:

var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                .getService(Components.interfaces.nsIPrefService).getBranch("extensions.trackdetect.");

But, when I try to get idUser value like this:

var idPref = prefs.getCharPref("idUser");

I get this error:`

Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPrefBranch.getCharPref]"  nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"

This post explains the error origins, but my preference as I showed bellow is set, so I don't understand the problem.


Solution

  • Bootstrapped (restartless) add-ons do not support auto-prefs via defaults/preferences. It is the responsibility of your bootstrap code to set up default preferences accordingly.

    Since your auto-prefs were never loaded, the getCharPref() call has to fail.

    You will need to get the default branch and seed your preferences. An easy way to do so would be:

    const PREF_BRANCH = "extensions.myaddon.";
    const PREFS = {
      someIntPref: 1,
      someStringPref: "some text value"
    };
    
    function setDefaultPrefs() {
      let branch = Services.prefs.getDefaultBranch(PREF_BRANCH);
      for (let [key, val] in Iterator(PREFS)) {
        switch (typeof val) {
          case "boolean":
            branch.setBoolPref(key, val);
            break;
          case "number":
            branch.setIntPref(key, val);
            break;
          case "string":
            branch.setCharPref(key, val);
            break;
        }
      }
    }
    
    function startup(aData, aReason) {
      // Always set the default prefs as they disappear on restart
      setDefaultPrefs();
      ...
    }
    

    There are alternatives, like using mozISubscriptLoader or Sandboxes, but I don't really have stand-alone code that can be easily copied for that.