NetworkManagementService: Add interface counters & throttle API

Change-Id: I4976549cdbb027ba7859335e69bf866e738961c9
Signed-off-by: San Mehat <san@google.com>
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index e970e7e..da8c5d2 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -179,4 +179,36 @@
      * Set Access Point config
      */
     void setAccessPoint(in WifiConfiguration wifiConfig, String wlanIface, String softapIface);
+
+    /**
+     * Read number of bytes sent over an interface
+     */
+    long getInterfaceTxCounter(String iface);
+
+    /**
+     * Read number of bytes received over an interface
+     */
+    long getInterfaceRxCounter(String iface);
+
+    /**
+     * Configures RX bandwidth throttling on an interface
+     */
+    void setInterfaceRxThrottle(String iface, int kbps);
+
+    /**
+     * Configures TX bandwidth throttling on an interface
+     */
+    void setInterfaceTxThrottle(String iface, int kbps);
+
+    /**
+     * Returns the currently configured RX throttle values
+     * for the specified interface
+     */
+    int getInterfaceRxThrottle(String iface);
+
+    /**
+     * Returns the currently configured TX throttle values
+     * for the specified interface
+     */
+    int getInterfaceTxThrottle(String iface);
 }
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 072fc1b..b7f6175 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -65,6 +65,10 @@
         public static final int InterfaceGetCfgResult     = 213;
         public static final int SoftapStatusResult        = 214;
         public static final int UsbRNDISStatusResult      = 215;
+        public static final int InterfaceRxCounterResult  = 216;
+        public static final int InterfaceTxCounterResult  = 217;
+        public static final int InterfaceRxThrottleResult = 218;
+        public static final int InterfaceTxThrottleResult = 219;
 
         public static final int InterfaceChange           = 600;
     }
@@ -524,4 +528,89 @@
             mConnector.doCommand(str);
         }
     }
+
+    private long getInterfaceCounter(String iface, boolean rx) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
+        try {
+            String rsp = mConnector.doCommand(
+                    String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
+            String []tok = rsp.split(" ");
+            int code;
+            try {
+                code = Integer.parseInt(tok[0]);
+            } catch (NumberFormatException nfe) {
+                Slog.e(TAG, String.format("Error parsing code %s", tok[0]));
+                return -1;
+            }
+            if ((rx && code != NetdResponseCode.InterfaceRxCounterResult) || (
+                    !rx && code != NetdResponseCode.InterfaceTxCounterResult)) {
+                Slog.e(TAG, String.format("Unexpected response code %d", code));
+                return -1;
+            }
+            return Long.parseLong(tok[1]);
+        } catch (Exception e) {
+            Slog.e(TAG, String.format(
+                    "Failed to read interface %s counters", (rx ? "rx" : "tx")), e);
+        }
+        return -1;
+    }
+
+    public long getInterfaceRxCounter(String iface) {
+        return getInterfaceCounter(iface, true);
+    }
+
+    public long getInterfaceTxCounter(String iface) {
+        return getInterfaceCounter(iface, false);
+    }
+
+    private void setInterfaceThrottle(String iface, boolean rx, int kbps) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        mConnector.doCommand(String.format(
+                "interface setthrottle %s %s %d", iface, (rx ? "rx" : "tx"), kbps));
+    }
+
+    public void setInterfaceRxThrottle(String iface, int kbps) {
+        setInterfaceThrottle(iface, true, kbps);
+    }
+
+    public void setInterfaceTxThrottle(String iface, int kbps) {
+        setInterfaceThrottle(iface, false, kbps);
+    }
+
+    private int getInterfaceThrottle(String iface, boolean rx) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
+        try {
+            String rsp = mConnector.doCommand(
+                    String.format("interface getthrottle %s %s", iface,(rx ? "rx" : "tx"))).get(0);
+            String []tok = rsp.split(" ");
+            int code;
+            try {
+                code = Integer.parseInt(tok[0]);
+            } catch (NumberFormatException nfe) {
+                Slog.e(TAG, String.format("Error parsing code %s", tok[0]));
+                return -1;
+            }
+            if ((rx && code != NetdResponseCode.InterfaceRxThrottleResult) || (
+                    !rx && code != NetdResponseCode.InterfaceTxThrottleResult)) {
+                Slog.e(TAG, String.format("Unexpected response code %d", code));
+                return -1;
+            }
+            return Integer.parseInt(tok[1]);
+        } catch (Exception e) {
+            Slog.e(TAG, String.format(
+                    "Failed to read interface %s throttle value", (rx ? "rx" : "tx")), e);
+        }
+        return -1;
+    }
+
+    public int getInterfaceRxThrottle(String iface) {
+        return getInterfaceThrottle(iface, true);
+    }
+
+    public int getInterfaceTxThrottle(String iface) {
+        return getInterfaceThrottle(iface, false);
+    }
 }