Merge "Mark 3 tests as flaky."
am: f6c61f329a

Change-Id: Ie1c38e247ccfaa407d35cf6b6e28306d36cdccca
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index 25e111e..a66fcae 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -78,7 +78,7 @@
         out.writeStrongBinder(mBinder);
     }
 
-    public static final Parcelable.Creator<CaptivePortal> CREATOR
+    public static final @android.annotation.NonNull Parcelable.Creator<CaptivePortal> CREATOR
             = new Parcelable.Creator<CaptivePortal>() {
         @Override
         public CaptivePortal createFromParcel(Parcel in) {
diff --git a/core/java/android/net/ConnectionInfo.java b/core/java/android/net/ConnectionInfo.java
index 58d0e05..4514a84 100644
--- a/core/java/android/net/ConnectionInfo.java
+++ b/core/java/android/net/ConnectionInfo.java
@@ -54,7 +54,7 @@
         out.writeInt(remote.getPort());
     }
 
-    public static final Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() {
+    public static final @android.annotation.NonNull Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() {
         public ConnectionInfo createFromParcel(Parcel in) {
             int protocol = in.readInt();
             InetAddress localAddress;
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 788d7d9..98bab44 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -84,7 +84,7 @@
     }
 
     /** Implement the Parcelable interface {@hide} */
-    public static final Creator<DhcpInfo> CREATOR =
+    public static final @android.annotation.NonNull Creator<DhcpInfo> CREATOR =
         new Creator<DhcpInfo>() {
             public DhcpInfo createFromParcel(Parcel in) {
                 DhcpInfo info = new DhcpInfo();
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
index 3319f33..2af82d7 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/core/java/android/net/IpConfiguration.java
@@ -189,7 +189,7 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final Creator<IpConfiguration> CREATOR =
+    public static final @android.annotation.NonNull Creator<IpConfiguration> CREATOR =
         new Creator<IpConfiguration>() {
             public IpConfiguration createFromParcel(Parcel in) {
                 IpConfiguration config = new IpConfiguration();
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index 416157c..8cfe6df 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -288,7 +288,7 @@
     /**
      * Implement the Parcelable interface.
      */
-    public static final Creator<IpPrefix> CREATOR =
+    public static final @android.annotation.NonNull Creator<IpPrefix> CREATOR =
             new Creator<IpPrefix>() {
                 public IpPrefix createFromParcel(Parcel in) {
                     byte[] address = in.createByteArray();
diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java
index 18726f7..9b8b732 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/core/java/android/net/KeepalivePacketData.java
@@ -105,7 +105,7 @@
     }
 
     /** Parcelable Creator */
-    public static final Parcelable.Creator<KeepalivePacketData> CREATOR =
+    public static final @android.annotation.NonNull Parcelable.Creator<KeepalivePacketData> CREATOR =
             new Parcelable.Creator<KeepalivePacketData>() {
                 public KeepalivePacketData createFromParcel(Parcel in) {
                     return new KeepalivePacketData(in);
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index f17adea..93dd2e4 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -378,7 +378,7 @@
     /**
      * Implement the Parcelable interface.
      */
-    public static final Creator<LinkAddress> CREATOR =
+    public static final @android.annotation.NonNull Creator<LinkAddress> CREATOR =
         new Creator<LinkAddress>() {
             public LinkAddress createFromParcel(Parcel in) {
                 InetAddress address = null;
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index ad67763..d3f48ac 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -1627,7 +1627,7 @@
     /**
      * Implement the Parcelable interface.
      */
-    public static final Creator<LinkProperties> CREATOR =
+    public static final @android.annotation.NonNull Creator<LinkProperties> CREATOR =
         new Creator<LinkProperties>() {
             public LinkProperties createFromParcel(Parcel in) {
                 LinkProperties netProp = new LinkProperties();
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 52d485d..a809b28 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -168,7 +168,7 @@
         return 0;
     }
 
-    public static final Parcelable.Creator<MacAddress> CREATOR =
+    public static final @android.annotation.NonNull Parcelable.Creator<MacAddress> CREATOR =
             new Parcelable.Creator<MacAddress>() {
                 public MacAddress createFromParcel(Parcel in) {
                     return new MacAddress(in.readLong());
@@ -411,6 +411,21 @@
     }
 
     /**
+     * Checks if this MAC Address matches the provided range.
+     *
+     * @param baseAddress MacAddress representing the base address to compare with.
+     * @param mask MacAddress representing the mask to use during comparison.
+     * @return true if this MAC Address matches the given range.
+     *
+     * @hide
+     */
+    public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+        Preconditions.checkNotNull(baseAddress);
+        Preconditions.checkNotNull(mask);
+        return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
+    }
+
+    /**
      * Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address is converted
      * to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is used to construct a link-local
      * IPv6 address per RFC 4862.
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 09a86fc..3f56def 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -471,7 +471,7 @@
         dest.writeInt(netId);
     }
 
-    public static final Creator<Network> CREATOR =
+    public static final @android.annotation.NonNull Creator<Network> CREATOR =
         new Creator<Network>() {
             public Network createFromParcel(Parcel in) {
                 int netId = in.readInt();
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index b3f829a..43ea589 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -516,7 +516,7 @@
     }
 
     /**
-     * Requests that the network hardware stops sending keepalive packets.
+     * Requests that the network hardware send the specified packet at the specified interval.
      */
     protected void stopSocketKeepalive(Message msg) {
         onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index dfd7089..3e325b7 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -1481,7 +1481,7 @@
         dest.writeString(mSSID);
     }
 
-    public static final Creator<NetworkCapabilities> CREATOR =
+    public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
         new Creator<NetworkCapabilities>() {
             @Override
             public NetworkCapabilities createFromParcel(Parcel in) {
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 8fb5a20..92f105f 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -560,7 +560,7 @@
         }
     }
 
-    public static final Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
+    public static final @android.annotation.NonNull Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
         @Override
         public NetworkInfo createFromParcel(Parcel in) {
             int netType = in.readInt();
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 6fb2390..9ba3bd9 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -106,7 +106,7 @@
         out.writeInt(skip464xlat ? 1 : 0);
     }
 
-    public static final Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
+    public static final @android.annotation.NonNull Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
         @Override
         public NetworkMisc createFromParcel(Parcel in) {
             NetworkMisc networkMisc = new NetworkMisc();
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index acafa13..4270740 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -368,7 +368,7 @@
         dest.writeInt(requestId);
         dest.writeString(type.name());
     }
-    public static final Creator<NetworkRequest> CREATOR =
+    public static final @android.annotation.NonNull Creator<NetworkRequest> CREATOR =
         new Creator<NetworkRequest>() {
             public NetworkRequest createFromParcel(Parcel in) {
                 NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in);
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index 97fb3fb..292cf50 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -87,7 +87,7 @@
     }
 
     @UnsupportedAppUsage
-    public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
+    public static final @android.annotation.NonNull Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
         @Override
         public NetworkState createFromParcel(Parcel in) {
             return new NetworkState(in);
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 228e62d..d0f54b4 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,10 +16,15 @@
 
 package android.net;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.net.shared.Inet4AddressUtils;
 import android.os.Build;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Log;
 import android.util.Pair;
 
@@ -454,4 +459,30 @@
         }
         return routedIPCount;
     }
+
+    private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
+
+    /**
+     * Returns true if the hostname is weakly validated.
+     * @param hostname Name of host to validate.
+     * @return True if it's a valid-ish hostname.
+     *
+     * @hide
+     */
+    public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
+        // TODO(b/34953048): Use a validation method that permits more accurate,
+        // but still inexpensive, checking of likely valid DNS hostnames.
+        final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
+        if (!hostname.matches(weakHostnameRegex)) {
+            return false;
+        }
+
+        for (int address_family : ADDRESS_FAMILIES) {
+            if (Os.inet_pton(address_family, hostname) != null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index ef2269a..807c467 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -342,7 +342,7 @@
         dest.writeStringArray(mParsedExclusionList);
     }
 
-    public static final Creator<ProxyInfo> CREATOR =
+    public static final @android.annotation.NonNull Creator<ProxyInfo> CREATOR =
         new Creator<ProxyInfo>() {
             public ProxyInfo createFromParcel(Parcel in) {
                 String host = null;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index fdd904a..52d3fc4 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -527,7 +527,7 @@
     /**
      * Implement the Parcelable interface.
      */
-    public static final Creator<RouteInfo> CREATOR =
+    public static final @android.annotation.NonNull Creator<RouteInfo> CREATOR =
         new Creator<RouteInfo>() {
         public RouteInfo createFromParcel(Parcel in) {
             IpPrefix dest = in.readParcelable(null);
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 9ce6bae..5bc9953 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -283,7 +283,7 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final Creator<StaticIpConfiguration> CREATOR =
+    public static final @android.annotation.NonNull Creator<StaticIpConfiguration> CREATOR =
         new Creator<StaticIpConfiguration>() {
             public StaticIpConfiguration createFromParcel(Parcel in) {
                 return readFromParcel(in);
diff --git a/core/java/android/net/UidRange.java b/core/java/android/net/UidRange.java
index a1ac960..d75c43d 100644
--- a/core/java/android/net/UidRange.java
+++ b/core/java/android/net/UidRange.java
@@ -111,7 +111,7 @@
         dest.writeInt(stop);
     }
 
-    public static final Creator<UidRange> CREATOR =
+    public static final @android.annotation.NonNull Creator<UidRange> CREATOR =
         new Creator<UidRange>() {
             @Override
             public UidRange createFromParcel(Parcel in) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d822879..2a2dc3d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -20,6 +20,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_VPN;
@@ -2806,7 +2807,7 @@
             switch (msg.what) {
                 default:
                     return false;
-                case android.net.NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: {
+                case NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: {
                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.sendingUid,
                             /* callOnUnavailable */ true);
                     break;
@@ -7011,6 +7012,12 @@
             }
         }
 
+        // restore private DNS settings to default mode (opportunistic)
+        if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+        }
+
         Settings.Global.putString(mContext.getContentResolver(),
                 Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
     }
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index b0e5fb1..daf187d 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -254,6 +254,39 @@
         }
     }
 
+    @Test
+    public void testMatches() {
+        // match 4 bytes prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:00:00"),
+                MacAddress.fromString("ff:ff:ff:ff:00:00")));
+
+        // match bytes 0,1,2 and 5
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:00:00:11"),
+                MacAddress.fromString("ff:ff:ff:00:00:ff")));
+
+        // match 34 bit prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:c0:00"),
+                MacAddress.fromString("ff:ff:ff:ff:c0:00")));
+
+        // fail to match 36 bit prefix
+        assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:40:00"),
+                MacAddress.fromString("ff:ff:ff:ff:f0:00")));
+
+        // match all 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:ee:11"),
+                MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
+
+        // match none of 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("00:00:00:00:00:00"),
+                MacAddress.fromString("00:00:00:00:00:00")));
+    }
+
     /**
      * Tests that link-local address generation from MAC is valid.
      */
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c63bf42..caa3203 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -3427,7 +3427,7 @@
         testFactory.setScoreFilter(40);
 
         // Register the factory and expect it to receive the default request.
-        testFactory.expectAddRequestsWithScores(0); // default request score is 0, not served yet
+        testFactory.expectAddRequestsWithScores(0);
         testFactory.register();
         SparseArray<NetworkRequest> requests = testFactory.waitForNetworkRequests(1);
 
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 7c40adf..71b72b8 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -32,6 +32,7 @@
 
 import android.app.AppOpsManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.net.INetd;
 import android.net.IpSecAlgorithm;
 import android.net.IpSecConfig;
@@ -57,6 +58,7 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
+import java.net.Inet4Address;
 import java.net.Socket;
 import java.util.Arrays;
 import java.util.Collection;
@@ -119,6 +121,11 @@
         }
 
         @Override
+        public PackageManager getPackageManager() {
+            return mMockPkgMgr;
+        }
+
+        @Override
         public void enforceCallingOrSelfPermission(String permission, String message) {
             if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
                 return;
@@ -128,6 +135,7 @@
     };
 
     INetd mMockNetd;
+    PackageManager mMockPkgMgr;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
     IpSecService mIpSecService;
     Network fakeNetwork = new Network(0xAB);
@@ -152,11 +160,16 @@
     @Before
     public void setUp() throws Exception {
         mMockNetd = mock(INetd.class);
+        mMockPkgMgr = mock(PackageManager.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
         mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
+
+        // PackageManager should always return true (feature flag tests in IpSecServiceTest)
+        when(mMockPkgMgr.hasSystemFeature(anyString())).thenReturn(true);
+
         // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
         when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage")))
             .thenReturn(AppOpsManager.MODE_ALLOWED);
@@ -709,4 +722,18 @@
         } catch (SecurityException expected) {
         }
     }
+
+    @Test
+    public void testFeatureFlagVerification() throws Exception {
+        when(mMockPkgMgr.hasSystemFeature(eq(PackageManager.FEATURE_IPSEC_TUNNELS)))
+                .thenReturn(false);
+
+        try {
+            String addr = Inet4Address.getLoopbackAddress().getHostAddress();
+            mIpSecService.createTunnelInterface(
+                    addr, addr, new Network(0), new Binder(), "blessedPackage");
+            fail("Expected UnsupportedOperationException for disabled feature");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
 }