Bug 858005 - Part 2: Netd integration. r=vchang
authorAlbert Crespell <acperez@tid.es>
Fri, 24 May 2013 11:28:20 +0200
changeset 159203 97b690fd7806dfdb0c0ac9e8c0469d1b77e7018a
parent 159202 2052ba4c936cdf1fe892894810468db216271164
child 159204 7cbdd95bf3715f83482c2f1fdaa5bf01aac67adf
push idunknown
push userunknown
push dateunknown
reviewersvchang
bugs858005
milestone28.0a1
Bug 858005 - Part 2: Netd integration. r=vchang
dom/system/gonk/NetworkService.js
dom/system/gonk/NetworkService.manifest
dom/system/gonk/net_worker.js
dom/system/gonk/nsINetworkService.idl
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -5,17 +5,17 @@
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const NETWORKSERVICE_CONTRACTID = "@mozilla.org/network/service;1";
-const NETWORKSERVICE_CID = Components.ID("{a6c58260-46df-11e3-8f96-0800200c9a66}");
+const NETWORKSERVICE_CID = Components.ID("{c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c}");
 
 // 1xx - Requested action is proceeding
 const NETD_COMMAND_PROCEEDING   = 100;
 // 2xx - Requested action has been successfully completed
 const NETD_COMMAND_OKAY         = 200;
 // 4xx - The command is accepted but the requested action didn't
 // take place.
 const NETD_COMMAND_FAIL         = 400;
@@ -112,23 +112,99 @@ NetworkService.prototype = {
       cmd: "getNetworkInterfaceStats",
       ifname: networkName
     };
 
     params.report = true;
     params.isAsync = true;
 
     this.controlMessage(params, function(result) {
-      let success = result.resultCode >= NETD_COMMAND_OKAY &&
-                    result.resultCode < NETD_COMMAND_ERROR;
+      let success = !isError(result.resultCode);
       callback.networkStatsAvailable(success, result.rxBytes,
                                      result.txBytes, result.date);
     });
   },
 
+  setNetworkInterfaceAlarm: function setNetworkInterfaceAlarm(networkName, threshold, callback) {
+    if (!networkName) {
+      callback.networkUsageAlarmResult(-1);
+      return;
+    }
+
+    if (threshold < 0) {
+      this._disableNetworkInterfaceAlarm(networkName, callback);
+      return;
+    }
+
+    this._setNetworkInterfaceAlarm(networkName, threshold, callback);
+  },
+
+  _setNetworkInterfaceAlarm: function _setNetworkInterfaceAlarm(networkName, threshold, callback) {
+    debug("setNetworkInterfaceAlarm for " + networkName + " at " + threshold + "bytes");
+
+    let params = {
+      cmd: "setNetworkInterfaceAlarm",
+      ifname: networkName,
+      threshold: threshold
+    };
+
+    params.report = true;
+    params.isAsync = true;
+
+    this.controlMessage(params, function(result) {
+      if (!isError(result.resultCode)) {
+        callback.networkUsageAlarmResult(null);
+        return;
+      }
+
+      this._enableNetworkInterfaceAlarm(networkName, threshold, callback);
+    });
+  },
+
+  _enableNetworkInterfaceAlarm: function _enableNetworkInterfaceAlarm(networkName, threshold, callback) {
+    debug("enableNetworkInterfaceAlarm for " + networkName + " at " + threshold + "bytes");
+
+    let params = {
+      cmd: "enableNetworkInterfaceAlarm",
+      ifname: networkName,
+      threshold: threshold
+    };
+
+    params.report = true;
+    params.isAsync = true;
+
+    this.controlMessage(params, function(result) {
+      if (!isError(result.resultCode)) {
+        callback.networkUsageAlarmResult(null);
+        return;
+      }
+      callback.networkUsageAlarmResult(result.reason);
+    });
+  },
+
+  _disableNetworkInterfaceAlarm: function _disableNetworkInterfaceAlarm(networkName, callback) {
+    debug("disableNetworkInterfaceAlarm for " + networkName);
+
+    let params = {
+      cmd: "disableNetworkInterfaceAlarm",
+      ifname: networkName,
+    };
+
+    params.report = true;
+    params.isAsync = true;
+
+    this.controlMessage(params, function(result) {
+      if (!isError(result.resultCode)) {
+        callback.networkUsageAlarmResult(null);
+        return;
+      }
+      callback.networkUsageAlarmResult(result.reason);
+    });
+  },
+
   setWifiOperationMode: function setWifiOperationMode(interfaceName, mode, callback) {
     if(DEBUG) debug("setWifiOperationMode on " + interfaceName + " to " + mode);
 
     let params = {
       cmd: "setWifiOperationMode",
       ifname: interfaceName,
       mode: mode
     };
--- a/dom/system/gonk/NetworkService.manifest
+++ b/dom/system/gonk/NetworkService.manifest
@@ -1,3 +1,3 @@
 # NetworkService.js
-component {a6c58260-46df-11e3-8f96-0800200c9a66} NetworkService.js
-contract @mozilla.org/network/service;1 {a6c58260-46df-11e3-8f96-0800200c9a66}
+component {c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c} NetworkService.js
+contract @mozilla.org/network/service;1 {c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c}
--- a/dom/system/gonk/net_worker.js
+++ b/dom/system/gonk/net_worker.js
@@ -146,17 +146,29 @@ function networkInterfaceStatsFail(param
   // Notify the main thread.
   postMessage(params);
   return true;
 }
 
 function networkInterfaceStatsSuccess(params) {
   // Notify the main thread.
   params.txBytes = parseFloat(params.resultReason);
+  postMessage(params);
+  return true;
+}
 
+function networkInterfaceAlarmFail(params) {
+  // Notify the main thread.
+  postMessage(params);
+  return true;
+}
+
+function networkInterfaceAlarmSuccess(params) {
+  // Notify the main thread.
+  params.error = parseFloat(params.resultReason);
   postMessage(params);
   return true;
 }
 
 function updateUpStreamSuccess(params) {
   // Notify the main thread.
   postMessage(params);
   return true;
@@ -602,16 +614,41 @@ function getRxBytes(params, callback) {
 
 function getTxBytes(params, callback) {
   params.rxBytes = parseFloat(params.resultReason);
 
   let command = "interface readtxcounter " + params.ifname;
   return doCommand(command, callback);
 }
 
+function enableAlarm(params, callback) {
+  let command = "bandwidth enable";
+  return doCommand(command, callback);
+}
+
+function disableAlarm(params, callback) {
+  let command = "bandwidth disable";
+  return doCommand(command, callback);
+}
+
+function setQuota(params, callback) {
+  let command = "bandwidth setiquota " + params.ifname + " " + parseInt('0xffffffffffffffff');
+  return doCommand(command, callback);
+}
+
+function removeQuota(params, callback) {
+  let command = "bandwidth removeiquota " + params.ifname;
+  return doCommand(command, callback);
+}
+
+function setAlarm(params, callback) {
+  let command = "bandwidth setinterfacealert " + params.ifname + " " + params.threshold;
+  return doCommand(command, callback);
+}
+
 function escapeQuote(str) {
   str = str.replace(/\\/g, "\\\\");
   return str.replace(/"/g, "\\\"");
 }
 
 /**
  * Command format for sdk version < 16
  *   Arguments:
@@ -909,16 +946,49 @@ function getNetworkInterfaceStats(params
   params.rxBytes = -1;
   params.txBytes = -1;
   params.date = new Date();
 
   chain(params, gNetworkInterfaceStatsChain, networkInterfaceStatsFail);
   return true;
 }
 
+let gNetworkInterfaceEnableAlarmChain = [enableAlarm,
+                                         setQuota,
+                                         setAlarm,
+                                         networkInterfaceAlarmSuccess];
+
+function enableNetworkInterfaceAlarm(params) {
+  debug("enableNetworkInterfaceAlarms: " + params.ifname);
+
+  chain(params, gNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail);
+  return true;
+}
+
+let gNetworkInterfaceDisableAlarmChain = [removeQuota,
+                                          disableAlarm,
+                                          networkInterfaceAlarmSuccess];
+
+function disableNetworkInterfaceAlarm(params) {
+  debug("disableNetworkInterfaceAlarms: " + params.ifname);
+
+  chain(params, gNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail);
+  return true;
+}
+
+let gNetworkInterfaceSetAlarmChain = [setAlarm,
+                                      networkInterfaceAlarmSuccess];
+
+function setNetworkInterfaceAlarm(params) {
+  debug("setNetworkInterfaceAlarms: " + params.ifname);
+
+  chain(params, gNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail);
+  return true;
+}
+
 let gWifiOperationModeChain = [wifiFirmwareReload,
                                wifiOperationModeSuccess];
 
 /**
  * handling main thread's reload Wifi firmware request
  */
 function setWifiOperationMode(params) {
   debug("setWifiOperationMode: " + params.ifname + " " + params.mode);
--- a/dom/system/gonk/nsINetworkService.idl
+++ b/dom/system/gonk/nsINetworkService.idl
@@ -23,16 +23,22 @@ interface nsIWifiTetheringCallback : nsI
 interface nsINetworkStatsCallback : nsISupports
 {
   void networkStatsAvailable(in boolean success,
                              in unsigned long rxBytes,
                              in unsigned long txBytes,
                              in jsval date);
 };
 
+[scriptable, function, uuid(0706bfa2-ac2d-11e2-9a8d-7b6d988d4767)]
+interface nsINetworkUsageAlarmCallback : nsISupports
+{
+  void networkUsageAlarmResult(in jsval error);
+};
+
 [scriptable, function, uuid(9ede8720-f8bc-11e2-b778-0800200c9a66)]
 interface nsIWifiOperationModeCallback : nsISupports
 {
   /**
    * Callback function used to report result to WifiManager.
    *
    * @param error
    *        An error message if the operation wasn't successful,
@@ -93,17 +99,17 @@ interface nsIUpdateUpStreamCallback : ns
    *        The external interface name.
    */
   void updateUpStreamResult(in boolean success, in DOMString externalIfname);
 };
 
 /**
  * Provide network services.
  */
-[scriptable, uuid(a6c58260-46df-11e3-8f96-0800200c9a66)]
+[scriptable, uuid(c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c)]
 interface nsINetworkService : nsISupports
 {
   /**
    * Enable or disable Wifi Tethering
    *
    * @param enabled
    *        Boolean that indicates whether tethering should be enabled (true) or disabled (false).
    * @param config
@@ -147,16 +153,34 @@ interface nsINetworkService : nsISupport
    *
    * @param callback
    *        Callback to notify result and provide stats, connectionType
    *        and the date when stats are retrieved
    */
   void getNetworkInterfaceStats(in DOMString networkName, in nsINetworkStatsCallback callback);
 
   /**
+   * Set Alarm of usage per interface
+   *
+   * @param networkName
+   *        Select the Network interface to set an alarm.
+   *
+   * @param threshold
+   *        Amount of data that will trigger the alarm.
+   *
+   * @param callback
+   *        Callback to notify the result.
+   *
+   * @return false if there is no interface registered for the networkType param.
+   */
+  boolean setNetworkInterfaceAlarm(in DOMString networkName,
+                                   in long threshold,
+                                   in nsINetworkUsageAlarmCallback callback);
+
+  /**
    * Reload Wifi firmware to specific operation mode.
    *
    * @param interfaceName
    *        Wifi Network interface name.
    *
    * @param mode
    *        AP  - Access pointer mode.
    *        P2P - Peer to peer connection mode.