Bug 948743 - Query interface stat directly. r=vchang, r=acperez, a=1.3+
authorChuck Lee <chulee@mozilla.com>
Thu, 16 Jan 2014 09:57:26 +0800
changeset 169319 ac12618cf462b8ed36fc354c72e0742c2a6488e0
parent 169318 f4bc0d1cae6ffd2290bbb8638d4b6943fb8c0e88
child 169320 b3401fde9ff00ae5ed57c07ea1d6a331584c61ce
push id4971
push userryanvm@gmail.com
push dateThu, 16 Jan 2014 21:31:22 +0000
treeherdermozilla-aurora@af30f8d0d27f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvchang, acperez, 1.3
bugs948743
milestone28.0a2
Bug 948743 - Query interface stat directly. r=vchang, r=acperez, a=1.3+
dom/system/gonk/NetworkService.js
dom/system/gonk/net_worker.js
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -3,16 +3,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "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");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
 
 const NETWORKSERVICE_CONTRACTID = "@mozilla.org/network/service;1";
 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;
@@ -47,17 +49,17 @@ function debug(msg) {
  * This component watches for network interfaces changing state and then
  * adjusts routes etc. accordingly.
  */
 function NetworkService() {
   if(DEBUG) debug("Starting net_worker.");
   this.worker = new ChromeWorker("resource://gre/modules/net_worker.js");
   this.worker.onmessage = this.handleWorkerMessage.bind(this);
   this.worker.onerror = function onerror(event) {
-    if(DEBUG) debug("Received error from worker: " + event.filename + 
+    if(DEBUG) debug("Received error from worker: " + event.filename +
                     ":" + event.lineno + ": " + event.message + "\n");
     // Prevent the event from bubbling any further.
     event.preventDefault();
   };
 
   // Callbacks to invoke when a reply arrives from the net_worker.
   this.controlCallbacks = Object.create(null);
 }
@@ -102,28 +104,47 @@ NetworkService.prototype = {
       delete this.controlCallbacks[id];
     }
   },
 
   // nsINetworkService
 
   getNetworkInterfaceStats: function getNetworkInterfaceStats(networkName, callback) {
     if(DEBUG) debug("getNetworkInterfaceStats for " + networkName);
+    let file = new FileUtils.File("/proc/net/dev");
 
-    let params = {
-      cmd: "getNetworkInterfaceStats",
-      ifname: networkName
-    };
+    if (!file) {
+      callback.networkStatsAvailable(false, -1, -1, new Date());
+      return;
+    }
+
+    NetUtil.asyncFetch(file, function(inputStream, status) {
+      let result = {
+        success: true,  // netd always return success even interface doesn't exist.
+        rxBytes: 0,
+        txBytes: 0
+      };
+      result.date = new Date();
 
-    params.report = true;
-    params.isAsync = true;
+      if (Components.isSuccessCode(status)) {
+        // Find record for corresponding interface.
+        let statExpr = / +(\S+): +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+/;
+        let data = NetUtil.readInputStreamToString(inputStream,
+                    inputStream.available()).split("\n");
+        for (let i = 2; i < data.length; i++) {
+          let parseResult = statExpr.exec(data[i]);
+          if (parseResult && parseResult[1] === networkName) {
+            result.rxBytes = parseInt(parseResult[2], 10);
+            result.txBytes = parseInt(parseResult[3], 10);
+            break;
+          }
+        }
+      }
 
-    this.controlMessage(params, function(result) {
-      let success = !isError(result.resultCode);
-      callback.networkStatsAvailable(success, result.rxBytes,
+      callback.networkStatsAvailable(result.success, result.rxBytes,
                                      result.txBytes, result.date);
     });
   },
 
   setNetworkInterfaceAlarm: function setNetworkInterfaceAlarm(networkName, threshold, callback) {
     if (!networkName) {
       callback.networkUsageAlarmResult(-1);
       return;
--- a/dom/system/gonk/net_worker.js
+++ b/dom/system/gonk/net_worker.js
@@ -137,29 +137,16 @@ function usbTetheringFail(params) {
 }
 
 function usbTetheringSuccess(params) {
   // Notify the main thread.
   postMessage(params);
   return true;
 }
 
-function networkInterfaceStatsFail(params) {
-  // 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.
@@ -602,28 +589,16 @@ function startSoftAP(params, callback) {
   return doCommand(command, callback);
 }
 
 function stopSoftAP(params, callback) {
   let command = "softap stopap";
   return doCommand(command, callback);
 }
 
-function getRxBytes(params, callback) {
-  let command = "interface readrxcounter " + params.ifname;
-  return doCommand(command, 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);
@@ -928,34 +903,16 @@ function setUSBTethering(params) {
     // Disable USB tetehring.
     debug("Stopping USB Tethering on " +
            params.internalIfname + "<->" + params.externalIfname);
     chain(params, gUSBDisableChain, usbTetheringFail);
   }
   return true;
 }
 
-let gNetworkInterfaceStatsChain = [getRxBytes,
-                                   getTxBytes,
-                                   networkInterfaceStatsSuccess];
-
-/**
- * handling main thread's get network interface stats request
- */
-function getNetworkInterfaceStats(params) {
-  debug("getNetworkInterfaceStats: " + params.ifname);
-
-  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);