bandwidth-related commands porting

Test: built, flashed, booted
      system/netd/tests/runtests.sh passes

Change-Id: I7db81136dfaa581d4257a05aad64059dc0cd7976
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index 5b08819..a2e63c0 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -332,26 +332,46 @@
     return ret;
 }
 
+// TODO: Remove after removing these commands in CommandListener
 int BandwidthController::addNaughtyApps(int numUids, const char* const appUids[]) {
     return manipulateSpecialApps(toStrVec(numUids, appUids), NAUGHTY_CHAIN,
                                  IptJumpReject, IptOpInsert);
 }
 
+// TODO: Remove after removing these commands in CommandListener
 int BandwidthController::removeNaughtyApps(int numUids, const char* const appUids[]) {
     return manipulateSpecialApps(toStrVec(numUids, appUids), NAUGHTY_CHAIN,
                                  IptJumpReject, IptOpDelete);
 }
 
+// TODO: Remove after removing these commands in CommandListener
 int BandwidthController::addNiceApps(int numUids, const char* const appUids[]) {
     return manipulateSpecialApps(toStrVec(numUids, appUids), NICE_CHAIN,
                                  IptJumpReturn, IptOpInsert);
 }
 
+// TODO: Remove after removing these commands in CommandListener
 int BandwidthController::removeNiceApps(int numUids, const char* const appUids[]) {
     return manipulateSpecialApps(toStrVec(numUids, appUids), NICE_CHAIN,
                                  IptJumpReturn, IptOpDelete);
 }
 
+int BandwidthController::addNaughtyApps(const std::vector<std::string>& appStrUid) {
+    return manipulateSpecialApps(appStrUid, NAUGHTY_CHAIN, IptJumpReject, IptOpInsert);
+}
+
+int BandwidthController::removeNaughtyApps(const std::vector<std::string>& appStrUid) {
+    return manipulateSpecialApps(appStrUid, NAUGHTY_CHAIN, IptJumpReject, IptOpDelete);
+}
+
+int BandwidthController::addNiceApps(const std::vector<std::string>& appStrUid) {
+    return manipulateSpecialApps(appStrUid, NICE_CHAIN, IptJumpReturn, IptOpInsert);
+}
+
+int BandwidthController::removeNiceApps(const std::vector<std::string>& appStrUid) {
+    return manipulateSpecialApps(appStrUid, NICE_CHAIN, IptJumpReturn, IptOpDelete);
+}
+
 int BandwidthController::manipulateSpecialApps(const std::vector<std::string>& appStrUids,
                                                const std::string& chain, IptJumpOp jumpHandling,
                                                IptOp op) {
@@ -482,13 +502,11 @@
 int BandwidthController::setInterfaceQuota(const std::string& iface, int64_t maxBytes) {
     const std::string& cost = iface;
 
-    if (!isIfaceName(iface))
-        return -1;
+    if (!isIfaceName(iface)) return -EINVAL;
 
     if (!maxBytes) {
-        /* Don't talk about -1, deprecate it. */
         ALOGE("Invalid bytes value. 1..max_int64.");
-        return -1;
+        return -ERANGE;
     }
     if (maxBytes == -1) {
         return removeInterfaceQuota(iface);
@@ -498,10 +516,10 @@
     auto it = mQuotaIfaces.find(iface);
 
     if (it != mQuotaIfaces.end()) {
-        if (updateQuota(cost, maxBytes) != 0) {
+        if (int res = updateQuota(cost, maxBytes)) {
             ALOGE("Failed update quota for %s", iface.c_str());
             removeInterfaceQuota(iface);
-            return -1;
+            return res;
         }
         it->second.quota = maxBytes;
         return 0;
@@ -523,11 +541,10 @@
                      chain.c_str(), maxBytes, cost.c_str()),
         "COMMIT\n",
     };
-
     if (iptablesRestoreFunction(V4V6, Join(cmds, "\n"), nullptr) != 0) {
         ALOGE("Failed set quota rule");
         removeInterfaceQuota(iface);
-        return -1;
+        return -EREMOTEIO;
     }
 
     mQuotaIfaces[iface] = QuotaInfo{maxBytes, 0};
@@ -559,14 +576,13 @@
 }
 
 int BandwidthController::removeInterfaceQuota(const std::string& iface) {
-    if (!isIfaceName(iface))
-        return -1;
+    if (!isIfaceName(iface)) return -EINVAL;
 
     auto it = mQuotaIfaces.find(iface);
 
     if (it == mQuotaIfaces.end()) {
         ALOGE("No such iface %s to delete", iface.c_str());
-        return -1;
+        return -ENODEV;
     }
 
     const std::string chain = "bw_costly_" + iface;
@@ -587,7 +603,7 @@
         mQuotaIfaces.erase(it);
     }
 
-    return res;
+    return res ? -EREMOTEIO : 0;
 }
 
 int BandwidthController::updateQuota(const std::string& quotaName, int64_t bytes) {
@@ -596,13 +612,14 @@
 
     if (!isIfaceName(quotaName)) {
         ALOGE("updateQuota: Invalid quotaName \"%s\"", quotaName.c_str());
-        return -1;
+        return -EINVAL;
     }
 
     StatusOr<UniqueFile> file = sys.fopen(fname, "we");
     if (!isOk(file)) {
+        int res = errno;
         ALOGE("Updating quota %s failed (%s)", quotaName.c_str(), toString(file).c_str());
-        return -1;
+        return -res;
     }
     sys.fprintf(file.value().get(), "%" PRId64 "\n", bytes);
     return 0;
@@ -641,7 +658,7 @@
 
     if (!bytes) {
         ALOGE("Invalid bytes value. 1..max_int64.");
-        return -1;
+        return -ERANGE;
     }
     if (mGlobalAlertBytes) {
         res = updateQuota(alertName, bytes);
@@ -651,6 +668,9 @@
             ALOGV("setGlobalAlert for %d tether", mGlobalAlertTetherCount);
             res |= runIptablesAlertFwdCmd(IptOpInsert, alertName, bytes);
         }
+        if (res) {
+            res = -EREMOTEIO;
+        }
     }
     mGlobalAlertBytes = bytes;
     return res;
@@ -737,18 +757,18 @@
 int BandwidthController::setInterfaceAlert(const std::string& iface, int64_t bytes) {
     if (!isIfaceName(iface)) {
         ALOGE("setInterfaceAlert: Invalid iface \"%s\"", iface.c_str());
-        return -1;
+        return -EINVAL;
     }
 
     if (!bytes) {
         ALOGE("Invalid bytes value. 1..max_int64.");
-        return -1;
+        return -ERANGE;
     }
     auto it = mQuotaIfaces.find(iface);
 
     if (it == mQuotaIfaces.end()) {
         ALOGE("Need to have a prior interface quota set to set an alert");
-        return -1;
+        return -ENOENT;
     }
 
     return setCostlyAlert(iface, bytes, &it->second.alert);
@@ -757,14 +777,14 @@
 int BandwidthController::removeInterfaceAlert(const std::string& iface) {
     if (!isIfaceName(iface)) {
         ALOGE("removeInterfaceAlert: Invalid iface \"%s\"", iface.c_str());
-        return -1;
+        return -EINVAL;
     }
 
     auto it = mQuotaIfaces.find(iface);
 
     if (it == mQuotaIfaces.end()) {
         ALOGE("No prior alert set for interface %s", iface.c_str());
-        return -1;
+        return -ENOENT;
     }
 
     return removeCostlyAlert(iface, &it->second.alert);
@@ -776,12 +796,12 @@
 
     if (!isIfaceName(costName)) {
         ALOGE("setCostlyAlert: Invalid costName \"%s\"", costName.c_str());
-        return -1;
+        return -EINVAL;
     }
 
     if (!bytes) {
         ALOGE("Invalid bytes value. 1..max_int64.");
-        return -1;
+        return -ERANGE;
     }
 
     std::string alertName = costName + "Alert";
@@ -797,6 +817,7 @@
         res = iptablesRestoreFunction(V4V6, Join(commands, ""), nullptr);
         if (res) {
             ALOGE("Failed to set costly alert for %s", costName.c_str());
+            res = -EREMOTEIO;
         }
     }
     if (res == 0) {
@@ -808,12 +829,12 @@
 int BandwidthController::removeCostlyAlert(const std::string& costName, int64_t* alertBytes) {
     if (!isIfaceName(costName)) {
         ALOGE("removeCostlyAlert: Invalid costName \"%s\"", costName.c_str());
-        return -1;
+        return -EINVAL;
     }
 
     if (!*alertBytes) {
         ALOGE("No prior alert set for %s alert", costName.c_str());
-        return -1;
+        return -ENOENT;
     }
 
     std::string alertName = costName + "Alert";
@@ -825,7 +846,7 @@
     };
     if (iptablesRestoreFunction(V4V6, Join(commands, ""), nullptr) != 0) {
         ALOGE("Failed to remove costly alert %s", costName.c_str());
-        return -1;
+        return -EREMOTEIO;
     }
 
     *alertBytes = 0;
diff --git a/server/BandwidthController.h b/server/BandwidthController.h
index bc27c07..0b76134 100644
--- a/server/BandwidthController.h
+++ b/server/BandwidthController.h
@@ -46,11 +46,17 @@
     int getInterfaceQuota(const std::string& iface, int64_t* bytes);
     int removeInterfaceQuota(const std::string& iface);
 
+    // TODO: Remove after removing these commands in CommandListener
     int addNaughtyApps(int numUids, const char* const appUids[]);
     int removeNaughtyApps(int numUids, const char* const appUids[]);
     int addNiceApps(int numUids, const char* const appUids[]);
     int removeNiceApps(int numUids, const char* const appUids[]);
 
+    int addNaughtyApps(const std::vector<std::string>& appStrUid);
+    int removeNaughtyApps(const std::vector<std::string>& appStrUid);
+    int addNiceApps(const std::vector<std::string>& appStrUid);
+    int removeNiceApps(const std::vector<std::string>& appStrUid);
+
     int setGlobalAlert(int64_t bytes);
     int removeGlobalAlert();
     int setGlobalAlertInForwardChain();
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index cb974ea..0563af4 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -208,6 +208,102 @@
     return binder::Status::ok();
 }
 
+binder::Status NetdNativeService::bandwidthSetInterfaceQuota(const std::string& ifName,
+                                                             int64_t bytes) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName).arg(bytes);
+
+    int res = gCtls->bandwidthCtrl.setInterfaceQuota(ifName, bytes);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthRemoveInterfaceQuota(const std::string& ifName) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
+
+    int res = gCtls->bandwidthCtrl.removeInterfaceQuota(ifName);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthSetInterfaceAlert(const std::string& ifName,
+                                                             int64_t bytes) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName).arg(bytes);
+
+    int res = gCtls->bandwidthCtrl.setInterfaceAlert(ifName, bytes);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthRemoveInterfaceAlert(const std::string& ifName) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
+
+    int res = gCtls->bandwidthCtrl.removeInterfaceAlert(ifName);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthSetGlobalAlert(int64_t bytes) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(bytes);
+
+    int res = gCtls->bandwidthCtrl.setGlobalAlert(bytes);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthAddNaughtyApp(int32_t uid) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+
+    std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
+    int res = gCtls->bandwidthCtrl.addNaughtyApps(appStrUids);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthRemoveNaughtyApp(int32_t uid) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+
+    std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
+    int res = gCtls->bandwidthCtrl.removeNaughtyApps(appStrUids);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthAddNiceApp(int32_t uid) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+
+    std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
+    int res = gCtls->bandwidthCtrl.addNiceApps(appStrUids);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::bandwidthRemoveNiceApp(int32_t uid) {
+    NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
+    auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
+
+    std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
+    int res = gCtls->bandwidthCtrl.removeNiceApps(appStrUids);
+
+    gLog.log(entry.returns(res).withAutomaticDuration());
+    return statusFromErrcode(res);
+}
+
 binder::Status NetdNativeService::networkCreatePhysical(int32_t netId,
         const std::string& permission) {
     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index c8b85f0..57d99db 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -43,6 +43,15 @@
 
     // Bandwidth control commands.
     binder::Status bandwidthEnableDataSaver(bool enable, bool *ret) override;
+    binder::Status bandwidthSetInterfaceQuota(const std::string& ifName, int64_t bytes) override;
+    binder::Status bandwidthRemoveInterfaceQuota(const std::string& ifName) override;
+    binder::Status bandwidthSetInterfaceAlert(const std::string& ifName, int64_t bytes) override;
+    binder::Status bandwidthRemoveInterfaceAlert(const std::string& ifName) override;
+    binder::Status bandwidthSetGlobalAlert(int64_t bytes) override;
+    binder::Status bandwidthAddNaughtyApp(int32_t uid) override;
+    binder::Status bandwidthRemoveNaughtyApp(int32_t uid) override;
+    binder::Status bandwidthAddNiceApp(int32_t uid) override;
+    binder::Status bandwidthRemoveNiceApp(int32_t uid) override;
 
     // Network and routing commands.
     binder::Status networkCreatePhysical(int32_t netId, const std::string& permission)
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index 5e42770..e69025a 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -682,4 +682,87 @@
     */
     void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
 
+   /**
+    * Set quota for interface
+    *
+    * @param ifName Name of target interface
+    * @param bytes Quota value in bytes
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
+
+   /**
+    * Remove quota for interface
+    *
+    * @param ifName Name of target interface
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
+
+   /**
+    * Set alert for interface
+    *
+    * @param ifName Name of target interface
+    * @param bytes Alert value in bytes
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
+
+   /**
+    * Remove alert for interface
+    *
+    * @param ifName Name of target interface
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
+
+   /**
+    * Set global alert
+    *
+    * @param bytes Alert value in bytes
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthSetGlobalAlert(long bytes);
+
+   /**
+    * Add naughty app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthAddNaughtyApp(int uid);
+
+   /**
+    * Remove naughty app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthRemoveNaughtyApp(int uid);
+
+   /**
+    * Add nice app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthAddNiceApp(int uid);
+
+   /**
+    * Remove nice app bandwidth rule for specific app
+    *
+    * @param uid uid of target app
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the the failure.
+    */
+    void bandwidthRemoveNiceApp(int uid);
+
 }