Merge "Fix NetworkInterface#getHardwareAddress corner case"
diff --git a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
index 73cb7ac..6ddb483 100644
--- a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
@@ -17,6 +17,7 @@
 package libcore.java.net;
 
 import junit.framework.TestCase;
+import java.lang.reflect.Field;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -146,6 +147,48 @@
         }
     }
 
+    // b/28903817
+    public void testInterfaceRemoval() throws Exception {
+        NetworkInterface lo = NetworkInterface.getByName("lo");
+
+        // Simulate interface removal by changing it's name to unused value.
+        // This works only because getHardwareAddress (and others) is using name to fetch
+        // the NI data. If this changes, this test needs an update.
+        Field nameField = NetworkInterface.class.getDeclaredField("name");
+        nameField.setAccessible(true);
+        nameField.set(lo, "noSuchInterface");
+
+        try {
+            lo.getHardwareAddress();
+            fail();
+        } catch(SocketException expected) {}
+
+        try {
+            lo.getMTU();
+            fail();
+        } catch(SocketException expected) {}
+
+        try {
+            lo.isLoopback();
+            fail();
+        } catch(SocketException expected) {}
+
+        try {
+            lo.isUp();
+            fail();
+        } catch(SocketException expected) {}
+
+        try {
+            lo.isPointToPoint();
+            fail();
+        } catch(SocketException expected) {}
+
+        try {
+            lo.supportsMulticast();
+            fail();
+        } catch(SocketException expected) {}
+    }
+
     // Is ifName a name of a Ethernet device?
     private static Pattern ethernetNamePattern = Pattern.compile("^(eth|wlan)[0-9]+$");
     private static boolean isEthernet(String ifName) throws Exception {
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index 3ea67be..ac39d2a 100755
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -439,7 +439,13 @@
      * @since 1.6
      */
     public byte[] getHardwareAddress() throws SocketException {
-        return (hardwareAddr != null) ? hardwareAddr.clone() : null;
+        // Android chage - do not use the cached address, fetch
+        // the object again. NI might not be valid anymore.
+        NetworkInterface ni = getByName0(name);
+        if (ni == null) {
+            throw new SocketException("NetworkInterface doesn't exist anymore");
+        }
+        return ni.hardwareAddr;
     }
 
     /**