Implement network default set/clear.

(cherry picked from commit 4cc7df247a7ec67da3b5edfb9356077fbbf0150c)

Change-Id: Ib35d54816884c6a6ba28231c9b1f54e362d1d16a
diff --git a/NetworkController.cpp b/NetworkController.cpp
index 185f7d7..14c63f3 100644
--- a/NetworkController.cpp
+++ b/NetworkController.cpp
@@ -51,12 +51,51 @@
 }
 
 unsigned NetworkController::getDefaultNetwork() const {
+    android::RWLock::AutoRLock lock(mRWLock);
     return mDefaultNetId;
 }
 
-void NetworkController::setDefaultNetwork(unsigned netId) {
-    android::RWLock::AutoWLock lock(mRWLock);
-    mDefaultNetId = netId;
+bool NetworkController::setDefaultNetwork(unsigned newNetId) {
+    unsigned oldNetId;
+    {
+        android::RWLock::AutoWLock lock(mRWLock);
+        oldNetId = mDefaultNetId;
+        mDefaultNetId = newNetId;
+    }
+
+    if (oldNetId == newNetId) {
+        return true;
+    }
+
+    bool status = true;
+
+    // Add default network rules for the new netId.
+    if (isNetIdValid(newNetId)) {
+        Permission permission = mPermissionsController->getPermissionForNetwork(newNetId);
+
+        typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
+        std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(newNetId);
+        for (Iterator iter = range.first; iter != range.second; ++iter) {
+            if (!mRouteController->addDefaultNetwork(iter->second.c_str(), permission)) {
+                status = false;
+            }
+        }
+    }
+
+    // Remove the old default network rules.
+    if (isNetIdValid(oldNetId)) {
+        Permission permission = mPermissionsController->getPermissionForNetwork(oldNetId);
+
+        typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
+        std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(oldNetId);
+        for (Iterator iter = range.first; iter != range.second; ++iter) {
+            if (!mRouteController->removeDefaultNetwork(iter->second.c_str(), permission)) {
+                status = false;
+            }
+        }
+    }
+
+    return status;
 }
 
 void NetworkController::setNetworkForPid(int pid, unsigned netId) {
@@ -176,6 +215,14 @@
     mPermissionsController->setPermissionForNetwork(PERMISSION_NONE, netId);
     mNetIdToInterfaces.erase(netId);
 
+    if (netId == getDefaultNetwork()) {
+        // Could the default network have changed from below us, after we evaluated the 'if', thus
+        // making it wrong to call setDefaultNetwork() now? No, because the default can only change
+        // due to another command from CommandListener, and those are serialized (i.e., they can't
+        // happen in parallel with the destroyNetwork() that we are currently processing).
+        setDefaultNetwork(NETID_UNSET);
+    }
+
     return status;
 }