Make isHostRoute match only host routes

Currently, isHostRoute returns true iff the gateway address is
the unspecified address (0.0.0.0 or ::). Thus, it will return
true for any route that has no gateway (e.g., a route pointing at
a point-to-point interface), even if the route is not a host
route.

Fix this by checking the prefix length instead. This should be
safe because:

1. mDestination cannot be null, since it's created using new.
2. Host routes created using makeHostRoute (which is what
   ConnectivityService calls) always have the correct prefix
   lengths (/32 or /128) set.

Bug: 8276725
Change-Id: I14285398823fa6c312349128c7cc216cad4a84c9
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 3a7abc0..cc3c5f7 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -132,7 +132,10 @@
     }
 
     private boolean isHost() {
-        return (mGateway.equals(Inet4Address.ANY) || mGateway.equals(Inet6Address.ANY));
+        return (mDestination.getAddress() instanceof Inet4Address &&
+                mDestination.getNetworkPrefixLength() == 32) ||
+               (mDestination.getAddress() instanceof Inet6Address &&
+                mDestination.getNetworkPrefixLength() == 128);
     }
 
     private boolean isDefault() {
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 59eb601..55d6592 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -149,6 +149,40 @@
         assertAreNotEqual(r1, r3);
     }
 
+    public void testHostRoute() {
+      RouteInfo r;
+
+      r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0");
+      assertFalse(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("::/0"), Address("::"), "wlan0");
+      assertFalse(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
+      assertFalse(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("2001:db8::/48"), null, "wlan0");
+      assertFalse(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("192.0.2.0/32"), Address("0.0.0.0"), "wlan0");
+      assertTrue(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("2001:db8::/128"), Address("::"), "wlan0");
+      assertTrue(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("192.0.2.0/32"), null, "wlan0");
+      assertTrue(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("2001:db8::/128"), null, "wlan0");
+      assertTrue(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("::/128"), Address("fe80::"), "wlan0");
+      assertTrue(r.isHostRoute());
+
+      r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0");
+      assertTrue(r.isHostRoute());
+    }
+
     public RouteInfo passThroughParcel(RouteInfo r) {
         Parcel p = Parcel.obtain();
         RouteInfo r2 = null;