Merge "Close netlink socket when shutting down IpReachabilityMonitor" into mnc-dev
diff --git a/core/java/android/net/IpReachabilityMonitor.java b/core/java/android/net/IpReachabilityMonitor.java
index add8774..cb8c866 100644
--- a/core/java/android/net/IpReachabilityMonitor.java
+++ b/core/java/android/net/IpReachabilityMonitor.java
@@ -73,7 +73,8 @@
     private final Set<InetAddress> mIpWatchList;
     private int mIpWatchListVersion;
     private boolean mRunning;
-    final private Thread mObserverThread;
+    private final NetlinkSocketObserver mNetlinkSocketObserver;
+    private final Thread mObserverThread;
 
     public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
         mInterfaceName = ifName;
@@ -88,15 +89,15 @@
         mIpWatchList = new HashSet<InetAddress>();
         mIpWatchListVersion = 0;
         mRunning = false;
-        mObserverThread = new Thread(new NetlinkSocketObserver());
+        mNetlinkSocketObserver = new NetlinkSocketObserver();
+        mObserverThread = new Thread(mNetlinkSocketObserver);
         mObserverThread.start();
     }
 
     public void stop() {
-        synchronized (mLock) {
-            mRunning = false;
-            mIpWatchList.clear();
-        }
+        synchronized (mLock) { mRunning = false; }
+        clearLinkProperties();
+        mNetlinkSocketObserver.clearNetlinkSocket();
     }
 
     // TODO: add a public dump() method that can be called during a bug report.
@@ -251,6 +252,7 @@
     }
 
 
+    // TODO: simply the number of objects by making this extend Thread.
     private final class NetlinkSocketObserver implements Runnable {
         private static final String TAG = "NetlinkSocketObserver";
         private NetlinkSocket mSocket;
@@ -292,7 +294,6 @@
             if (mSocket != null) {
                 mSocket.close();
             }
-            mSocket = null;
         }
 
             // TODO: Refactor the main loop to recreate the socket upon recoverable errors.
diff --git a/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java b/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java
index b32de78..c599fe3 100644
--- a/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java
+++ b/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java
@@ -90,4 +90,27 @@
 
         s.close();
     }
+
+    public void testRepeatedCloseCallsAreQuiet() throws Exception {
+        // Create a working NetlinkSocket.
+        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
+        assertNotNull(s);
+        s.connectToKernel();
+        NetlinkSocketAddress localAddr = s.getLocalAddress();
+        assertNotNull(localAddr);
+        assertEquals(0, localAddr.getGroupsMask());
+        assertTrue(0 != localAddr.getPortId());
+        // Close once.
+        s.close();
+        // Test that it is closed.
+        boolean expectedErrorSeen = false;
+        try {
+            localAddr = s.getLocalAddress();
+        } catch (ErrnoException e) {
+            expectedErrorSeen = true;
+        }
+        assertTrue(expectedErrorSeen);
+        // Close once more.
+        s.close();
+    }
 }