Merge changes from topic "DnsException"

* changes:
  CTS DnsResolverTest for DnsException ctor
  DnsResolver: Make DnsException ctor public
diff --git a/framework/aidl-export/android/net/DhcpOption.aidl b/framework/aidl-export/android/net/DhcpOption.aidl
new file mode 100644
index 0000000..9ed0e62
--- /dev/null
+++ b/framework/aidl-export/android/net/DhcpOption.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable DhcpOption;
+
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 7fc0382..50dd2ad 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -99,6 +99,15 @@
     field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3
   }
 
+  public final class DhcpOption implements android.os.Parcelable {
+    ctor public DhcpOption(byte, @Nullable byte[]);
+    method public int describeContents();
+    method public byte getType();
+    method @Nullable public byte[] getValue();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpOption> CREATOR;
+  }
+
   public final class NetworkAgentConfig implements android.os.Parcelable {
     method @Nullable public String getSubscriberId();
     method public boolean isBypassableVpn();
diff --git a/framework/api/module-lib-lint-baseline.txt b/framework/api/module-lib-lint-baseline.txt
new file mode 100644
index 0000000..c7b0db5
--- /dev/null
+++ b/framework/api/module-lib-lint-baseline.txt
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+NoByteOrShort: android.net.DhcpOption#DhcpOption(byte, byte[]) parameter #0:
+    Should avoid odd sized primitives; use `int` instead of `byte` in parameter type in android.net.DhcpOption(byte type, byte[] value)
+NoByteOrShort: android.net.DhcpOption#describeContents():
+    Should avoid odd sized primitives; use `int` instead of `byte` in method android.net.DhcpOption.describeContents()
+NoByteOrShort: android.net.DhcpOption#getType():
+    Should avoid odd sized primitives; use `int` instead of `byte` in method android.net.DhcpOption.getType()
diff --git a/framework/src/android/net/DhcpOption.java b/framework/src/android/net/DhcpOption.java
new file mode 100644
index 0000000..a125290
--- /dev/null
+++ b/framework/src/android/net/DhcpOption.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing an option in the DHCP protocol.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class DhcpOption implements Parcelable {
+    private final byte mType;
+    private final byte[] mValue;
+
+    /**
+     * Constructs a DhcpOption object.
+     *
+     * @param type the type of this option
+     * @param value the value of this option. If {@code null}, DHCP packets containing this option
+     *              will include the option type in the Parameter Request List. Otherwise, DHCP
+     *              packets containing this option will include the option in the options section.
+     */
+    public DhcpOption(byte type, @Nullable byte[] value) {
+        mType = type;
+        mValue = value;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeByte(mType);
+        dest.writeByteArray(mValue);
+    }
+
+    /** Implement the Parcelable interface */
+    public static final @NonNull Creator<DhcpOption> CREATOR =
+            new Creator<DhcpOption>() {
+                public DhcpOption createFromParcel(Parcel in) {
+                    return new DhcpOption(in.readByte(), in.createByteArray());
+                }
+
+                public DhcpOption[] newArray(int size) {
+                    return new DhcpOption[size];
+                }
+            };
+
+    /** Get the type of DHCP option */
+    public byte getType() {
+        return mType;
+    }
+
+    /** Get the value of DHCP option */
+    @Nullable public byte[] getValue() {
+        return mValue == null ? null : mValue.clone();
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 579be15..80c2db4 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -2380,7 +2380,7 @@
         final String ssid = unquoteSSID(wifiNetworkCapabilities.getSsid());
         final boolean oldMeteredValue = wifiNetworkCapabilities.isMetered();
 
-        try {
+        testAndCleanup(() -> {
             // This network will be used for unmetered. Wait for it to be validated because
             // OEM_NETWORK_PREFERENCE_TEST only prefers NOT_METERED&VALIDATED to a network with
             // TRANSPORT_TEST, like OEM_NETWORK_PREFERENCE_OEM_PAID.
@@ -2405,18 +2405,18 @@
             // callback in any case therefore confirm its receipt before continuing to assure the
             // system is in the expected state.
             waitForAvailable(systemDefaultCallback, TRANSPORT_WIFI);
-        } finally {
+        }, /* cleanup */ () -> {
             // Validate that removing the test network will fallback to the default network.
             runWithShellPermissionIdentity(tnt::teardown);
             defaultCallback.expectCallback(CallbackEntry.LOST, tnt.getNetwork(),
                     NETWORK_CALLBACK_TIMEOUT_MS);
             waitForAvailable(defaultCallback);
-
-            setWifiMeteredStatusAndWait(ssid, oldMeteredValue, false /* waitForValidation */);
-
-            // Cleanup any prior test state from setOemNetworkPreference
-            clearOemNetworkPreference();
-        }
+            }, /* cleanup */ () -> {
+                setWifiMeteredStatusAndWait(ssid, oldMeteredValue, false /* waitForValidation */);
+            }, /* cleanup */ () -> {
+                // Cleanup any prior test state from setOemNetworkPreference
+                clearOemNetworkPreference();
+            });
     }
 
     /**
@@ -2437,29 +2437,30 @@
 
         final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
 
-        try {
+        testAndCleanup(() -> {
             setOemNetworkPreferenceForMyPackage(
                     OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY);
             registerTestOemNetworkPreferenceCallbacks(defaultCallback, systemDefaultCallback);
             waitForAvailable(defaultCallback, tnt.getNetwork());
             waitForAvailable(systemDefaultCallback, wifiNetwork);
-        } finally {
-            runWithShellPermissionIdentity(tnt::teardown);
-            defaultCallback.expectCallback(CallbackEntry.LOST, tnt.getNetwork(),
-                    NETWORK_CALLBACK_TIMEOUT_MS);
+        }, /* cleanup */ () -> {
+                runWithShellPermissionIdentity(tnt::teardown);
+                defaultCallback.expectCallback(CallbackEntry.LOST, tnt.getNetwork(),
+                        NETWORK_CALLBACK_TIMEOUT_MS);
 
-            // This network preference should only ever use the test network therefore available
-            // should not trigger when the test network goes down (e.g. switch to cellular).
-            defaultCallback.assertNoCallback();
-            // The system default should still be connected to Wi-fi
-            assertEquals(wifiNetwork, systemDefaultCallback.getLastAvailableNetwork());
+                // This network preference should only ever use the test network therefore available
+                // should not trigger when the test network goes down (e.g. switch to cellular).
+                defaultCallback.assertNoCallback();
+                // The system default should still be connected to Wi-fi
+                assertEquals(wifiNetwork, systemDefaultCallback.getLastAvailableNetwork());
+            }, /* cleanup */ () -> {
+                // Cleanup any prior test state from setOemNetworkPreference
+                clearOemNetworkPreference();
 
-            // Cleanup any prior test state from setOemNetworkPreference
-            clearOemNetworkPreference();
-
-            // The default (non-test) network should be available as the network pref was cleared.
-            waitForAvailable(defaultCallback);
-        }
+                // The default (non-test) network should be available as the network pref was
+                // cleared.
+                waitForAvailable(defaultCallback);
+            });
     }
 
     private void registerTestOemNetworkPreferenceCallbacks(
diff --git a/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt b/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt
new file mode 100644
index 0000000..1a62560
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/DhcpOptionTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts
+
+import android.os.Build
+import android.net.DhcpOption
+import androidx.test.filters.SmallTest
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.DevSdkIgnoreRunner
+import org.junit.Assert.assertArrayEquals
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.runner.RunWith
+import org.junit.Test
+
+@SmallTest
+@IgnoreUpTo(Build.VERSION_CODES.S)
+@RunWith(DevSdkIgnoreRunner::class)
+class DhcpOptionTest {
+    private val DHCP_OPTION_TYPE: Byte = 2
+    private val DHCP_OPTION_VALUE = byteArrayOf(0, 1, 2, 4, 8, 16)
+
+    @Test
+    fun testConstructor() {
+        val dhcpOption = DhcpOption(DHCP_OPTION_TYPE, DHCP_OPTION_VALUE)
+        assertEquals(DHCP_OPTION_TYPE, dhcpOption.type)
+        assertArrayEquals(DHCP_OPTION_VALUE, dhcpOption.value)
+    }
+
+    @Test
+    fun testConstructorWithNullValue() {
+        val dhcpOption = DhcpOption(DHCP_OPTION_TYPE, null)
+        assertEquals(DHCP_OPTION_TYPE, dhcpOption.type)
+        assertNull(dhcpOption.value)
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index bd30b77..49037ee 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -69,8 +69,7 @@
         "java/android/net/IpSecTransformTest.java",
         "java/android/net/KeepalivePacketDataUtilTest.java",
         "java/android/net/NetworkIdentityTest.kt",
-        "java/android/net/NetworkStatsTest.java",
-        "java/android/net/NetworkStatsHistoryTest.java",
+        "java/android/net/NetworkStats*.java",
         "java/android/net/NetworkTemplateTest.kt",
         "java/android/net/TelephonyNetworkSpecifierTest.java",
         "java/android/net/VpnManagerTest.java",
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java b/tests/unit/java/android/net/NetworkStatsAccessTest.java
similarity index 97%
rename from tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java
rename to tests/unit/java/android/net/NetworkStatsAccessTest.java
index 03d9404..0f9ed41 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java
+++ b/tests/unit/java/android/net/NetworkStatsAccessTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
-package com.android.server.net;
+package android.net;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.when;
@@ -43,7 +43,7 @@
 
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
 public class NetworkStatsAccessTest {
     private static final String TEST_PKG = "com.example.test";
     private static final int TEST_UID = 12345;
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
similarity index 97%
rename from tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java
rename to tests/unit/java/android/net/NetworkStatsCollectionTest.java
index 6b4ead5..0c4ffac 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.net;
+package android.net;
 
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.NetworkIdentity.OEM_NONE;
@@ -37,11 +37,6 @@
 import static org.junit.Assert.fail;
 
 import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkIdentity;
-import android.net.NetworkStats;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
 import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
@@ -83,7 +78,7 @@
  */
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
 public class NetworkStatsCollectionTest {
 
     private static final String TEST_FILE = "test.bin";
@@ -250,8 +245,8 @@
                 collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE));
 
         // Verify security check in getHistory.
-        assertNotNull(collection.getHistory(buildTemplateMobileAll(TEST_IMSI), null, myUid, SET_DEFAULT,
-                TAG_NONE, 0, 0L, 0L, NetworkStatsAccess.Level.DEFAULT, myUid));
+        assertNotNull(collection.getHistory(buildTemplateMobileAll(TEST_IMSI), null,
+                myUid, SET_DEFAULT, TAG_NONE, 0, 0L, 0L, NetworkStatsAccess.Level.DEFAULT, myUid));
         try {
             collection.getHistory(buildTemplateMobileAll(TEST_IMSI), null, otherUidInSameUser,
                     SET_DEFAULT, TAG_NONE, 0, 0L, 0L, NetworkStatsAccess.Level.DEFAULT, myUid);
@@ -275,7 +270,8 @@
                 new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
         stageFile(R.raw.netstats_v1, testFile);
 
-        final NetworkStatsCollection emptyCollection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
+        final NetworkStatsCollection emptyCollection =
+                new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
         collection.readLegacyNetwork(testFile);
 
@@ -313,7 +309,8 @@
             assertEquals(0L, history.getTotalBytes());
 
             // Normal collection should be untouched
-            history = getHistory(collection, plan, TIME_A, TIME_C); i = 0;
+            history = getHistory(collection, plan, TIME_A, TIME_C);
+            i = 0;
             assertEntry(100647, 197, 23649, 185, history.getValues(i++, null));
             assertEntry(100647, 196, 23648, 185, history.getValues(i++, null));
             assertEntry(18323, 76, 15032, 76, history.getValues(i++, null));
@@ -342,7 +339,8 @@
 
             // Slice from middle should be untouched
             history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
-                    TIME_B + HOUR_IN_MILLIS); i = 0;
+                    TIME_B + HOUR_IN_MILLIS);
+            i = 0;
             assertEntry(3821, 23, 4525, 26, history.getValues(i++, null));
             assertEntry(3820, 21, 4524, 26, history.getValues(i++, null));
             assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
@@ -365,7 +363,8 @@
             assertEquals(200000L, history.getTotalBytes());
 
             // Normal collection should be augmented
-            history = getHistory(collection, plan, TIME_A, TIME_C); i = 0;
+            history = getHistory(collection, plan, TIME_A, TIME_C);
+            i = 0;
             assertEntry(100647, 197, 23649, 185, history.getValues(i++, null));
             assertEntry(100647, 196, 23648, 185, history.getValues(i++, null));
             assertEntry(18323, 76, 15032, 76, history.getValues(i++, null));
@@ -397,7 +396,8 @@
 
             // Slice from middle should be augmented
             history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
-                    TIME_B + HOUR_IN_MILLIS); i = 0;
+                    TIME_B + HOUR_IN_MILLIS);
+            i = 0;
             assertEntry(2669, 0, 3161, 0, history.getValues(i++, null));
             assertEntry(2668, 0, 3160, 0, history.getValues(i++, null));
             assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
@@ -420,7 +420,8 @@
             assertEquals(400000L, history.getTotalBytes());
 
             // Normal collection should be augmented
-            history = getHistory(collection, plan, TIME_A, TIME_C); i = 0;
+            history = getHistory(collection, plan, TIME_A, TIME_C);
+            i = 0;
             assertEntry(100647, 197, 23649, 185, history.getValues(i++, null));
             assertEntry(100647, 196, 23648, 185, history.getValues(i++, null));
             assertEntry(18323, 76, 15032, 76, history.getValues(i++, null));
@@ -451,7 +452,8 @@
 
             // Slice from middle should be augmented
             history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
-                    TIME_B + HOUR_IN_MILLIS); i = 0;
+                    TIME_B + HOUR_IN_MILLIS);
+            i = 0;
             assertEntry(5338, 0, 6322, 0, history.getValues(i++, null));
             assertEntry(5337, 0, 6320, 0, history.getValues(i++, null));
             assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
index e35104e..416549c 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -37,7 +37,9 @@
 import android.app.usage.NetworkStatsManager;
 import android.net.DataUsageRequest;
 import android.net.NetworkIdentity;
+import android.net.NetworkIdentitySet;
 import android.net.NetworkStats;
+import android.net.NetworkStatsAccess;
 import android.net.NetworkTemplate;
 import android.os.Build;
 import android.os.ConditionVariable;
@@ -72,7 +74,7 @@
  */
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
 public class NetworkStatsObserversTest {
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test1";