Add a binder RPC to enable/disable data saver.

Bug: 26685616
Bug: 27506285
Change-Id: Id11ee717cfc1c79070b6bbec397986c25947646c
diff --git a/server/BandwidthController.h b/server/BandwidthController.h
index f62cb1b..9d59a6c 100644
--- a/server/BandwidthController.h
+++ b/server/BandwidthController.h
@@ -21,9 +21,12 @@
 #include <utility>  // for pair
 
 #include <sysutils/SocketClient.h>
+#include <utils/RWLock.h>
 
 class BandwidthController {
 public:
+    android::RWLock lock;
+
     class TetherStats {
     public:
         TetherStats(void)
diff --git a/server/CommandListener.cpp b/server/CommandListener.cpp
index 968b415..6dc8485 100644
--- a/server/CommandListener.cpp
+++ b/server/CommandListener.cpp
@@ -190,7 +190,7 @@
     registerLockingCmd(new ListTtysCmd());
     registerLockingCmd(new PppdCmd());
     registerLockingCmd(new SoftapCmd());
-    registerLockingCmd(new BandwidthControlCmd());
+    registerLockingCmd(new BandwidthControlCmd(), gCtls->bandwidthCtrl.lock);
     registerLockingCmd(new IdletimerControlCmd());
     registerLockingCmd(new ResolverCmd());
     registerLockingCmd(new FirewallCmd(), gCtls->firewallCtrl.lock);
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index d39bdfa..97b41b2 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -114,7 +114,15 @@
     int err = gCtls->firewallCtrl.replaceUidChain(name.string(), isWhitelist, uids);
     *ret = (err == 0);
     return binder::Status::ok();
-
 }
+
+binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
+    NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock);
+
+    int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
+    *ret = (err == 0);
+    return binder::Status::ok();
+}
+
 }  // namespace net
 }  // namespace android
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index b24e96e..f7409d8 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -36,6 +36,7 @@
     binder::Status firewallReplaceUidChain(
             const String16& chainName, bool isWhitelist,
             const std::vector<int32_t>& uids, bool *ret) override;
+    binder::Status bandwidthEnableDataSaver(bool enable, bool *ret) override;
 
 };
 
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index b54c7fa..cca5b58 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -37,4 +37,22 @@
      * @return true if the chain was successfully replaced, false otherwise.
      */
     boolean firewallReplaceUidChain(String chainName, boolean isWhitelist, in int[] uids);
+
+    /**
+     * Enables or disables data saver mode on costly network interfaces.
+     *
+     * - When disabled, all packets to/from apps in the penalty box chain are rejected on costly
+     *   interfaces. Traffic to/from other apps or on other network interfaces is allowed.
+     * - When enabled, only apps that are in the happy box chain and not in the penalty box chain
+     *   are allowed network connectivity on costly interfaces. All other packets on these
+     *   interfaces are rejected. The happy box chain always contains all system UIDs; to disallow
+     *   traffic from system UIDs, place them in the penalty box chain.
+     *
+     * By default, data saver mode is disabled. This command has no effect but might still return an
+     * error) if {@code enable} is the same as the current value.
+     *
+     * @param enable whether to enable or disable data saver mode.
+     * @return true if the if the operation was successful, false otherwise.
+     */
+    boolean bandwidthEnableDataSaver(boolean enable);
 }