Snap for 10743636 from 43af15894d9f995f15fc0098acfe05569f68940a to mainline-uwb-release

Change-Id: I4de5c225dae3dfee6eb516e369be2e0c06c01cbd
diff --git a/Android.bp b/Android.bp
index 15b4235..ebe5217 100644
--- a/Android.bp
+++ b/Android.bp
@@ -307,7 +307,6 @@
     name: "NetworkStackAndroidLibraryDefaults",
     srcs: [
         ":framework-networkstack-shared-srcs",
-        ":services-connectivity-shared-srcs",
     ],
     libs: ["unsupportedappusage"],
     static_libs: [
@@ -389,7 +388,10 @@
     ],
     // If this library is ever used outside of tests, it should not use "Dhcp*Packet", and specify
     // its contents explicitly.
-    visibility: ["//packages/modules/Connectivity/tests/cts/net"],
+    visibility: [
+        "//packages/modules/Connectivity/Tethering/tests/integration",
+        "//packages/modules/Connectivity/tests/cts/net",
+    ],
 }
 
 java_genrule {
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index 5378294..e6339a0 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -101,11 +101,11 @@
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.net.module.util.PacketReader;
+import com.android.net.module.util.arp.ArpPacket;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
 import com.android.networkstack.apishim.SocketUtilsShimImpl;
 import com.android.networkstack.apishim.common.ShimUtils;
-import com.android.networkstack.arp.ArpPacket;
 import com.android.networkstack.metrics.IpProvisioningMetrics;
 import com.android.networkstack.util.NetworkStackUtils;
 
diff --git a/src/android/net/dhcp/DhcpResultsParcelableUtil.java b/src/android/net/dhcp/DhcpResultsParcelableUtil.java
index 7075925..3b97546 100644
--- a/src/android/net/dhcp/DhcpResultsParcelableUtil.java
+++ b/src/android/net/dhcp/DhcpResultsParcelableUtil.java
@@ -17,15 +17,12 @@
 package android.net.dhcp;
 
 import static android.net.shared.IpConfigurationParcelableUtil.parcelAddress;
-import static android.net.shared.IpConfigurationParcelableUtil.unparcelAddress;
 
 import android.net.DhcpResults;
 import android.net.DhcpResultsParcelable;
 
 import androidx.annotation.Nullable;
 
-import java.net.Inet4Address;
-
 /**
  * A utility class to convert DhcpResults to DhcpResultsParcelable.
  */
@@ -45,19 +42,4 @@
         p.captivePortalApiUrl = results.captivePortalApiUrl;
         return p;
     }
-
-    /**
-     * Convert a DhcpResultsParcelable to DhcpResults.
-     */
-    public static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
-        if (p == null) return null;
-        final DhcpResults results = new DhcpResults(p.baseConfiguration);
-        results.leaseDuration = p.leaseDuration;
-        results.mtu = p.mtu;
-        results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
-        results.vendorInfo = p.vendorInfo;
-        results.serverHostName = p.serverHostName;
-        results.captivePortalApiUrl = p.captivePortalApiUrl;
-        return results;
-    }
 }
diff --git a/src/android/net/dhcp6/Dhcp6Client.java b/src/android/net/dhcp6/Dhcp6Client.java
index d4b4a21..fa6b1bd 100644
--- a/src/android/net/dhcp6/Dhcp6Client.java
+++ b/src/android/net/dhcp6/Dhcp6Client.java
@@ -17,8 +17,8 @@
 package android.net.dhcp6;
 
 import static android.net.dhcp6.Dhcp6Packet.PrefixDelegation;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
 import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IFA_F_NODAD;
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 import static android.system.OsConstants.SOCK_DGRAM;
@@ -28,6 +28,7 @@
 import static com.android.net.module.util.NetworkStackConstants.DHCP6_CLIENT_PORT;
 import static com.android.net.module.util.NetworkStackConstants.DHCP6_SERVER_PORT;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ANY;
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
 import static com.android.networkstack.apishim.ConstantsShim.IFA_F_MANAGETEMPADDR;
 import static com.android.networkstack.apishim.ConstantsShim.IFA_F_NOPREFIXROUTE;
 import static com.android.networkstack.util.NetworkStackUtils.createInet6AddressFromEui64;
@@ -107,8 +108,11 @@
     private static final int FIRST_TIMEOUT_MS  =   1 * SECONDS;
     private static final int MAX_TIMEOUT_MS    = 512 * SECONDS;
 
+    // Per rfc8415#section-12, the IAID MUST be consistent across restarts.
+    // Since currently only one IAID is supported, a well-known value can be used (0).
+    private static final int IAID = 0;
+
     private int mTransId;
-    private int mIaId;
     private long mTransStartMillis;
     @Nullable private PrefixDelegation mAdvertise;
     @Nullable private PrefixDelegation mReply;
@@ -325,7 +329,7 @@
     }
 
     private ByteBuffer buildEmptyIaPdOption() {
-        return Dhcp6Packet.buildIaPdOption(mIaId, 0 /* t1 */, 0 /* t2 */, 0 /* preferred */,
+        return Dhcp6Packet.buildIaPdOption(IAID, 0 /* t1 */, 0 /* t2 */, 0 /* preferred */,
                 0 /* valid */, new byte[16] /* empty prefix */, (byte) RFC7421_PREFIX_LENGTH);
     }
 
@@ -398,19 +402,20 @@
         public void enter() {
             super.enter();
             startNewTransaction();
-            mIaId = mRandom.nextInt();
         }
 
+        @Override
         protected boolean sendPacket() {
             return sendSolicitPacket(buildEmptyIaPdOption());
         }
 
         // TODO: support multiple prefixes.
+        @Override
         protected void receivePacket(Dhcp6Packet packet) {
             if (!packet.isValid(mTransId, mClientDuid)) return;
             if (packet instanceof Dhcp6AdvertisePacket) {
                 mAdvertise = packet.mPrefixDelegation;
-                if (mAdvertise != null && mAdvertise.iaid == mIaId) {
+                if (mAdvertise != null && mAdvertise.iaid == IAID) {
                     Log.d(TAG, "Get prefix delegation option from Advertise: " + mAdvertise);
                     mServerDuid = packet.mServerDuid;
                     transitionTo(mRequestState);
@@ -422,7 +427,7 @@
                     return;
                 }
                 final PrefixDelegation pd = packet.mPrefixDelegation;
-                if (pd != null && pd.iaid == mIaId) {
+                if (pd != null && pd.iaid == IAID) {
                     Log.d(TAG, "Get prefix delegation option from RapidCommit Reply: " + pd);
                     mReply = pd;
                     mServerDuid = packet.mServerDuid;
@@ -437,15 +442,17 @@
      * process the Reply message in this state.
      */
     class RequestState extends PacketRetransmittingState {
+        @Override
         protected boolean sendPacket() {
             return sendRequestPacket(buildIaPdOption(mAdvertise));
         }
 
+        @Override
         protected void receivePacket(Dhcp6Packet packet) {
             if (!(packet instanceof Dhcp6ReplyPacket)) return;
             if (!packet.isValid(mTransId, mClientDuid)) return;
             final PrefixDelegation pd = packet.mPrefixDelegation;
-            if (pd != null && pd.iaid == mIaId) {
+            if (pd != null && pd.iaid == IAID) {
                 Log.d(TAG, "Get prefix delegation option from Reply: " + pd);
                 mReply = pd;
                 transitionTo(mBoundState);
@@ -515,7 +522,7 @@
             // time it enters BoundState.
             final Inet6Address address = createInet6AddressFromEui64(prefix,
                     mIface.macAddr.toByteArray());
-            final int flags = IFA_F_NOPREFIXROUTE | IFA_F_MANAGETEMPADDR;
+            final int flags = IFA_F_NOPREFIXROUTE | IFA_F_MANAGETEMPADDR | IFA_F_NODAD;
             final long now = SystemClock.elapsedRealtime();
             final long deprecationTime = now + mReply.ipo.preferred;
             final long expirationTime = now + mReply.ipo.valid;
@@ -556,12 +563,13 @@
             startNewTransaction();
         }
 
+        @Override
         protected void receivePacket(Dhcp6Packet packet) {
             if (!(packet instanceof Dhcp6ReplyPacket)) return;
             if (!packet.isValid(mTransId, mClientDuid)) return;
             final PrefixDelegation pd = packet.mPrefixDelegation;
             if (pd != null) {
-                if (pd.iaid != mIaId
+                if (pd.iaid != IAID
                         || !(Arrays.equals(pd.ipo.prefix, mReply.ipo.prefix)
                                 && pd.ipo.prefixLen == mReply.ipo.prefixLen)) {
                     Log.i(TAG, "Renewal prefix " + HexDump.toHexString(pd.ipo.prefix)
@@ -604,6 +612,7 @@
             }
         }
 
+        @Override
         protected boolean sendPacket() {
             return sendRenewPacket(buildIaPdOption(mReply));
         }
@@ -615,6 +624,7 @@
      * update other configuration parameters.
      */
     class RebindState extends ReacquireState {
+        @Override
         protected boolean sendPacket() {
             return sendRebindPacket(buildIaPdOption(mReply));
         }
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index c169ad5..42d177f 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -27,7 +27,6 @@
 import static android.net.ip.IIpClientCallbacks.DTIM_MULTIPLIER_RESET;
 import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE;
 import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
-import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
 import static android.net.util.SocketUtils.makePacketSocketAddress;
 import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
 import static android.system.OsConstants.AF_PACKET;
@@ -39,9 +38,9 @@
 import static com.android.net.module.util.NetworkStackConstants.ARP_REPLY;
 import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST;
+import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
 import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_IE_ID;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_DHCPV6_PREFIX_DELEGATION_VERSION;
-import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION;
 import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_MULTICAST_NS_VERSION;
@@ -116,6 +115,7 @@
 import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.SharedLog;
 import com.android.net.module.util.SocketUtils;
+import com.android.net.module.util.arp.ArpPacket;
 import com.android.net.module.util.ip.InterfaceController;
 import com.android.net.module.util.netlink.NetlinkUtils;
 import com.android.networkstack.R;
@@ -123,7 +123,6 @@
 import com.android.networkstack.apishim.SocketUtilsShimImpl;
 import com.android.networkstack.apishim.common.NetworkInformationShim;
 import com.android.networkstack.apishim.common.ShimUtils;
-import com.android.networkstack.arp.ArpPacket;
 import com.android.networkstack.metrics.IpProvisioningMetrics;
 import com.android.networkstack.metrics.NetworkQuirkMetrics;
 import com.android.networkstack.packets.NeighborAdvertisement;
@@ -474,6 +473,11 @@
 
     public static final String DUMP_ARG_CONFIRM = "confirm";
 
+    // Sysctl parameter strings.
+    private static final String ACCEPT_RA = "accept_ra";
+    private static final String ACCEPT_RA_DEFRTR = "accept_ra_defrtr";
+    private static final String DAD_TRANSMITS = "dad_transmits";
+
     // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
     private static final int CMD_TERMINATE_AFTER_STOP             = 1;
     private static final int CMD_STOP                             = 2;
@@ -664,7 +668,7 @@
     private long mStartTimeMillis;
     private long mIPv6ProvisioningDtimGracePeriodMillis;
     private MacAddress mCurrentBssid;
-    private boolean mHasDisabledIpv6OrAcceptRaOnProvLoss;
+    private boolean mHasDisabledAcceptRaDefrtrOnProvLoss;
     private Integer mDadTransmits = null;
     private int mMaxDtimMultiplier = DTIM_MULTIPLIER_RESET;
     private ApfCapabilities mCurrentApfCapabilities;
@@ -1061,11 +1065,6 @@
         return bssid;
     }
 
-    private boolean shouldDisableAcceptRaOnProvisioningLoss() {
-        return mDependencies.isFeatureEnabled(mContext, IPCLIENT_DISABLE_ACCEPT_RA_VERSION,
-                true /* defaultEnabled */);
-    }
-
     @Override
     protected void onQuitting() {
         mCallback.onQuit();
@@ -1442,39 +1441,26 @@
         return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
     }
 
-    private void setIpv6AcceptRa(int acceptRa) {
+    // Set "/proc/sys/net/ipv6/conf/${iface}/${name}" with the given specific value.
+    private void setIpv6Sysctl(@NonNull final String name, int value) {
         try {
-            mNetd.setProcSysNet(INetd.IPV6, INetd.CONF, mInterfaceParams.name, "accept_ra",
-                    Integer.toString(acceptRa));
+            mNetd.setProcSysNet(INetd.IPV6, INetd.CONF, mInterfaceParams.name,
+                    name, Integer.toString(value));
         } catch (Exception e) {
-            Log.e(mTag, "Failed to set accept_ra to " + acceptRa + ": " + e);
+            Log.e(mTag, "Failed to set " + name + " to  + " + value + ": " + e);
         }
     }
 
     private Integer getIpv6DadTransmits() {
         try {
             return Integer.parseUnsignedInt(mNetd.getProcSysNet(INetd.IPV6, INetd.CONF,
-                    mInterfaceName, "dad_transmits"));
+                    mInterfaceName, DAD_TRANSMITS));
         } catch (RemoteException | ServiceSpecificException e) {
             logError("Couldn't read dad_transmits on " + mInterfaceName, e);
             return null;
         }
     }
 
-    private void setIpv6DadTransmits(int dadTransmits) {
-        try {
-            mNetd.setProcSysNet(INetd.IPV6, INetd.CONF, mInterfaceParams.name,
-                    "dad_transmits", Integer.toString(dadTransmits));
-        } catch (Exception e) {
-            Log.e(mTag, "Failed to set dad_transmits to " + dadTransmits + ": " + e);
-        }
-    }
-
-    private void restartIpv6WithAcceptRaDisabled() {
-        mInterfaceCtrl.disableIPv6();
-        startIPv6(0 /* acceptRa */);
-    }
-
     // TODO: Investigate folding all this into the existing static function
     // LinkProperties.compareProvisioning() or some other single function that
     // takes two LinkProperties objects and returns a ProvisioningChange
@@ -1524,7 +1510,7 @@
         // Note that we can still be disconnected by IpReachabilityMonitor
         // if the IPv6 default gateway (but not the IPv6 DNS servers; see
         // accompanying code in IpReachabilityMonitor) is unreachable.
-        final boolean ignoreIPv6ProvisioningLoss = mHasDisabledIpv6OrAcceptRaOnProvLoss
+        final boolean ignoreIPv6ProvisioningLoss = mHasDisabledAcceptRaDefrtrOnProvLoss
                 || (mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
                         && !mCm.shouldAvoidBadWifi());
 
@@ -1552,31 +1538,27 @@
         if (oldLp.hasGlobalIpv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
             // Although link properties have lost IPv6 default route in this case, if IPv4 is still
             // working with appropriate routes and DNS servers, we can keep the current connection
-            // without disconnecting from the network, just disable IPv6 or accept_ra parameter on
-            // that given network until to the next provisioning.
+            // without disconnecting from the network, just disable accept_ra_defrtr sysctl on that
+            // given network until to the next provisioning.
             //
             // Disabling IPv6 stack will result in all IPv6 connectivity torn down and all IPv6
             // sockets being closed, the non-routable IPv6 DNS servers will be stripped out, so
             // applications will be able to reconnect immediately over IPv4. See b/131781810.
             //
-            // Sometimes disabling IPv6 stack might introduce other issues(see b/179222860),
-            // instead disabling accept_ra will result in only IPv4 provisioning and IPv6 link
-            // local address left on the interface, so applications will be able to reconnect
-            // immediately over IPv4 and keep IPv6 link-local capable.
+            // Sometimes disabling IPv6 stack can cause other problems(see b/179222860), conversely,
+            // disabling accept_ra_defrtr can still keep the interface IPv6 capable, but no longer
+            // learns the default router from incoming RA, partial IPv6 connectivity will remain on
+            // the interface, through which applications can still communicate locally.
             if (newLp.isIpv4Provisioned()) {
-                if (shouldDisableAcceptRaOnProvisioningLoss()) {
-                    restartIpv6WithAcceptRaDisabled();
-                } else {
-                    mInterfaceCtrl.disableIPv6();
-                }
+                // Restart ipv6 with accept_ra_defrtr set to 0.
+                mInterfaceCtrl.disableIPv6();
+                startIPv6(0 /* accept_ra_defrtr */);
+
                 mNetworkQuirkMetrics.setEvent(NetworkQuirkEvent.QE_IPV6_PROVISIONING_ROUTER_LOST);
                 mNetworkQuirkMetrics.statsWrite();
-                mHasDisabledIpv6OrAcceptRaOnProvLoss = true;
+                mHasDisabledAcceptRaDefrtrOnProvLoss = true;
                 delta = PROV_CHANGE_STILL_PROVISIONED;
-                mLog.log(shouldDisableAcceptRaOnProvisioningLoss()
-                        ? "Disabled accept_ra parameter "
-                        : "Disabled IPv6 stack completely "
-                        + "when the IPv6 default router has gone");
+                mLog.log("Disabled accept_ra_defrtr sysctl on loss of IPv6 default router");
             } else {
                 delta = PROV_CHANGE_LOST_PROVISIONING;
             }
@@ -2119,13 +2101,15 @@
                         == ProvisioningConfiguration.IPV6_ADDR_GEN_MODE_EUI64;
     }
 
-    private boolean startIPv6(int acceptRa) {
-        setIpv6AcceptRa(acceptRa);
+    private boolean startIPv6(int acceptRaDefrtr) {
+        setIpv6Sysctl(ACCEPT_RA,
+                mConfiguration.mIPv6ProvisioningMode == PROV_IPV6_LINKLOCAL ? 0 : 2);
+        setIpv6Sysctl(ACCEPT_RA_DEFRTR, acceptRaDefrtr);
         if (shouldDisableDad()) {
             final Integer dadTransmits = getIpv6DadTransmits();
             if (dadTransmits != null) {
                 mDadTransmits = dadTransmits;
-                setIpv6DadTransmits(0 /* dad_transmits */);
+                setIpv6Sysctl(DAD_TRANSMITS, 0 /* dad_transmits */);
             }
         }
         return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
@@ -2232,7 +2216,7 @@
     private void maybeRestoreDadTransmits() {
         if (mDadTransmits == null) return;
 
-        setIpv6DadTransmits(mDadTransmits);
+        setIpv6Sysctl(DAD_TRANSMITS, mDadTransmits);
         mDadTransmits = null;
     }
 
@@ -2326,7 +2310,7 @@
         @Override
         public void enter() {
             stopAllIP();
-            mHasDisabledIpv6OrAcceptRaOnProvLoss = false;
+            mHasDisabledAcceptRaDefrtrOnProvLoss = false;
             mGratuitousNaTargetAddresses.clear();
             mMulticastNsSourceAddresses.clear();
 
@@ -2713,9 +2697,7 @@
             mPacketTracker = createPacketTracker();
             if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
 
-            final int acceptRa =
-                    mConfiguration.mIPv6ProvisioningMode == PROV_IPV6_LINKLOCAL ? 0 : 2;
-            if (isIpv6Enabled() && !startIPv6(acceptRa)) {
+            if (isIpv6Enabled() && !startIPv6(1 /* acceptRaDefrtr */)) {
                 doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
                 enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6);
                 return;
@@ -2802,6 +2784,10 @@
         }
 
         private void clearIpv6PrefixDelegationAddresses() {
+            if (mPrefixDelegation == null) {
+                Log.wtf(mTag, "PrefixDelegation shouldn't be null when DHCPv6 PD fails.");
+                return;
+            }
             final IpPrefix prefix;
             try {
                 prefix = new IpPrefix(Inet6Address.getByAddress(mPrefixDelegation.ipo.prefix),
diff --git a/src/com/android/networkstack/arp/ArpPacket.java b/src/com/android/networkstack/arp/ArpPacket.java
deleted file mode 100644
index a25d7bf..0000000
--- a/src/com/android/networkstack/arp/ArpPacket.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.networkstack.arp;
-
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-
-import static com.android.net.module.util.NetworkStackConstants.ARP_ETHER_IPV4_LEN;
-import static com.android.net.module.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
-import static com.android.net.module.util.NetworkStackConstants.ARP_REPLY;
-import static com.android.net.module.util.NetworkStackConstants.ARP_REQUEST;
-import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN;
-import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_LEN;
-
-import android.net.MacAddress;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-
-/**
- * Defines basic data and operations needed to build and parse packets for the
- * ARP protocol.
- *
- * @hide
- */
-public class ArpPacket {
-    private static final String TAG = "ArpPacket";
-
-    public final short opCode;
-    public final Inet4Address senderIp;
-    public final Inet4Address targetIp;
-    public final MacAddress senderHwAddress;
-    public final MacAddress targetHwAddress;
-
-    ArpPacket(short opCode, MacAddress senderHwAddress, Inet4Address senderIp,
-            MacAddress targetHwAddress, Inet4Address targetIp) {
-        this.opCode = opCode;
-        this.senderHwAddress = senderHwAddress;
-        this.senderIp = senderIp;
-        this.targetHwAddress = targetHwAddress;
-        this.targetIp = targetIp;
-    }
-
-    /**
-     * Build an ARP packet from the required specified parameters.
-     */
-    @VisibleForTesting
-    public static ByteBuffer buildArpPacket(final byte[] dstMac, final byte[] srcMac,
-            final byte[] targetIp, final byte[] targetHwAddress, byte[] senderIp,
-            final short opCode) {
-        final ByteBuffer buf = ByteBuffer.allocate(ARP_ETHER_IPV4_LEN);
-
-        // Ether header
-        buf.put(dstMac);
-        buf.put(srcMac);
-        buf.putShort((short) ETH_P_ARP);
-
-        // ARP header
-        buf.putShort((short) ARP_HWTYPE_ETHER);  // hrd
-        buf.putShort((short) ETH_P_IP);          // pro
-        buf.put((byte) ETHER_ADDR_LEN);          // hln
-        buf.put((byte) IPV4_ADDR_LEN);           // pln
-        buf.putShort(opCode);                    // op
-        buf.put(srcMac);                         // sha
-        buf.put(senderIp);                       // spa
-        buf.put(targetHwAddress);                // tha
-        buf.put(targetIp);                       // tpa
-        buf.flip();
-        return buf;
-    }
-
-    /**
-     * Parse an ARP packet from an ByteBuffer object.
-     */
-    @VisibleForTesting
-    public static ArpPacket parseArpPacket(final byte[] recvbuf, final int length)
-            throws ParseException {
-        try {
-            if (length < ARP_ETHER_IPV4_LEN || recvbuf.length < length) {
-                throw new ParseException("Invalid packet length: " + length);
-            }
-
-            final ByteBuffer buffer = ByteBuffer.wrap(recvbuf, 0, length);
-            byte[] l2dst = new byte[ETHER_ADDR_LEN];
-            byte[] l2src = new byte[ETHER_ADDR_LEN];
-            buffer.get(l2dst);
-            buffer.get(l2src);
-
-            final short etherType = buffer.getShort();
-            if (etherType != ETH_P_ARP) {
-                throw new ParseException("Incorrect Ether Type: " + etherType);
-            }
-
-            final short hwType = buffer.getShort();
-            if (hwType != ARP_HWTYPE_ETHER) {
-                throw new ParseException("Incorrect HW Type: " + hwType);
-            }
-
-            final short protoType = buffer.getShort();
-            if (protoType != ETH_P_IP) {
-                throw new ParseException("Incorrect Protocol Type: " + protoType);
-            }
-
-            final byte hwAddrLength = buffer.get();
-            if (hwAddrLength != ETHER_ADDR_LEN) {
-                throw new ParseException("Incorrect HW address length: " + hwAddrLength);
-            }
-
-            final byte ipAddrLength = buffer.get();
-            if (ipAddrLength != IPV4_ADDR_LEN) {
-                throw new ParseException("Incorrect Protocol address length: " + ipAddrLength);
-            }
-
-            final short opCode = buffer.getShort();
-            if (opCode != ARP_REQUEST && opCode != ARP_REPLY) {
-                throw new ParseException("Incorrect opCode: " + opCode);
-            }
-
-            byte[] senderHwAddress = new byte[ETHER_ADDR_LEN];
-            byte[] senderIp = new byte[IPV4_ADDR_LEN];
-            buffer.get(senderHwAddress);
-            buffer.get(senderIp);
-
-            byte[] targetHwAddress = new byte[ETHER_ADDR_LEN];
-            byte[] targetIp = new byte[IPV4_ADDR_LEN];
-            buffer.get(targetHwAddress);
-            buffer.get(targetIp);
-
-            return new ArpPacket(opCode, MacAddress.fromBytes(senderHwAddress),
-                    (Inet4Address) InetAddress.getByAddress(senderIp),
-                    MacAddress.fromBytes(targetHwAddress),
-                    (Inet4Address) InetAddress.getByAddress(targetIp));
-        } catch (IndexOutOfBoundsException e) {
-            throw new ParseException("Invalid index when wrapping a byte array into a buffer");
-        } catch (BufferUnderflowException e) {
-            throw new ParseException("Invalid buffer position");
-        } catch (IllegalArgumentException e) {
-            throw new ParseException("Invalid MAC address representation");
-        } catch (UnknownHostException e) {
-            throw new ParseException("Invalid IP address of Host");
-        }
-    }
-
-    /**
-     * Thrown when parsing ARP packet failed.
-     */
-    public static class ParseException extends Exception {
-        ParseException(String message) {
-            super(message);
-        }
-    }
-}
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java
index 8fb157c..fe60cdd 100755
--- a/src/com/android/networkstack/util/NetworkStackUtils.java
+++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -248,12 +248,6 @@
             "ipclient_accept_ipv6_link_local_dns_version";
 
     /**
-     * Experiment flag to disable accept_ra parameter when IPv6 provisioning loss happens due to
-     * the default route has gone.
-     */
-    public static final String IPCLIENT_DISABLE_ACCEPT_RA_VERSION = "ipclient_disable_accept_ra";
-
-    /**
      * Experiment flag to enable "mcast_resolicit" neighbor parameter in IpReachabilityMonitor,
      * set it to 3 by default.
      */
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
index 6f30d4c..39eb727 100644
--- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -36,7 +36,6 @@
 import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
 import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
 import static android.net.dhcp.DhcpPacket.MIN_V6ONLY_WAIT_MS;
-import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
 import static android.net.ip.IIpClientCallbacks.DTIM_MULTIPLIER_RESET;
 import static android.net.ip.IpClient.CONFIG_IPV6_AUTOCONF_TIMEOUT;
 import static android.net.ip.IpClientLinkObserver.CLAT_PREFIX;
@@ -69,7 +68,6 @@
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ANY;
-import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN;
 import static com.android.net.module.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
 import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE;
 import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER;
@@ -120,7 +118,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
-import android.net.DhcpResults;
 import android.net.DhcpResultsParcelable;
 import android.net.INetd;
 import android.net.InetAddresses;
@@ -172,7 +169,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.stats.connectivity.NetworkQuirkEvent;
 import android.stats.connectivity.NudEventType;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -189,6 +185,7 @@
 import com.android.net.module.util.PacketBuilder;
 import com.android.net.module.util.SharedLog;
 import com.android.net.module.util.Struct;
+import com.android.net.module.util.arp.ArpPacket;
 import com.android.net.module.util.ip.IpNeighborMonitor;
 import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer;
 import com.android.net.module.util.netlink.NetlinkUtils;
@@ -202,7 +199,6 @@
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
 import com.android.networkstack.apishim.ConstantsShim;
 import com.android.networkstack.apishim.common.ShimUtils;
-import com.android.networkstack.arp.ArpPacket;
 import com.android.networkstack.ipmemorystore.IpMemoryStoreService;
 import com.android.networkstack.metrics.IpProvisioningMetrics;
 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics;
@@ -2859,14 +2855,14 @@
         ArgumentCaptor<DhcpResultsParcelable> captor =
                 ArgumentCaptor.forClass(DhcpResultsParcelable.class);
         verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(captor.capture());
-        DhcpResults lease = fromStableParcelable(captor.getValue());
+        final DhcpResultsParcelable lease = captor.getValue();
         assertNotNull(lease);
-        assertEquals(lease.getIpAddress().getAddress(), CLIENT_ADDR);
-        assertEquals(lease.getGateway(), SERVER_ADDR);
-        assertEquals(1, lease.getDnsServers().size());
-        assertTrue(lease.getDnsServers().contains(SERVER_ADDR));
-        assertEquals(lease.getServerAddress(), SERVER_ADDR);
-        assertEquals(lease.getMtu(), TEST_DEFAULT_MTU);
+        assertEquals(CLIENT_ADDR, lease.baseConfiguration.getIpAddress().getAddress());
+        assertEquals(SERVER_ADDR, lease.baseConfiguration.getGateway());
+        assertEquals(1, lease.baseConfiguration.getDnsServers().size());
+        assertTrue(lease.baseConfiguration.getDnsServers().contains(SERVER_ADDR));
+        assertEquals(SERVER_ADDR, InetAddresses.parseNumericAddress(lease.serverAddress));
+        assertEquals(TEST_DEFAULT_MTU, lease.mtu);
 
         if (expectMetered) {
             assertEquals(lease.vendorInfo, DhcpPacket.VENDOR_INFO_ANDROID_METERED);
@@ -3010,7 +3006,7 @@
             ArgumentCaptor<DhcpResultsParcelable> resultsCaptor =
                     ArgumentCaptor.forClass(DhcpResultsParcelable.class);
             verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(resultsCaptor.capture());
-            DhcpResults lease = fromStableParcelable(resultsCaptor.getValue());
+            final DhcpResultsParcelable lease = resultsCaptor.getValue();
             assertNull(lease);
 
             // DhcpClient rolls back to StoppedState instead of INIT state after calling
@@ -3110,13 +3106,11 @@
         return lp;
     }
 
-    private void doDualStackProvisioning(boolean shouldDisableAcceptRa) throws Exception {
+    private void doDualStackProvisioning() throws Exception {
         final ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                 .withoutIpReachabilityMonitor()
                 .build();
 
-        setFeatureEnabled(NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION,
-                shouldDisableAcceptRa);
         // Enable rapid commit to accelerate DHCP handshake to shorten test duration,
         // not strictly necessary.
         setDhcpFeatures(false /* isDhcpLeaseCacheEnabled */, true /* isRapidCommitEnabled */,
@@ -3131,37 +3125,6 @@
         performDualStackProvisioning();
     }
 
-    @Test @SignatureRequiredTest(reason = "signature perms are required due to mocked callabck")
-    public void testIgnoreIpv6ProvisioningLoss_disableIPv6Stack() throws Exception {
-        doDualStackProvisioning(false /* shouldDisableAcceptRa */);
-
-        final CompletableFuture<LinkProperties> lpFuture = new CompletableFuture<>();
-
-        // Send RA with 0-lifetime and wait until all IPv6-related default route and DNS servers
-        // have been removed, then verify if there is IPv4-only info left in the LinkProperties.
-        sendRouterAdvertisementWithZeroRouterLifetime();
-        verify(mCb, timeout(TEST_TIMEOUT_MS).atLeastOnce()).onLinkPropertiesChange(
-                argThat(x -> {
-                    final boolean isOnlyIPv4Provisioned = (x.getLinkAddresses().size() == 1
-                            && x.getDnsServers().size() == 1
-                            && x.getAddresses().get(0) instanceof Inet4Address
-                            && x.getDnsServers().get(0) instanceof Inet4Address);
-
-                    if (!isOnlyIPv4Provisioned) return false;
-                    lpFuture.complete(x);
-                    return true;
-                }));
-        final LinkProperties lp = lpFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        assertNotNull(lp);
-        assertEquals(lp.getAddresses().get(0), CLIENT_ADDR);
-        assertEquals(lp.getDnsServers().get(0), SERVER_ADDR);
-
-        final ArgumentCaptor<Integer> quirkEvent = ArgumentCaptor.forClass(Integer.class);
-        verify(mNetworkQuirkMetricsDeps, timeout(TEST_TIMEOUT_MS)).writeStats(quirkEvent.capture());
-        assertEquals((long) quirkEvent.getValue(),
-                (long) NetworkQuirkEvent.QE_IPV6_PROVISIONING_ROUTER_LOST.ordinal());
-    }
-
     private boolean hasRouteTo(@NonNull final LinkProperties lp, @NonNull final String prefix) {
         return hasRouteTo(lp, prefix, RTN_UNICAST);
     }
@@ -3185,9 +3148,9 @@
         return false;
     }
 
-    @Test @SignatureRequiredTest(reason = "signature perms are required due to mocked callabck")
-    public void testIgnoreIpv6ProvisioningLoss_disableAcceptRa() throws Exception {
-        doDualStackProvisioning(true /* shouldDisableAcceptRa */);
+    @Test
+    public void testIgnoreIpv6ProvisioningLoss_disableAcceptRaDefrtr() throws Exception {
+        doDualStackProvisioning();
 
         final CompletableFuture<LinkProperties> lpFuture = new CompletableFuture<>();
 
@@ -3220,16 +3183,23 @@
         assertTrue(hasRouteTo(lp, IPV4_ANY_ADDRESS_PREFIX)); // IPv4 default route
         assertTrue(lp.getAddresses().get(1).isLinkLocalAddress());
 
-        reset(mCb);
+        clearInvocations(mCb);
 
-        // Send an RA to verify that global IPv6 addresses won't be configured on the interface.
+        // Send an RA to verify that device gains the IPv6 provisioning without default route and
+        // off-link DNS server.
         sendBasicRouterAdvertisement(false /* waitForRs */);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(0)).onLinkPropertiesChange(any());
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(argThat(
+                x -> x.hasGlobalIpv6Address()
+                        // IPv4, IPv6 link local, privacy and stable privacy
+                        && x.getLinkAddresses().size() == 4
+                        && !x.hasIpv6DefaultRoute()
+                        && x.getDnsServers().size() == 1
+                        && x.getDnsServers().get(0).equals(SERVER_ADDR)));
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDualStackProvisioning() throws Exception {
-        doDualStackProvisioning(false /* shouldDisableAcceptRa */);
+        doDualStackProvisioning();
 
         verify(mCb, never()).onProvisioningFailure(any());
     }
@@ -3450,7 +3420,7 @@
     public void testNoFdLeaks() throws Exception {
         // Shut down and restart IpClient once to ensure that any fds that are opened the first
         // time it runs do not cause the test to fail.
-        doDualStackProvisioning(false /* shouldDisableAcceptRa */);
+        doDualStackProvisioning();
         shutdownAndRecreateIpClient();
 
         // Unfortunately we cannot use a large number of iterations as it would make the test run
@@ -3458,7 +3428,7 @@
         final int iterations = 10;
         final int before = getNumOpenFds();
         for (int i = 0; i < iterations; i++) {
-            doDualStackProvisioning(false /* shouldDisableAcceptRa */);
+            doDualStackProvisioning();
             shutdownAndRecreateIpClient();
             // The last time this loop runs, mIpc will be shut down in tearDown.
         }
@@ -4347,6 +4317,25 @@
     }
 
     @Test
+    public void testIPv6LinkLocalOnly_verifyAcceptRaDefrtr() throws Exception {
+        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+                .withoutIPv4()
+                .withIpv6LinkLocalOnly()
+                .withRandomMacAddress()
+                .build();
+        startIpClientProvisioning(config);
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningSuccess(any());
+
+        clearInvocations(mCb);
+
+        // accept_ra is set to 0 and accept_ra_defrtr is set to 1 in IPv6 link-local only mode,
+        // send another RA to tap interface, to verify that we should not see any IPv6 provisioning
+        // although accept_ra_defrtr is set to 1.
+        sendBasicRouterAdvertisement(false /* waitForRs */);
+        verify(mCb, never()).onLinkPropertiesChange(argThat(x -> x.isIpv6Provisioned()));
+    }
+
+    @Test
     public void testIPv6LinkLocalOnlyAndThenGlobal() throws Exception {
         ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                 .withoutIPv4()
@@ -4639,7 +4628,7 @@
     }
 
     private void runDualStackNetworkDtimMultiplierSetting(final InOrder inOrder) throws Exception {
-        doDualStackProvisioning(false /* shouldDisableAcceptRa */);
+        doDualStackProvisioning();
         inOrder.verify(mCb).setMaxDtimMultiplier(
                 IpClient.DEFAULT_BEFORE_IPV6_PROV_MAX_DTIM_MULTIPLIER);
         inOrder.verify(mCb, timeout(TEST_TIMEOUT_MS)).setMaxDtimMultiplier(
@@ -4678,7 +4667,7 @@
         verify(mCb, after(10).never()).setMaxDtimMultiplier(
                 IpClient.DEFAULT_MULTICAST_LOCK_MAX_DTIM_MULTIPLIER);
 
-        doDualStackProvisioning(false /* shouldDisableAcceptRa */);
+        doDualStackProvisioning();
         verify(mCb, times(1)).setMaxDtimMultiplier(
                 IpClient.DEFAULT_MULTICAST_LOCK_MAX_DTIM_MULTIPLIER);
     }
diff --git a/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
index bff1088..3bba529 100644
--- a/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
+++ b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
@@ -58,7 +58,7 @@
             return networkStackVersion == 300000000L || networkStackVersion >= 301100000L
         }
 
-        private fun getNetworkStackComponent(connectorAction: String): ComponentName {
+        private fun getNetworkStackComponent(connectorAction: String?): ComponentName {
             val connectorIntent = Intent(connectorAction)
             return connectorIntent.resolveSystemService(context.packageManager, MATCH_SYSTEM_ONLY)
                     ?: fail("TestNetworkStackService not found")
diff --git a/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt b/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt
index 0f860a8..8b1b046 100644
--- a/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt
+++ b/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt
@@ -98,7 +98,7 @@
     private val packetBridge = runAsShell(MANAGE_TEST_NETWORKS) {
         PacketBridge(context, INTERNAL_V6ADDR, EXTERNAL_V6ADDR, REMOTE_V6ADDR.address)
     }
-    private val cm = context.getSystemService(ConnectivityManager::class.java)
+    private val cm = context.getSystemService(ConnectivityManager::class.java)!!
 
     // Set up DNS server for testing server and DNS64.
     private val fakeDns = TestDnsServer(
@@ -129,7 +129,7 @@
     // network stats being counted, which can only be achieved when they are marked as TYPE_TEST.
     // If the tethering module does not support TYPE_TEST stats, then these tests will need
     // to be skipped.
-    fun shouldRunTests() = cm.getNetworkInfo(packetBridge.internalNetwork).type == TYPE_TEST
+    fun shouldRunTests() = cm.getNetworkInfo(packetBridge.internalNetwork)!!.type == TYPE_TEST
 
     @After
     fun tearDown() {
@@ -139,7 +139,7 @@
     }
 
     private fun waitFor464XlatReady(network: Network): String {
-        val iface = cm.getLinkProperties(network).interfaceName
+        val iface = cm.getLinkProperties(network)!!.interfaceName!!
 
         // Make a network request to listen to the specific test network.
         val nr = NetworkRequest.Builder()
@@ -152,14 +152,14 @@
 
         // Wait for the stacked address to be available.
         testCb.eventuallyExpect<LinkPropertiesChanged> {
-            it.lp.stackedLinks?.getOrNull(0)?.linkAddresses?.getOrNull(0) != null
+            it.lp.stackedLinks.getOrNull(0)?.linkAddresses?.getOrNull(0) != null
         }
 
         return iface
     }
 
     private val Network.mtu: Int get() {
-        val lp = cm.getLinkProperties(this)
+        val lp = cm.getLinkProperties(this)!!
         val mtuStacked = if (lp.stackedLinks[0]?.mtu != 0) lp.stackedLinks[0].mtu else DEFAULT_MTU
         val mtuInterface = if (lp.mtu != 0) lp.mtu else DEFAULT_MTU
         return mtuInterface.coerceAtMost(mtuStacked)
@@ -408,7 +408,7 @@
             tag: Int,
             queryApi: (nsm: NetworkStatsManager, template: NetworkTemplate) -> NetworkStats
         ): BareStats {
-            val nsm = context.getSystemService(NetworkStatsManager::class.java)
+            val nsm = context.getSystemService(NetworkStatsManager::class.java)!!
             nsm.forceUpdate()
             val testTemplate = NetworkTemplate.Builder(MATCH_TEST)
                 .setWifiNetworkKeys(setOf(iface)).build()
diff --git a/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java b/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
index 5e160ad..2810301 100644
--- a/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
@@ -17,8 +17,8 @@
 package android.net.dhcp;
 
 import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
 import static android.net.dhcp.DhcpResultsParcelableUtil.toStableParcelable;
+import static android.net.shared.IpConfigurationParcelableUtil.unparcelAddress;
 
 import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
 
@@ -26,9 +26,12 @@
 import static org.junit.Assert.assertTrue;
 
 import android.net.DhcpResults;
+import android.net.DhcpResultsParcelable;
 import android.net.LinkAddress;
 import android.net.shared.IpConfigurationParcelableUtil;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -65,63 +68,90 @@
     }
 
     @Test
-    public void testParcelUnparcelDhcpResults() {
-        doDhcpResultsParcelUnparcelTest();
+    public void testParcelDhcpResults() {
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullIpAddress() {
         mDhcpResults.ipAddress = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullGateway() {
         mDhcpResults.gateway = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullDomains() {
         mDhcpResults.domains = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_EmptyDomains() {
         mDhcpResults.domains = "";
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullServerAddress() {
         mDhcpResults.serverAddress = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullVendorInfo() {
         mDhcpResults.vendorInfo = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullServerHostName() {
         mDhcpResults.serverHostName = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
     @Test
     public void testParcelUnparcelDhcpResults_NullCaptivePortalApiUrl() {
         mDhcpResults.captivePortalApiUrl = null;
-        doDhcpResultsParcelUnparcelTest();
+        doDhcpResultsParcelTest();
     }
 
-    private void doDhcpResultsParcelUnparcelTest() {
+    private void doDhcpResultsParcelTest() {
         final DhcpResults unparceled = fromStableParcelable(toStableParcelable(mDhcpResults));
+        setFieldsLostWhileParceling(unparceled);
         assertEquals(mDhcpResults, unparceled);
     }
 
+    private static void setFieldsLostWhileParceling(@NonNull DhcpResults unparceledResults) {
+        // TODO: add other fields that are not part of DhcpResultsParcelable here
+        // e.g. if the dmnsrchList field is added,
+        // parceledResults.dmnsrchList.addAll(mDhcpResults.dmnSrchList);
+    }
+
+    /**
+     * Convert a DhcpResultsParcelable to DhcpResults.
+     */
+    private static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
+        if (p == null) return null;
+        final DhcpResults results = new DhcpResults(p.baseConfiguration);
+        results.leaseDuration = p.leaseDuration;
+        results.mtu = p.mtu;
+        results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
+        results.vendorInfo = p.vendorInfo;
+        results.serverHostName = p.serverHostName;
+        results.captivePortalApiUrl = p.captivePortalApiUrl;
+        // DhcpResultsParcelable is only used to fill the legacy DhcpInfo class in Wifi, so it
+        // should not be extended with any new field. Some fields maybe part of DhcpResults, but
+        // not DhcpResultsParcelable, as DhcpResults is used internally in NetworkStack, but
+        // DhcpResultsParcelable is used to provide info to wifi (for building DhcpInfo)
+
+        return results;
+    }
+
     @Test
     public void testToString() {
         final String str = toStableParcelable(mDhcpResults).toString();
diff --git a/tests/unit/src/com/android/networkstack/arp/ArpPacketTest.java b/tests/unit/src/com/android/networkstack/arp/ArpPacketTest.java
deleted file mode 100644
index dd7ba6a..0000000
--- a/tests/unit/src/com/android/networkstack/arp/ArpPacketTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.networkstack.arp;
-
-import static com.android.net.module.util.NetworkStackConstants.ARP_REQUEST;
-import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN;
-import static com.android.testutils.MiscAsserts.assertThrows;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import android.net.InetAddresses;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpPacket;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class ArpPacketTest {
-
-    private static final Inet4Address TEST_IPV4_ADDR =
-            (Inet4Address) InetAddresses.parseNumericAddress("192.168.1.2");
-    private static final Inet4Address INADDR_ANY =
-            (Inet4Address) InetAddresses.parseNumericAddress("0.0.0.0");
-    private static final byte[] TEST_SENDER_MAC_ADDR = new byte[] {
-            0x00, 0x1a, 0x11, 0x22, 0x33, 0x33 };
-    private static final byte[] TEST_TARGET_MAC_ADDR = new byte[] {
-            0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    private static final byte[] TEST_ARP_PROBE = new byte[] {
-        // dst mac address
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        // src mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // ether type
-        (byte) 0x08, (byte) 0x06,
-        // hardware type
-        (byte) 0x00, (byte) 0x01,
-        // protocol type
-        (byte) 0x08, (byte) 0x00,
-        // hardware address size
-        (byte) 0x06,
-        // protocol address size
-        (byte) 0x04,
-        // opcode
-        (byte) 0x00, (byte) 0x01,
-        // sender mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // sender IP address
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        // target mac address
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        // target IP address
-        (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02,
-    };
-
-    private static final byte[] TEST_ARP_ANNOUNCE = new byte[] {
-        // dst mac address
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        // src mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // ether type
-        (byte) 0x08, (byte) 0x06,
-        // hardware type
-        (byte) 0x00, (byte) 0x01,
-        // protocol type
-        (byte) 0x08, (byte) 0x00,
-        // hardware address size
-        (byte) 0x06,
-        // protocol address size
-        (byte) 0x04,
-        // opcode
-        (byte) 0x00, (byte) 0x01,
-        // sender mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // sender IP address
-        (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02,
-        // target mac address
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        // target IP address
-        (byte) 0xc0, (byte) 0xa8, (byte) 0x01, (byte) 0x02,
-    };
-
-    private static final byte[] TEST_ARP_PROBE_TRUNCATED = new byte[] {
-        // dst mac address
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        // src mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // ether type
-        (byte) 0x08, (byte) 0x06,
-        // hardware type
-        (byte) 0x00, (byte) 0x01,
-        // protocol type
-        (byte) 0x08, (byte) 0x00,
-        // hardware address size
-        (byte) 0x06,
-        // protocol address size
-        (byte) 0x04,
-        // opcode
-        (byte) 0x00,
-    };
-
-    private static final byte[] TEST_ARP_PROBE_TRUNCATED_MAC = new byte[] {
-         // dst mac address
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        // src mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x33,
-        // ether type
-        (byte) 0x08, (byte) 0x06,
-        // hardware type
-        (byte) 0x00, (byte) 0x01,
-        // protocol type
-        (byte) 0x08, (byte) 0x00,
-        // hardware address size
-        (byte) 0x06,
-        // protocol address size
-        (byte) 0x04,
-        // opcode
-        (byte) 0x00, (byte) 0x01,
-        // sender mac address
-        (byte) 0x00, (byte) 0x1a, (byte) 0x11, (byte) 0x22, (byte) 0x33,
-    };
-
-    @Test
-    public void testBuildArpProbePacket() throws Exception {
-        final ByteBuffer arpProbe = ArpPacket.buildArpPacket(DhcpPacket.ETHER_BROADCAST,
-                TEST_SENDER_MAC_ADDR, TEST_IPV4_ADDR.getAddress(), new byte[ETHER_ADDR_LEN],
-                INADDR_ANY.getAddress(), (short) ARP_REQUEST);
-        assertArrayEquals(arpProbe.array(), TEST_ARP_PROBE);
-    }
-
-    @Test
-    public void testBuildArpAnnouncePacket() throws Exception {
-        final ByteBuffer arpAnnounce = ArpPacket.buildArpPacket(DhcpPacket.ETHER_BROADCAST,
-                TEST_SENDER_MAC_ADDR, TEST_IPV4_ADDR.getAddress(), new byte[ETHER_ADDR_LEN],
-                TEST_IPV4_ADDR.getAddress(), (short) ARP_REQUEST);
-        assertArrayEquals(arpAnnounce.array(), TEST_ARP_ANNOUNCE);
-    }
-
-    @Test
-    public void testParseArpProbePacket() throws Exception {
-        final ArpPacket packet = ArpPacket.parseArpPacket(TEST_ARP_PROBE, TEST_ARP_PROBE.length);
-        assertEquals(packet.opCode, ARP_REQUEST);
-        assertEquals(packet.senderHwAddress, MacAddress.fromBytes(TEST_SENDER_MAC_ADDR));
-        assertEquals(packet.targetHwAddress, MacAddress.fromBytes(TEST_TARGET_MAC_ADDR));
-        assertEquals(packet.senderIp, INADDR_ANY);
-        assertEquals(packet.targetIp, TEST_IPV4_ADDR);
-    }
-
-    @Test
-    public void testParseArpAnnouncePacket() throws Exception {
-        final ArpPacket packet = ArpPacket.parseArpPacket(TEST_ARP_ANNOUNCE,
-                TEST_ARP_ANNOUNCE.length);
-        assertEquals(packet.opCode, ARP_REQUEST);
-        assertEquals(packet.senderHwAddress, MacAddress.fromBytes(TEST_SENDER_MAC_ADDR));
-        assertEquals(packet.targetHwAddress, MacAddress.fromBytes(TEST_TARGET_MAC_ADDR));
-        assertEquals(packet.senderIp, TEST_IPV4_ADDR);
-        assertEquals(packet.targetIp, TEST_IPV4_ADDR);
-    }
-
-    @Test
-    public void testParseArpPacket_invalidByteBufferParameters() throws Exception {
-        assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket(
-                TEST_ARP_PROBE, 0));
-    }
-
-    @Test
-    public void testParseArpPacket_truncatedPacket() throws Exception {
-        assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket(
-                TEST_ARP_PROBE_TRUNCATED, TEST_ARP_PROBE_TRUNCATED.length));
-    }
-
-    @Test
-    public void testParseArpPacket_truncatedMacAddress() throws Exception {
-        assertThrows(ArpPacket.ParseException.class, () -> ArpPacket.parseArpPacket(
-                TEST_ARP_PROBE_TRUNCATED_MAC, TEST_ARP_PROBE_TRUNCATED.length));
-    }
-}
diff --git a/tests/unit/src/com/android/networkstack/netlink/TcpInfoTest.java b/tests/unit/src/com/android/networkstack/netlink/TcpInfoTest.java
index ddab8c7..c362044 100644
--- a/tests/unit/src/com/android/networkstack/netlink/TcpInfoTest.java
+++ b/tests/unit/src/com/android/networkstack/netlink/TcpInfoTest.java
@@ -17,6 +17,8 @@
 package com.android.networkstack.netlink;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -27,6 +29,7 @@
 import org.junit.runner.RunWith;
 
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -49,38 +52,38 @@
             "07" +                // option = TCPI_OPT_WSCALE|TCPI_OPT_SACK|TCPI_OPT_TIMESTAMPS
             "88" +                // wscale = 8
             "00" +                // delivery_rate_app_limited = 0
-            "001B914A" +          // rto = 1806666
+            "4A911B00" +          // rto = 1806666
             "00000000" +          // ato = 0
-            "0000052E" +          // sndMss = 1326
-            "00000218" +          // rcvMss = 536
+            "2E050000" +          // sndMss = 1326
+            "18020000" +          // rcvMss = 536
             "00000000" +          // unsacked = 0
             "00000000" +          // acked = 0
             "00000000" +          // lost = 0
             "00000000" +          // retrans = 0
             "00000000" +          // fackets = 0
-            "000000BB" +          // lastDataSent = 187
+            "BB000000" +          // lastDataSent = 187
             "00000000" +          // lastAckSent = 0
-            "000000BB" +          // lastDataRecv = 187
-            "000000BB" +          // lastDataAckRecv = 187
-            "000005DC" +          // pmtu = 1500
-            "00015630" +          // rcvSsthresh = 87600
-            "00092C3E" +          // rttt = 601150
-            "0004961F" +          // rttvar = 300575
-            "00000578" +          // sndSsthresh = 1400
-            "0000000A" +          // sndCwnd = 10
-            "000005A8" +          // advmss = 1448
-            "00000003" +          // reordering = 3
+            "BB000000" +          // lastDataRecv = 187
+            "BB00000000" +          // lastDataAckRecv = 187
+            "DC0500" +          // pmtu = 1500
+            "30560100" +          // rcvSsthresh = 87600
+            "3E2C0900" +          // rttt = 601150
+            "1F960400" +          // rttvar = 300575
+            "78050000" +          // sndSsthresh = 1400
+            "0A000000" +          // sndCwnd = 10
+            "A8050000" +          // advmss = 1448
+            "02000000" +          // reordering = 3
             "00000000" +          // rcvrtt = 0
-            "00015630" +          // rcvspace = 87600
+            "30560100" +          // rcvspace = 87600
             "00000000" +          // totalRetrans = 0
-            "000000000000AC53" +  // pacingRate = 44115
+            "53AC000000000000" +  // pacingRate = 44115
             "FFFFFFFFFFFFFFFF" +  // maxPacingRate = 18446744073709551615
-            "0000000000000001" +  // bytesAcked = 1
+            "0100000000000001" +  // bytesAcked = 1
             "0000000000000000" +  // bytesReceived = 0
-            "00000002" +          // SegsOut = 2
-            "00000001" +          // SegsIn = 1
+            "02000000" +          // SegsOut = 2
+            "01000000" +          // SegsIn = 1
             "00000000" +          // NotSentBytes = 0
-            "00092C3E" +          // minRtt = 601150
+            "3E2C0900" +          // minRtt = 601150
             "00000000" +          // DataSegsIn = 0
             "00000000" +          // DataSegsOut = 0
             "0000000000000000" +  // deliverRate = 0
@@ -102,21 +105,29 @@
     @Test
     public void testParseTcpInfo() {
         final ByteBuffer buffer = ByteBuffer.wrap(TCP_INFO_BYTES);
+        // Android is always little-endian. Refer to https://developer.android.com/ndk/guides/abis.
+        buffer.order(ByteOrder.nativeOrder());
         // Length is less than required
-        final TcpInfo nullInfo = TcpInfo.parse(buffer, SHORT_TEST_TCP_INFO);
-        assertEquals(nullInfo, null);
+        assertNull(TcpInfo.parse(buffer, SHORT_TEST_TCP_INFO));
+        assertEquals(TEST_TCPINFO, TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1));
 
-        final TcpInfo parsedInfo = TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1);
-        assertEquals(parsedInfo, TEST_TCPINFO);
+        // Make a data that TcpInfo is not started from the beginning of the buffer.
+        final ByteBuffer buffer2 = ByteBuffer.wrap(TCP_INFO_BYTES);
+        buffer2.order(ByteOrder.nativeOrder());
+        // Move to certain position.
+        buffer2.position(2);
+        // Parsing is started in an incorrect position. This results in a failed parsing.
+        assertNotEquals(TEST_TCPINFO, TcpInfo.parse(buffer2, TCP_INFO_LENGTH_V1));
 
-        // Make a data that TcpInfo is not started from the begining of the buffer.
-        final ByteBuffer bufferWithHeader =
+        // Make a TcpInfo with extra tcp info fields. Parsing is only performed with
+        // TCP_INFO_LENGTH_V1 length. Result is the same as parsing with TCP_INFO_BYTES.
+        final ByteBuffer bufferExtraInfo =
                 ByteBuffer.allocate(EXPANDED_TCP_INFO_BYTES.length + TCP_INFO_BYTES.length);
-        bufferWithHeader.put(EXPANDED_TCP_INFO_BYTES);
-        bufferWithHeader.put(TCP_INFO_BYTES);
-        final TcpInfo infoWithHeader = TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1);
-        bufferWithHeader.position(EXPANDED_TCP_INFO_BYTES.length);
-        assertEquals(parsedInfo, TEST_TCPINFO);
+        bufferExtraInfo.order(ByteOrder.nativeOrder());
+        bufferExtraInfo.put(TCP_INFO_BYTES);
+        bufferExtraInfo.put(EXPANDED_TCP_INFO_BYTES);
+        bufferExtraInfo.position(0);
+        assertEquals(TEST_TCPINFO, TcpInfo.parse(bufferExtraInfo, TCP_INFO_LENGTH_V1));
     }
 
     @Test
@@ -130,25 +141,27 @@
     @Test
     public void testParseTcpInfoExpanded() {
         final ByteBuffer buffer = ByteBuffer.wrap(EXPANDED_TCP_INFO_BYTES);
+        // Android is always little-endian. Refer to https://developer.android.com/ndk/guides/abis.
+        buffer.order(ByteOrder.nativeOrder());
         final TcpInfo parsedInfo =
                 TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1 + EXPANDED_TCP_INFO_LENGTH);
 
-        assertEquals(parsedInfo, TEST_TCPINFO);
+        assertEquals(TEST_TCPINFO, parsedInfo);
         assertEquals(buffer.limit(), buffer.position());
 
         // reset the index.
         buffer.position(0);
         final TcpInfo parsedInfoShorterLen = TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1);
-        assertEquals(parsedInfoShorterLen, TEST_TCPINFO);
+        assertEquals(TEST_TCPINFO, parsedInfoShorterLen);
         assertEquals(TCP_INFO_LENGTH_V1, buffer.position());
     }
 
     @Test
     public void testTcpStateName() {
-        assertEquals(TcpInfo.getTcpStateName(4), TCP_FIN_WAIT1);
-        assertEquals(TcpInfo.getTcpStateName(1), TCP_ESTABLISHED);
-        assertEquals(TcpInfo.getTcpStateName(2), TCP_SYN_SENT);
-        assertEquals(TcpInfo.getTcpStateName(20), UNKNOWN_20);
+        assertEquals(TCP_FIN_WAIT1, TcpInfo.getTcpStateName(4));
+        assertEquals(TCP_ESTABLISHED, TcpInfo.getTcpStateName(1));
+        assertEquals(TCP_SYN_SENT, TcpInfo.getTcpStateName(2));
+        assertEquals(UNKNOWN_20, TcpInfo.getTcpStateName(20));
     }
 
     private static final String MALFORMED_TCP_INFO_HEX =
@@ -166,12 +179,8 @@
     @Test
     public void testMalformedTcpInfo() {
         final ByteBuffer buffer = ByteBuffer.wrap(MALFORMED_TCP_INFO_BYTES);
-
-        TcpInfo parsedInfo = TcpInfo.parse(buffer, SHORT_TEST_TCP_INFO);
-        assertEquals(parsedInfo, null);
-
-        parsedInfo = TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1);
-        assertEquals(parsedInfo, null);
+        assertNull(TcpInfo.parse(buffer, SHORT_TEST_TCP_INFO));
+        assertNull(TcpInfo.parse(buffer, TCP_INFO_LENGTH_V1));
     }
 
     // Make a TcpInfo contains only first 8 bytes.
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index 4cf6f34..cd948b3 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -76,6 +76,7 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.after;
@@ -550,8 +551,8 @@
                     return null;
             }
         }).when(mCleartextDnsNetwork).openConnection(any());
-        doReturn(new ArrayMap<>()).when(mHttpConnection).getRequestProperties();
-        doReturn(new ArrayMap<>()).when(mHttpsConnection).getRequestProperties();
+        initHttpConnection(mHttpConnection);
+        initHttpConnection(mHttpsConnection);
 
         mFakeDns = new FakeDns();
         mFakeDns.startMocking();
@@ -608,6 +609,18 @@
         }
     }
 
+    private void initHttpConnection(HttpURLConnection connection) {
+        doReturn(new ArrayMap<>()).when(connection).getRequestProperties();
+        // Explicitly set the HttpURLConnection methods so that these will not interact with real
+        // methods to prevent threading issue in the test.
+        doReturn(new HashMap<>()).when(connection).getHeaderFields();
+        doNothing().when(connection).setInstanceFollowRedirects(anyBoolean());
+        doNothing().when(connection).setConnectTimeout(anyInt());
+        doNothing().when(connection).setReadTimeout(anyInt());
+        doNothing().when(connection).setRequestProperty(any(), any());
+        doNothing().when(connection).setUseCaches(anyBoolean());
+    }
+
     private void initCallbacks(int interfaceVersion) throws Exception {
         try {
             doReturn(interfaceVersion).when(mCallbacks).getInterfaceVersion();