Bug 741862 - B2G 3G: Settings API hookup. r=philikon a=b2g-only
authorJose Antonio Olivera Ortega <josea.olivera@gmail.com>
Tue, 24 Apr 2012 17:46:42 -0300
changeset 92246 440371943508b3ab5c491f8eada57349cff5898f
parent 92245 c81818b53c379e901cf6c7a54e224cc11443533e
child 92247 55c5e6d0e9ecbb2533a196a42a672df2cfcfcde5
push id8624
push userpweitershausen@mozilla.com
push dateTue, 24 Apr 2012 20:46:57 +0000
treeherdermozilla-inbound@440371943508 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilikon, b2g-only
bugs741862
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 741862 - B2G 3G: Settings API hookup. r=philikon a=b2g-only
b2g/app/b2g.js
b2g/chrome/content/shell.js
dom/system/gonk/NetworkManager.js
dom/system/gonk/RadioInterfaceLayer.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -470,25 +470,16 @@ pref("b2g.keys.search.enabled", false);
 // Screen timeout in minutes
 pref("power.screen.timeout", 60);
 pref("dom.power.whitelist", "http://homescreen.gaiamobile.org,http://settings.gaiamobile.org");
 
 pref("full-screen-api.enabled", true);
 
 pref("media.volume.steps", 10);
 
-// Data connection settings. These will eventually live in the
-// navigator.settings API, or even in a database where we can look
-// it up automatically (bug 729440), but for this will have to do.
-pref("ril.data.enabled", false);
-pref("ril.data.roaming.enabled", false);
-pref("ril.data.apn", "");
-pref("ril.data.user", "");
-pref("ril.data.passwd", "");
-
 //Enable/disable marionette server, set listening port
 pref("marionette.defaultPrefs.enabled", true);
 pref("marionette.defaultPrefs.port", 2828);
 
 #ifdef MOZ_UPDATER
 pref("app.update.enabled", true);
 pref("app.update.auto", true);
 pref("app.update.silent", true);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -360,16 +360,64 @@ var shell = {
     if (e.settingName == "power.screen.timeout" && e.settingValue) {
       Services.idle.removeIdleObserver(idleHandler, idleTimeout);
       idleTimeout = e.settingValue;
       Services.idle.addIdleObserver(idleHandler, idleTimeout);
     }
   };
 })();
 
+const DATA_CALL_SETTING_BOLKEYS  = ["ril.data.enabled",
+                                    "ril.data.roaming.enabled"];
+const DATA_CALL_SETTING_CHARKEYS = ["ril.data.apn",
+                                    "ril.data.user",
+                                    "ril.data.passwd"];
+(function DataCallSettings() {
+  let sm = navigator.mozSettings;
+  let lock = sm.getLock();
+  DATA_CALL_SETTING_BOLKEYS.forEach(function(key) {
+    let request = lock.get(key);
+    request.onsuccess = function onSuccess() {
+      let value = request.result[key] || false;
+      Services.prefs.setBoolPref(key, value);
+      dump("DataCallSettings - " + key + ":" + value);
+    };
+    request.onerror = function onError() {
+      Services.prefs.setBoolPref(key, false);
+    };
+  });
+
+  DATA_CALL_SETTING_CHARKEYS.forEach(function(key) {
+    let request = lock.get(key);
+    request.onsuccess = function onSuccess() {
+      let value = request.result[key] || "";
+      Services.prefs.setCharPref(key, value);
+      dump("DataCallSettings - " + key + ":" + value);
+    };
+    request.onerror = function onError() {
+      Services.prefs.setCharPref(key, "");
+    };
+  });
+
+  navigator.mozSettings.onsettingchange = function onSettingChange(e) {
+    dump("DataCallSettings - onsettingchange: " + e.settingName +
+         ": " + e.settingValue);
+    if (e.settingValue) {
+      if (DATA_CALL_SETTING_BOLKEYS.indexOf(e.settingName) > -1 ) {
+        Services.prefs.setBoolPref(e.settingName, e.settingValue);
+        return;
+      }
+      if (DATA_CALL_SETTING_CHARKEYS.indexOf(e.settingName) > -1) {
+        Services.prefs.setCharPref(e.settingName, e.settingValue);
+      }
+    }
+  };
+
+})();
+
 function nsBrowserAccess() {
 }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]),
 
   openURI: function openURI(uri, opener, where, context) {
     // TODO This should be replaced by an 'open-browser-window' intent
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -168,17 +168,17 @@ NetworkManager.prototype = {
         continue;
       }
       this.active = network;
       if (network.type == this.preferredNetworkType) {
         debug("Found our preferred type of network: " + network.name);
         break;
       }
     }
-    if (oldActive != this.active) {
+    if (this.active && (oldActive != this.active)) {
       this.setDefaultRouteAndDNS();
     }
   },
 
   setDefaultRouteAndDNS: function setDefaultRouteAndDNS() {
     debug("Going to change route and DNS to " + this.active.name);
     if (this.active.dhcp) {
       this.worker.postMessage({cmd: "runDHCPAndSetDefaultRouteAndDNS",
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -55,16 +55,17 @@ const DATACALLINFO_CID =
   Components.ID("{ef474cd9-94f7-4c05-a31b-29b9de8a10d2}");
 
 const nsIAudioManager = Ci.nsIAudioManager;
 const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
 
 const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
 const kSmsReceivedObserverTopic          = "sms-received";
 const kSmsDeliveredObserverTopic         = "sms-delivered";
+const kMozSettingsChangedObserverTopic   = "mozsettings-changed";
 const DOM_SMS_DELIVERY_RECEIVED          = "received";
 const DOM_SMS_DELIVERY_SENT              = "sent";
 
 const RIL_IPC_MSG_NAMES = [
   "RIL:GetRadioState",
   "RIL:EnumerateCalls",
   "RIL:GetMicrophoneMuted",
   "RIL:SetMicrophoneMuted",
@@ -185,30 +186,32 @@ function RadioInterfaceLayer() {
                      type: null,
                      signalStrength: null,
                      relSignalStrength: null},
   };
   for each (let msgname in RIL_IPC_MSG_NAMES) {
     ppmm.addMessageListener(msgname, this);
   }
   Services.obs.addObserver(this, "xpcom-shutdown", false);
+  Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
 
   this._sentSmsEnvelopes = {};
   this.portAddressedSmsApps = {};
 }
 RadioInterfaceLayer.prototype = {
 
   classID:   RADIOINTERFACELAYER_CID,
   classInfo: XPCOMUtils.generateCI({classID: RADIOINTERFACELAYER_CID,
                                     classDescription: "RadioInterfaceLayer",
                                     interfaces: [Ci.nsIWorkerHolder,
                                                  Ci.nsIRadioInterfaceLayer]}),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder,
-                                         Ci.nsIRadioInterfaceLayer]),
+                                         Ci.nsIRadioInterfaceLayer,
+                                         Ci.nsIObserver]),
 
   /**
    * Process a message from the content process.
    */
   receiveMessage: function receiveMessage(msg) {
     debug("Received '" + msg.name + "' message from content process");
     switch (msg.name) {
       case "RIL:GetRadioState":
@@ -627,25 +630,54 @@ RadioInterfaceLayer.prototype = {
       datacalls.push(new DataCallInfo(datacall.state,
                                       datacall.cid,
                                       datacall.apn));
     }
     this._deliverDataCallCallback("receiveDataCallList",
                                   [datacalls, datacalls.length]);
   },
 
+  /**
+   * Handle setting changes.
+   */
+  handleMozSettingsChanged: function handleMozSettingsChanged(setting) {
+    // We only watch at "ril.data.enabled" flag changes for connecting or
+    // disconnecting the data call. If the value of "ril.data.enabled" is
+    // true and any of the remaining flags change the setting application
+    // should turn this flag to false and then to true in order to reload
+    // the new values and reconnect the data call.
+    if (setting.key != "ril.data.enabled") {
+      return;
+    }
+    if (!setting.value && RILNetworkInterface.connected) {
+      debug("Data call settings: disconnect data call.");
+      RILNetworkInterface.disconnect();
+    }
+    if (setting.value && !RILNetworkInterface.connected) {
+      debug("Data call settings connect data call.");
+      RILNetworkInterface.connect();
+    }
+  },
+
   // nsIObserver
 
   observe: function observe(subject, topic, data) {
-    if (topic == "xpcom-shutdown") {
-      for each (let msgname in RIL_IPC_MSG_NAMES) {
-        ppmm.removeMessageListener(msgname, this);
-      }
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-      ppmm = null;
+    switch (topic) {
+      case kMozSettingsChangedObserverTopic:
+        let setting = JSON.parse(data);
+        this.handleMozSettingsChanged(setting);
+        break;
+      case "xpcom-shutdown":
+        for each (let msgname in RIL_IPC_MSG_NAMES) {
+          ppmm.removeMessageListener(msgname, this);
+        }
+        ppmm = null;
+        Services.obs.removeObserver(this, "xpcom-shutdown");
+        Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
+        break;
     }
   },
 
   // nsIRadioWorker
 
   worker: null,
 
   // nsIRadioInterfaceLayer
@@ -1206,23 +1238,23 @@ let RILNetworkInterface = {
 
   name: null,
 
   dhcp: false,
 
   // nsIRILDataCallback
 
   dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) {
+    debug("Data call ID: " + cid + ", interface name: " + interfaceName);
     if (this.connecting &&
         (callState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
          callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
       this.connecting = false;
       this.cid = cid;
       this.name = interfaceName;
-      debug("Data call ID: " + cid + ", interface name: " + interfaceName);
       if (!this.registeredAsNetworkInterface) {
         let networkManager = Cc["@mozilla.org/network/manager;1"]
                                .getService(Ci.nsINetworkManager);
         networkManager.registerNetworkInterface(this);
         this.registeredAsNetworkInterface = true;
       }
     }
     if (this.cid != cid) {
@@ -1250,21 +1282,24 @@ let RILNetworkInterface = {
 
   get mRIL() {
     delete this.mRIL;
     return this.mRIL = Cc["@mozilla.org/telephony/system-worker-manager;1"]
                          .getService(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIRadioInterfaceLayer);
   },
 
+  get connected() {
+    return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
+  },
+
   connect: function connect() {
     if (this.connecting ||
         this.state == RIL.GECKO_NETWORK_STATE_CONNECTED ||
-        this.state == RIL.GECKO_NETWORK_STATE_SUSPENDED ||
-        this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTING) {
+        this.state == RIL.GECKO_NETWORK_STATE_SUSPENDED) {
       return;
     }
     if (!this.registeredAsDataCallCallback) {
       this.mRIL.registerDataCallCallback(this);
       this.registeredAsDataCallCallback = true;
     }
 
     let apn, user, passwd;
@@ -1281,17 +1316,23 @@ let RILNetworkInterface = {
     debug("Going to set up data connection with APN " + apn);
     this.mRIL.setupDataCall(RIL.DATACALL_RADIOTECHNOLOGY_GSM,
                             apn, user, passwd,
                             RIL.DATACALL_AUTH_PAP_OR_CHAP, "IP");
     this.connecting = true;
   },
 
   disconnect: function disconnect() {
-    this.mRIL.deactivateDataCall(this.cid);
+    if (this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTING ||
+        this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
+      return;
+    }
+    let reason = RIL.DATACALL_DEACTIVATE_NO_REASON;
+    debug("Going to disconnet data connection " + this.cid);
+    this.mRIL.deactivateDataCall(this.cid, reason);
   },
 
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([RadioInterfaceLayer]);
 
 let debug;
 if (DEBUG) {