Merge changes from topic "conn_t_move_tmdev" into tm-dev

* changes:
  Use Sources.bp for building
  Merge history of ConnectivityT
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index e4e2151..ddac19d 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -30,10 +30,10 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreferences(@NonNull android.os.UserHandle, @NonNull java.util.List<android.net.ProfileNetworkPreference>, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setUidFirewallRule(int, int, int);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
     method public void systemReady();
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateFirewallRule(int, int, boolean);
     field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
     field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
     field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
@@ -54,6 +54,9 @@
     field public static final int FIREWALL_CHAIN_POWERSAVE = 3; // 0x3
     field public static final int FIREWALL_CHAIN_RESTRICTED = 4; // 0x4
     field public static final int FIREWALL_CHAIN_STANDBY = 2; // 0x2
+    field public static final int FIREWALL_RULE_ALLOW = 1; // 0x1
+    field public static final int FIREWALL_RULE_DEFAULT = 0; // 0x0
+    field public static final int FIREWALL_RULE_DENY = 2; // 0x2
     field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0
     field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
     field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK = 2; // 0x2
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 53d485d..7a57426 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -104,12 +104,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.DscpPolicy> CREATOR;
     field public static final int PROTOCOL_ANY = -1; // 0xffffffff
     field public static final int SOURCE_PORT_ANY = -1; // 0xffffffff
-    field public static final int STATUS_DELETED = 4; // 0x4
-    field public static final int STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3; // 0x3
-    field public static final int STATUS_POLICY_NOT_FOUND = 5; // 0x5
-    field public static final int STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2; // 0x2
-    field public static final int STATUS_REQUEST_DECLINED = 1; // 0x1
-    field public static final int STATUS_SUCCESS = 0; // 0x0
   }
 
   public static final class DscpPolicy.Builder {
@@ -236,7 +230,6 @@
   public abstract class NetworkAgent {
     ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
     ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkScore, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
-    method public void destroyAndAwaitReplacement(@IntRange(from=0, to=0x1388) int);
     method @Nullable public android.net.Network getNetwork();
     method public void markConnected();
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
@@ -271,6 +264,13 @@
     method public void setTeardownDelayMillis(@IntRange(from=0, to=0x1388) int);
     method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
     method public void unregister();
+    method public void unregisterAfterReplacement(@IntRange(from=0, to=0x1388) int);
+    field public static final int DSCP_POLICY_STATUS_DELETED = 4; // 0x4
+    field public static final int DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3; // 0x3
+    field public static final int DSCP_POLICY_STATUS_POLICY_NOT_FOUND = 5; // 0x5
+    field public static final int DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2; // 0x2
+    field public static final int DSCP_POLICY_STATUS_REQUEST_DECLINED = 1; // 0x1
+    field public static final int DSCP_POLICY_STATUS_SUCCESS = 0; // 0x0
     field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
     field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
   }
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index a798f6e..e25a855 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -995,6 +995,36 @@
     // LINT.ThenChange(packages/modules/Connectivity/service/native/include/Common.h)
 
     /**
+     * Specify default rule which may allow or drop packets depending on existing policy.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int FIREWALL_RULE_DEFAULT = 0;
+
+    /**
+     * Specify allow rule which allows packets.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int FIREWALL_RULE_ALLOW = 1;
+
+    /**
+     * Specify deny rule which drops packets.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int FIREWALL_RULE_DENY = 2;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = false, prefix = "FIREWALL_RULE_", value = {
+        FIREWALL_RULE_DEFAULT,
+        FIREWALL_RULE_ALLOW,
+        FIREWALL_RULE_DENY
+    })
+    public @interface FirewallRule {}
+
+    /**
      * A kludge to facilitate static access where a Context pointer isn't available, like in the
      * case of the static set/getProcessDefaultNetwork methods and from the Network class.
      * TODO: Remove this after deprecating the static methods in favor of non-static methods or
@@ -5802,8 +5832,9 @@
      *
      * @param chain target chain.
      * @param uid uid to allow/deny.
-     * @param allow whether networking is allowed or denied.
+     * @param rule firewall rule to allow/drop packets.
      * @throws IllegalStateException if updating firewall rule failed.
+     * @throws IllegalArgumentException if {@code rule} is not a valid rule.
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
@@ -5812,10 +5843,10 @@
             android.Manifest.permission.NETWORK_STACK,
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
     })
-    public void updateFirewallRule(@FirewallChain final int chain, final int uid,
-            final boolean allow) {
+    public void setUidFirewallRule(@FirewallChain final int chain, final int uid,
+            @FirewallRule final int rule) {
         try {
-            mService.updateFirewallRule(chain, uid, allow);
+            mService.setUidFirewallRule(chain, uid, rule);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/framework/src/android/net/DscpPolicy.java b/framework/src/android/net/DscpPolicy.java
index cda8205..6af795b 100644
--- a/framework/src/android/net/DscpPolicy.java
+++ b/framework/src/android/net/DscpPolicy.java
@@ -16,7 +16,6 @@
 
 package android.net;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -26,8 +25,6 @@
 
 import com.android.net.module.util.InetAddressUtils;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.Objects;
@@ -49,36 +46,6 @@
      */
     public static final int SOURCE_PORT_ANY = -1;
 
-    /**
-     * Policy was successfully added.
-     */
-    public static final int STATUS_SUCCESS = 0;
-
-    /**
-     * Policy was rejected for any reason besides invalid classifier or insufficient resources.
-     */
-    public static final int STATUS_REQUEST_DECLINED = 1;
-
-    /**
-     * Requested policy contained a classifier which is not supported.
-     */
-    public static final int STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2;
-
-    /**
-     * TODO: should this error case be supported?
-     */
-    public static final int STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3;
-
-    /**
-     * Policy was deleted.
-     */
-    public static final int STATUS_DELETED = 4;
-
-    /**
-     * Policy was not found during deletion.
-     */
-    public static final int STATUS_POLICY_NOT_FOUND = 5;
-
     /** The unique policy ID. Each requesting network is responsible for maintaining policy IDs
      * unique within that network. In the case where a policy with an existing ID is created, the
      * new policy will update the existing policy with the same ID.
@@ -112,17 +79,6 @@
         return 0;
     }
 
-    /** @hide */
-    @IntDef(prefix = "STATUS_", value = {
-        STATUS_SUCCESS,
-        STATUS_REQUEST_DECLINED,
-        STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED,
-        STATUS_INSUFFICIENT_PROCESSING_RESOURCES,
-        STATUS_DELETED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DscpPolicyStatus {}
-
     /* package */ DscpPolicy(
             int policyId,
             int dscp,
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index 0988bf3..bc73769 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -240,7 +240,7 @@
 
     void updateMeteredNetworkDenyList(int uid, boolean add);
 
-    void updateFirewallRule(int chain, int uid, boolean allow);
+    void setUidFirewallRule(int chain, int uid, int rule);
 
     void setFirewallChainEnabled(int chain, boolean enable);
 
diff --git a/framework/src/android/net/INetworkAgentRegistry.aidl b/framework/src/android/net/INetworkAgentRegistry.aidl
index 2b22a5c..b375b7b 100644
--- a/framework/src/android/net/INetworkAgentRegistry.aidl
+++ b/framework/src/android/net/INetworkAgentRegistry.aidl
@@ -47,5 +47,5 @@
     void sendAddDscpPolicy(in DscpPolicy policy);
     void sendRemoveDscpPolicy(int policyId);
     void sendRemoveAllDscpPolicies();
-    void sendDestroyAndAwaitReplacement(int timeoutMillis);
+    void sendUnregisterAfterReplacement(int timeoutMillis);
 }
diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java
index fdc9081..29add1c 100644
--- a/framework/src/android/net/NetworkAgent.java
+++ b/framework/src/android/net/NetworkAgent.java
@@ -25,7 +25,6 @@
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-import android.net.DscpPolicy.DscpPolicyStatus;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ConditionVariable;
@@ -435,12 +434,54 @@
     public static final int CMD_DSCP_POLICY_STATUS = BASE + 28;
 
     /**
+     * DSCP policy was successfully added.
+     */
+    public static final int DSCP_POLICY_STATUS_SUCCESS = 0;
+
+    /**
+     * DSCP policy was rejected for any reason besides invalid classifier or insufficient resources.
+     */
+    public static final int DSCP_POLICY_STATUS_REQUEST_DECLINED = 1;
+
+    /**
+     * Requested DSCP policy contained a classifier which is not supported.
+     */
+    public static final int DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2;
+
+    /**
+     * Requested DSCP policy was not added due to insufficient processing resources.
+     */
+    // TODO: should this error case be supported?
+    public static final int DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3;
+
+    /**
+     * DSCP policy was deleted.
+     */
+    public static final int DSCP_POLICY_STATUS_DELETED = 4;
+
+    /**
+     * DSCP policy was not found during deletion.
+     */
+    public static final int DSCP_POLICY_STATUS_POLICY_NOT_FOUND = 5;
+
+    /** @hide */
+    @IntDef(prefix = "DSCP_POLICY_STATUS_", value = {
+        DSCP_POLICY_STATUS_SUCCESS,
+        DSCP_POLICY_STATUS_REQUEST_DECLINED,
+        DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED,
+        DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES,
+        DSCP_POLICY_STATUS_DELETED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DscpPolicyStatus {}
+
+    /**
      * Sent by the NetworkAgent to ConnectivityService to notify that this network is expected to be
      * replaced within the specified time by a similar network.
      * arg1 = timeout in milliseconds
      * @hide
      */
-    public static final int EVENT_DESTROY_AND_AWAIT_REPLACEMENT = BASE + 29;
+    public static final int EVENT_UNREGISTER_AFTER_REPLACEMENT = BASE + 29;
 
     private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
         final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
@@ -984,9 +1025,9 @@
      * @param timeoutMillis the timeout after which this network will be unregistered even if
      *                      {@link #unregister} was not called.
      */
-    public void destroyAndAwaitReplacement(
+    public void unregisterAfterReplacement(
             @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int timeoutMillis) {
-        queueOrSendMessage(reg -> reg.sendDestroyAndAwaitReplacement(timeoutMillis));
+        queueOrSendMessage(reg -> reg.sendUnregisterAfterReplacement(timeoutMillis));
     }
 
     /**
diff --git a/nearby/framework/java/android/nearby/FastPairDevice.java b/nearby/framework/java/android/nearby/FastPairDevice.java
index e12b4f8..7160533 100644
--- a/nearby/framework/java/android/nearby/FastPairDevice.java
+++ b/nearby/framework/java/android/nearby/FastPairDevice.java
@@ -48,6 +48,7 @@
                 builder.addMedium(in.readInt());
             }
             builder.setRssi(in.readInt());
+            builder.setTxPower(in.readInt());
             if (in.readInt() == 1) {
                 builder.setModelId(in.readString());
             }
@@ -67,6 +68,10 @@
         }
     };
 
+    // The transmit power in dBm. Valid range is [-127, 126]. a
+    // See android.bluetooth.le.ScanResult#getTxPower
+    private int mTxPower;
+
     // Some OEM devices devices don't have model Id.
     @Nullable private final String mModelId;
 
@@ -82,6 +87,7 @@
      * @param name Name of the FastPairDevice. Can be {@code null} if there is no name.
      * @param mediums The {@link Medium}s over which the device is discovered.
      * @param rssi The received signal strength in dBm.
+     * @param txPower The transmit power in dBm. Valid range is [-127, 126].
      * @param modelId The identifier of the Fast Pair device.
      *                Can be {@code null} if there is no Model ID.
      * @param bluetoothAddress The hardware address of this BluetoothDevice.
@@ -90,16 +96,28 @@
     public FastPairDevice(@Nullable String name,
             List<Integer> mediums,
             int rssi,
+            int txPower,
             @Nullable String modelId,
             @NonNull String bluetoothAddress,
             @Nullable byte[] data) {
         super(name, mediums, rssi);
+        this.mTxPower = txPower;
         this.mModelId = modelId;
         this.mBluetoothAddress = bluetoothAddress;
         this.mData = data;
     }
 
     /**
+     * Gets the transmit power in dBm. A value of
+     * android.bluetooth.le.ScanResult#TX_POWER_NOT_PRESENT
+     * indicates that the TX power is not present.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
      * Gets the identifier of the Fast Pair device. Can be {@code null} if there is no Model ID.
      */
     @Nullable
@@ -149,6 +167,7 @@
             stringBuilder.append(mediumToString(medium));
         }
         stringBuilder.append("} rssi=").append(getRssi());
+        stringBuilder.append(" txPower=").append(mTxPower);
         stringBuilder.append(" modelId=").append(mModelId);
         stringBuilder.append(" bluetoothAddress=").append(mBluetoothAddress);
         stringBuilder.append("]");
@@ -162,7 +181,8 @@
             if (!super.equals(other)) {
                 return false;
             }
-            return Objects.equals(mModelId, otherDevice.mModelId)
+            return  mTxPower == otherDevice.mTxPower
+                    && Objects.equals(mModelId, otherDevice.mModelId)
                     && Objects.equals(mBluetoothAddress, otherDevice.mBluetoothAddress)
                     && Arrays.equals(mData, otherDevice.mData);
         }
@@ -172,7 +192,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(
-                getName(), getMediums(), getRssi(), mModelId, mBluetoothAddress,
+                getName(), getMediums(), getRssi(), mTxPower, mModelId, mBluetoothAddress,
                 Arrays.hashCode(mData));
     }
 
@@ -189,6 +209,7 @@
             dest.writeInt(medium);
         }
         dest.writeInt(getRssi());
+        dest.writeInt(mTxPower);
         dest.writeInt(mModelId == null ? 0 : 1);
         if (mModelId != null) {
             dest.writeString(mModelId);
@@ -211,6 +232,7 @@
 
         @Nullable private String mName;
         private int mRssi;
+        private int mTxPower;
         @Nullable private String mModelId;
         private String mBluetoothAddress;
         @Nullable private byte[] mData;
@@ -253,6 +275,17 @@
         }
 
         /**
+         * Sets the txPower.
+         *
+         * @param txPower The transmit power in dBm
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
          * Sets the model Id of this Fast Pair device.
          *
          * @param modelId The identifier of the Fast Pair device. Can be {@code null}
@@ -292,7 +325,7 @@
          */
         @NonNull
         public FastPairDevice build() {
-            return new FastPairDevice(mName, mMediums, mRssi, mModelId,
+            return new FastPairDevice(mName, mMediums, mRssi, mTxPower, mModelId,
                     mBluetoothAddress, mData);
         }
     }
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
index f137de4..694e15b 100644
--- a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -54,6 +55,7 @@
                     }
                     builder.setMedium(in.readInt());
                     builder.setRssi(in.readInt());
+                    builder.setTxPower(in.readInt());
                     if (in.readInt() == 1) {
                         builder.setFastPairModelId(in.readString());
                     }
@@ -81,6 +83,7 @@
     @NearbyDevice.Medium
     private final int mMedium;
     private final int mRssi;
+    private final int mTxPower;
 
     @Nullable
     private final String mBluetoothAddress;
@@ -90,12 +93,13 @@
     private final byte[] mData;
 
     private NearbyDeviceParcelable(@ScanRequest.ScanType int scanType, @Nullable String name,
-            int medium, int rssi, @Nullable String fastPairModelId,
+            int medium, int rssi, int txPower, @Nullable String fastPairModelId,
             @Nullable String bluetoothAddress, @Nullable byte[] data) {
         mScanType = scanType;
         mName = name;
         mMedium = medium;
         mRssi = rssi;
+        mTxPower = txPower;
         mFastPairModelId = fastPairModelId;
         mBluetoothAddress = bluetoothAddress;
         mData = data;
@@ -124,6 +128,7 @@
         }
         dest.writeInt(mMedium);
         dest.writeInt(mRssi);
+        dest.writeInt(mTxPower);
         dest.writeInt(mFastPairModelId == null ? 0 : 1);
         if (mFastPairModelId != null) {
             dest.writeString(mFastPairModelId);
@@ -148,6 +153,7 @@
                 + "name=" + mName
                 + ", medium=" + NearbyDevice.mediumToString(mMedium)
                 + ", rssi=" + mRssi
+                + ", txPower=" + mTxPower
                 + ", bluetoothAddress=" + mBluetoothAddress
                 + ", fastPairModelId=" + mFastPairModelId
                 + ", data=" + Arrays.toString(mData)
@@ -161,6 +167,7 @@
             return  Objects.equals(mName, otherNearbyDeviceParcelable.mName)
                     && (mMedium == otherNearbyDeviceParcelable.mMedium)
                     && (mRssi == otherNearbyDeviceParcelable.mRssi)
+                    && (mTxPower == otherNearbyDeviceParcelable.mTxPower)
                     && (Objects.equals(
                             mBluetoothAddress, otherNearbyDeviceParcelable.mBluetoothAddress))
                     && (Objects.equals(
@@ -173,7 +180,8 @@
     @Override
     public int hashCode() {
         return Objects.hash(
-                mName, mMedium, mRssi, mBluetoothAddress, mFastPairModelId, Arrays.hashCode(mData));
+                mName, mMedium, mRssi, mTxPower, mBluetoothAddress,
+                mFastPairModelId, Arrays.hashCode(mData));
     }
 
     /**
@@ -212,6 +220,16 @@
     }
 
     /**
+     * Gets the transmit power in dBm. A value of
+     * android.bluetooth.le.ScanResult#TX_POWER_NOT_PRESENT
+     * indicates that the TX power is not present.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
      * Gets the Fast Pair identifier. Returns {@code null} if there is no Model ID or this is not a
      * Fast Pair device.
      */
@@ -246,6 +264,7 @@
         @NearbyDevice.Medium
         private int mMedium;
         private int mRssi;
+        private int mTxPower = ScanResult.TX_POWER_NOT_PRESENT;
         @ScanRequest.ScanType int mScanType;
         @Nullable
         private String mFastPairModelId;
@@ -292,12 +311,23 @@
          * @param rssi The received signal strength in dBm.
          */
         @NonNull
-        public Builder setRssi(int rssi) {
+        public Builder setRssi(@IntRange(from = -127, to = 126) int rssi) {
             mRssi = rssi;
             return this;
         }
 
         /**
+         * Sets the txPower.
+         *
+         * @param txPower The transmit power in dBm
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
          * Sets the Fast Pair model Id.
          *
          * @param fastPairModelId Fast Pair device identifier.
@@ -336,8 +366,8 @@
          */
         @NonNull
         public NearbyDeviceParcelable build() {
-            return new NearbyDeviceParcelable(mScanType, mName, mMedium, mRssi, mFastPairModelId,
-                    mBluetoothAddress, mData);
+            return new NearbyDeviceParcelable(mScanType, mName, mMedium, mRssi, mTxPower,
+                    mFastPairModelId, mBluetoothAddress, mData);
         }
     }
 }
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
index 4cb2cc8..1c1d59f 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -104,6 +104,7 @@
                     .setName(nearbyDeviceParcelable.getName())
                     .addMedium(nearbyDeviceParcelable.getMedium())
                     .setRssi(nearbyDeviceParcelable.getRssi())
+                    .setTxPower(nearbyDeviceParcelable.getTxPower())
                     .setModelId(nearbyDeviceParcelable.getFastPairModelId())
                     .setBluetoothAddress(nearbyDeviceParcelable.getBluetoothAddress())
                     .setData(nearbyDeviceParcelable.getData()).build();
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
index a989143..db58476 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
@@ -64,6 +64,7 @@
                     NearbyDeviceParcelable.Builder builder = new NearbyDeviceParcelable.Builder();
                     builder.setMedium(NearbyDevice.Medium.BLE)
                             .setRssi(scanResult.getRssi())
+                            .setTxPower(scanResult.getTxPower())
                             .setBluetoothAddress(scanResult.getDevice().getAddress());
 
                     ScanRecord record = scanResult.getScanRecord();
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
index 82e6615..87fc4cd 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -50,6 +50,7 @@
                 .setName("testDevice")
                 .setMedium(NearbyDevice.Medium.BLE)
                 .setRssi(RSSI)
+                .setTxPower(-90)
                 .setFastPairModelId(FAST_PAIR_MODEL_ID)
                 .setBluetoothAddress(BLUETOOTH_ADDRESS)
                 .setData(SCAN_DATA);
@@ -64,7 +65,7 @@
                 mBuilder.setFastPairModelId(null).setData(null).build();
 
         assertThat(nearbyDeviceParcelable.toString()).isEqualTo(
-                "NearbyDeviceParcelable[name=testDevice, medium=BLE, rssi=-60, "
+                "NearbyDeviceParcelable[name=testDevice, medium=BLE, rssi=-60, txPower=-90, "
                         + "bluetoothAddress="
                         + BLUETOOTH_ADDRESS + ", fastPairModelId=null, data=null]");
     }
@@ -72,7 +73,7 @@
     @Test
     @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void test_defaultNullFields() {
-        NearbyDeviceParcelable nearbyDeviceParcelable =  new NearbyDeviceParcelable.Builder()
+        NearbyDeviceParcelable nearbyDeviceParcelable = new NearbyDeviceParcelable.Builder()
                 .setMedium(NearbyDevice.Medium.BLE)
                 .setRssi(RSSI)
                 .build();
diff --git a/nearby/tests/multidevices/clients/Android.bp b/nearby/tests/multidevices/clients/Android.bp
index 579baa5..49bc2e9 100644
--- a/nearby/tests/multidevices/clients/Android.bp
+++ b/nearby/tests/multidevices/clients/Android.bp
@@ -40,7 +40,7 @@
     static_libs: ["NearbyMultiDevicesClientsLib"],
     optimize: {
         enabled: true,
-        shrink: true,
+        shrink: false,
         proguard_flags_files: ["proguard.flags"],
     },
 }
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt
index 39edfe4..4a8a772 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorSnippet.kt
@@ -18,6 +18,8 @@
 
 import android.annotation.TargetApi
 import android.content.Context
+import android.nearby.multidevices.fastpair.provider.controller.FastPairProviderSimulatorController
+import android.nearby.multidevices.fastpair.provider.events.ProviderStatusEvents
 import android.os.Build
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.android.mobly.snippet.Snippet
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/ProviderStatusEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/ProviderStatusEvents.kt
deleted file mode 100644
index efa4f02..0000000
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/ProviderStatusEvents.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2022 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.nearby.multidevices.fastpair.provider
-
-import com.google.android.mobly.snippet.util.postSnippetEvent
-
-/** The Mobly snippet events to report to the Python side. */
-class ProviderStatusEvents(private val callbackId: String) :
-  FastPairProviderSimulatorController.EventListener {
-
-  /** Reports the first onServiceConnected of A2DP sink profile. */
-  override fun onA2DPSinkProfileConnected() {
-    postSnippetEvent(callbackId, "onA2DPSinkProfileConnected") {}
-  }
-
-  /**
-   * Indicates the Bluetooth scan mode of the Fast Pair provider simulator has changed.
-   *
-   * @param mode the current scan mode in String mapping by [FastPairSimulator#scanModeToString].
-   */
-  override fun onScanModeChange(mode: String) {
-    postSnippetEvent(callbackId, "onScanModeChange") { putString("mode", mode) }
-  }
-
-  /**
-   * Indicates the advertising state of the Fast Pair provider simulator has changed.
-   *
-   * @param isAdvertising the current advertising state, true if advertising otherwise false.
-   */
-  override fun onAdvertisingChange(isAdvertising: Boolean) {
-    postSnippetEvent(callbackId, "onAdvertisingChange") {
-      putBoolean("isAdvertising", isAdvertising)
-    }
-  }
-}
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorController.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt
similarity index 98%
rename from nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorController.kt
rename to nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt
index e700144..b591ae0 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/FastPairProviderSimulatorController.kt
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/controller/FastPairProviderSimulatorController.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.nearby.multidevices.fastpair.provider
+package android.nearby.multidevices.fastpair.provider.controller
 
 import android.bluetooth.le.AdvertiseSettings
 import android.content.Context
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt
new file mode 100644
index 0000000..2addd77
--- /dev/null
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/provider/events/ProviderStatusEvents.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 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.nearby.multidevices.fastpair.provider.events
+
+import android.nearby.multidevices.fastpair.provider.controller.FastPairProviderSimulatorController
+import com.google.android.mobly.snippet.util.postSnippetEvent
+
+/** The Mobly snippet events to report to the Python side. */
+class ProviderStatusEvents(private val callbackId: String) :
+    FastPairProviderSimulatorController.EventListener {
+
+    /** Reports the first onServiceConnected of A2DP sink profile. */
+    override fun onA2DPSinkProfileConnected() {
+        postSnippetEvent(callbackId, "onA2DPSinkProfileConnected") {}
+    }
+
+    /**
+     * Indicates the Bluetooth scan mode of the Fast Pair provider simulator has changed.
+     *
+     * @param mode the current scan mode in String mapping by [FastPairSimulator#scanModeToString].
+     */
+    override fun onScanModeChange(mode: String) {
+        postSnippetEvent(callbackId, "onScanModeChange") { putString("mode", mode) }
+    }
+
+    /**
+     * Indicates the advertising state of the Fast Pair provider simulator has changed.
+     *
+     * @param isAdvertising the current advertising state, true if advertising otherwise false.
+     */
+    override fun onAdvertisingChange(isAdvertising: Boolean) {
+        postSnippetEvent(callbackId, "onAdvertisingChange") {
+            putBoolean("isAdvertising", isAdvertising)
+        }
+    }
+}
\ No newline at end of file
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt
index 617eac1..65856d8 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/FastPairSeekerSnippet.kt
@@ -23,6 +23,7 @@
 import android.nearby.ScanRequest
 import android.nearby.fastpair.seeker.FAKE_TEST_ACCOUNT_NAME
 import android.nearby.multidevices.fastpair.seeker.data.FastPairTestDataManager
+import android.nearby.multidevices.fastpair.seeker.events.ScanCallbackEvents
 import android.nearby.multidevices.fastpair.seeker.ui.CheckNearbyHalfSheetUiTest
 import android.nearby.multidevices.fastpair.seeker.ui.DismissNearbyHalfSheetUiTest
 import androidx.test.core.app.ApplicationProvider
@@ -39,12 +40,12 @@
     private lateinit var scanCallback: ScanCallback
 
     /**
-     * Starts scanning as a Fast Pair seeker to find Fast Pair provider devices.
+     * Starts scanning as a Fast Pair seeker to find provider devices.
      *
      * @param callbackId the callback ID corresponding to the {@link FastPairSeekerSnippet#startScan}
      * call that started the scanning.
      */
-    @AsyncRpc(description = "Starts scanning as Fast Pair seeker to find Fast Pair provider devices.")
+    @AsyncRpc(description = "Starts scanning as Fast Pair seeker to find provider devices.")
     fun startScan(callbackId: String) {
         val scanRequest = ScanRequest.Builder()
             .setScanMode(ScanRequest.SCAN_MODE_LOW_LATENCY)
@@ -97,7 +98,10 @@
      * @param modelId a string of model id to be associated with.
      * @param json a string of FastPairAntispoofKeyDeviceMetadata JSON object.
      */
-    @Rpc(description = "Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.")
+    @Rpc(
+        description =
+        "Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache."
+    )
     fun putAntispoofKeyDeviceMetadata(modelId: String, json: String) {
         Log.i("Puts a model id to FastPairAntispoofKeyDeviceMetadata pair into test data cache.")
         fastPairTestDataManager.sendAntispoofKeyDeviceMetadata(modelId, json)
diff --git a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ScanCallbackEvents.kt b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt
similarity index 95%
rename from nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ScanCallbackEvents.kt
rename to nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt
index 5385238..363355f 100644
--- a/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/ScanCallbackEvents.kt
+++ b/nearby/tests/multidevices/clients/src/android/nearby/multidevices/fastpair/seeker/events/ScanCallbackEvents.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.nearby.multidevices.fastpair.seeker
+package android.nearby.multidevices.fastpair.seeker.events
 
 import android.nearby.NearbyDevice
 import android.nearby.ScanCallback
diff --git a/nearby/tests/multidevices/host/AndroidTest.xml b/nearby/tests/multidevices/host/AndroidTest.xml
index 9453647..a5f6839 100644
--- a/nearby/tests/multidevices/host/AndroidTest.xml
+++ b/nearby/tests/multidevices/host/AndroidTest.xml
@@ -32,6 +32,7 @@
         </target_preparer>
         <target_preparer class="com.android.tradefed.targetprep.PythonVirtualenvPreparer">
           <!-- Any python dependencies can be specified and will be installed with pip -->
+          <!-- TODO(b/225958696): Import python dependencies -->
           <option name="dep-module" value="mobly" />
           <option name="dep-module" value="retry" />
         </target_preparer>
diff --git a/nearby/tests/multidevices/host/seeker_discover_provider_test.py b/nearby/tests/multidevices/host/seeker_discover_provider_test.py
index c82812a..6356595 100644
--- a/nearby/tests/multidevices/host/seeker_discover_provider_test.py
+++ b/nearby/tests/multidevices/host/seeker_discover_provider_test.py
@@ -14,14 +14,8 @@
 
 """CTS-V Nearby Mainline Fast Pair end-to-end test case: seeker can discover the provider."""
 
-from typing import List
-
-from mobly import base_test
-from mobly.controllers import android_device
-
 from test_helper import constants
-from test_helper import fast_pair_provider_simulator
-from test_helper import fast_pair_seeker
+from test_helper import fast_pair_base_test
 
 # The model ID to simulate on provider side.
 PROVIDER_SIMULATOR_MODEL_ID = constants.DEFAULT_MODEL_ID
@@ -29,37 +23,16 @@
 PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY = constants.DEFAULT_ANTI_SPOOFING_KEY
 
 # Time in seconds for events waiting.
-SETUP_TIMEOUT_SEC = constants.SETUP_TIMEOUT_SEC
 BECOME_DISCOVERABLE_TIMEOUT_SEC = constants.BECOME_DISCOVERABLE_TIMEOUT_SEC
 START_ADVERTISING_TIMEOUT_SEC = constants.START_ADVERTISING_TIMEOUT_SEC
 SCAN_TIMEOUT_SEC = constants.SCAN_TIMEOUT_SEC
 
-# Abbreviations for common use type.
-FastPairProviderSimulator = fast_pair_provider_simulator.FastPairProviderSimulator
-FastPairSeeker = fast_pair_seeker.FastPairSeeker
 
-
-class SeekerDiscoverProviderTest(base_test.BaseTestClass):
+class SeekerDiscoverProviderTest(fast_pair_base_test.FastPairBaseTest):
     """Fast Pair seeker discover provider test."""
 
-    _duts: List[android_device.AndroidDevice]
-    _provider: FastPairProviderSimulator
-    _seeker: FastPairSeeker
-
-    def setup_class(self) -> None:
-        super().setup_class()
-        self._duts = self.register_controller(android_device)
-
-        # Assume the 1st phone is provider, the 2nd is seeker.
-        provider_ad, seeker_ad = self._duts
-        self._provider = FastPairProviderSimulator(provider_ad)
-        self._seeker = FastPairSeeker(seeker_ad)
-        self._provider.load_snippet()
-        self._seeker.load_snippet()
-
     def setup_test(self) -> None:
         super().setup_test()
-        self._provider.setup_provider_simulator(SETUP_TIMEOUT_SEC)
         self._provider.start_model_id_advertising(
             PROVIDER_SIMULATOR_MODEL_ID, PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY)
         self._provider.wait_for_discoverable_mode(BECOME_DISCOVERABLE_TIMEOUT_SEC)
@@ -67,12 +40,9 @@
         self._seeker.start_scan()
 
     def teardown_test(self) -> None:
-        super().teardown_test()
         self._seeker.stop_scan()
         self._provider.teardown_provider_simulator()
-        # Create per-test excepts of logcat.
-        for dut in self._duts:
-            dut.services.create_output_excerpts_all(self.current_test_info)
+        super().teardown_test()
 
     def test_seeker_start_scanning_find_provider(self) -> None:
         provider_ble_mac_address = self._provider.get_ble_mac_address()
diff --git a/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py b/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py
index 07079ae..f6561e5 100644
--- a/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py
+++ b/nearby/tests/multidevices/host/seeker_show_halfsheet_test.py
@@ -14,14 +14,8 @@
 
 """CTS-V Nearby Mainline Fast Pair end-to-end test case: seeker show half sheet UI."""
 
-from typing import List
-
-from mobly import base_test
-from mobly.controllers import android_device
-
 from test_helper import constants
-from test_helper import fast_pair_provider_simulator
-from test_helper import fast_pair_seeker
+from test_helper import fast_pair_base_test
 
 # The model ID to simulate on provider side.
 PROVIDER_SIMULATOR_MODEL_ID = constants.DEFAULT_MODEL_ID
@@ -36,32 +30,12 @@
 START_ADVERTISING_TIMEOUT_SEC = constants.START_ADVERTISING_TIMEOUT_SEC
 HALF_SHEET_POPUP_TIMEOUT_SEC = constants.HALF_SHEET_POPUP_TIMEOUT_SEC
 
-# Abbreviations for common use type.
-FastPairProviderSimulator = fast_pair_provider_simulator.FastPairProviderSimulator
-FastPairSeeker = fast_pair_seeker.FastPairSeeker
 
-
-class SeekerShowHalfSheetTest(base_test.BaseTestClass):
+class SeekerShowHalfSheetTest(fast_pair_base_test.FastPairBaseTest):
     """Fast Pair seeker show half sheet UI test."""
 
-    _duts: List[android_device.AndroidDevice]
-    _provider: FastPairProviderSimulator
-    _seeker: FastPairSeeker
-
-    def setup_class(self) -> None:
-        super().setup_class()
-        self._duts = self.register_controller(android_device)
-
-        # Assume the 1st phone is provider, the 2nd is seeker.
-        provider_ad, seeker_ad = self._duts
-        self._provider = FastPairProviderSimulator(provider_ad)
-        self._seeker = FastPairSeeker(seeker_ad)
-        self._provider.load_snippet()
-        self._seeker.load_snippet()
-
     def setup_test(self) -> None:
         super().setup_test()
-        self._provider.setup_provider_simulator(SETUP_TIMEOUT_SEC)
         self._provider.start_model_id_advertising(PROVIDER_SIMULATOR_MODEL_ID,
                                                   PROVIDER_SIMULATOR_ANTI_SPOOFING_KEY)
         self._provider.wait_for_discoverable_mode(BECOME_DISCOVERABLE_TIMEOUT_SEC)
@@ -71,13 +45,10 @@
         self._seeker.set_fast_pair_scan_enabled(True)
 
     def teardown_test(self) -> None:
-        super().teardown_test()
         self._seeker.set_fast_pair_scan_enabled(False)
         self._provider.teardown_provider_simulator()
         self._seeker.dismiss_halfsheet()
-        # Create per-test excepts of logcat.
-        for dut in self._duts:
-            dut.services.create_output_excerpts_all(self.current_test_info)
+        super().teardown_test()
 
     def test_seeker_show_half_sheet(self) -> None:
         self._seeker.wait_and_assert_halfsheet_showed(
diff --git a/nearby/tests/multidevices/host/test_helper/constants.py b/nearby/tests/multidevices/host/test_helper/constants.py
index 413e70b..646b428 100644
--- a/nearby/tests/multidevices/host/test_helper/constants.py
+++ b/nearby/tests/multidevices/host/test_helper/constants.py
@@ -27,3 +27,10 @@
 START_ADVERTISING_TIMEOUT_SEC = 5
 SCAN_TIMEOUT_SEC = 30
 HALF_SHEET_POPUP_TIMEOUT_SEC = 30
+
+# The phone to simulate Fast Pair provider (like headphone) needs changes in Android system:
+# 1. System permission check removal
+# 2. Adjusts Bluetooth profile configurations
+# The build fingerprint of the custom ROM for Fast Pair provider simulator.
+FAST_PAIR_PROVIDER_SIMULATOR_BUILD_FINGERPRINT = (
+    'google/bramble/bramble:Tiramisu/MASTER/eng.hylo.20211019.091550:userdebug/dev-keys')
diff --git a/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py b/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py
new file mode 100644
index 0000000..8b84839
--- /dev/null
+++ b/nearby/tests/multidevices/host/test_helper/fast_pair_base_test.py
@@ -0,0 +1,75 @@
+#  Copyright (C) 2022 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.
+
+"""Base for all Nearby Mainline Fast Pair end-to-end test cases."""
+
+from typing import List, Tuple
+
+from mobly import base_test
+from mobly import signals
+from mobly.controllers import android_device
+
+from test_helper import constants
+from test_helper import fast_pair_provider_simulator
+from test_helper import fast_pair_seeker
+
+# Abbreviations for common use type.
+AndroidDevice = android_device.AndroidDevice
+FastPairProviderSimulator = fast_pair_provider_simulator.FastPairProviderSimulator
+FastPairSeeker = fast_pair_seeker.FastPairSeeker
+REQUIRED_BUILD_FINGERPRINT = constants.FAST_PAIR_PROVIDER_SIMULATOR_BUILD_FINGERPRINT
+
+
+class FastPairBaseTest(base_test.BaseTestClass):
+    """Base class for all Nearby Mainline Fast Pair end-to-end classes to inherit."""
+
+    _duts: List[AndroidDevice]
+    _provider: FastPairProviderSimulator
+    _seeker: FastPairSeeker
+
+    def setup_class(self) -> None:
+        super().setup_class()
+        self._duts = self.register_controller(android_device, min_number=2)
+
+        provider_ad, seeker_ad = self._check_devices_supported()
+        self._provider = FastPairProviderSimulator(provider_ad)
+        self._seeker = FastPairSeeker(seeker_ad)
+        self._provider.load_snippet()
+        self._seeker.load_snippet()
+
+    def setup_test(self) -> None:
+        super().setup_test()
+        self._provider.setup_provider_simulator(constants.SETUP_TIMEOUT_SEC)
+
+    def teardown_test(self) -> None:
+        super().teardown_test()
+        # Create per-test excepts of logcat.
+        for dut in self._duts:
+            dut.services.create_output_excerpts_all(self.current_test_info)
+
+    def _check_devices_supported(self) -> Tuple[AndroidDevice, AndroidDevice]:
+        # Assume the 1st phone is provider, the 2nd one is seeker.
+        provider_ad, seeker_ad = self._duts[:2]
+
+        for ad in self._duts:
+            if ad.build_info['build_fingerprint'] == REQUIRED_BUILD_FINGERPRINT:
+                if ad != provider_ad:
+                    provider_ad, seeker_ad = seeker_ad, provider_ad
+                break
+        else:
+            raise signals.TestAbortClass(
+                f'None of phones has custom ROM ({REQUIRED_BUILD_FINGERPRINT}) for Fast Pair '
+                f'provider simulator. Skip all the test cases!')
+
+        return provider_ad, seeker_ad
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index 1af00c7..81782f9 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -176,7 +176,7 @@
     NetworkMonitor will continue to attempt validation, and if it fails after this time has passed,
     the network will be marked unvalidated.
 
-    Only supported up to S. On T+, the Wi-Fi code should use destroyAndAwaitReplacement in order
+    Only supported up to S. On T+, the Wi-Fi code should use unregisterAfterReplacement in order
     to ensure that apps see the network disconnect and reconnect. -->
     <integer translatable="false" name="config_validationFailureAfterRoamIgnoreTimeMillis">-1</integer>
 </resources>
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index e58160a..b4cc41a 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -34,6 +34,9 @@
 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
+import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
+import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
@@ -3648,7 +3651,7 @@
                     }
                     break;
                 }
-                case NetworkAgent.EVENT_DESTROY_AND_AWAIT_REPLACEMENT: {
+                case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: {
                     // If nai is not yet created, or is already destroyed, ignore.
                     if (!shouldDestroyNativeNetwork(nai)) break;
 
@@ -4213,7 +4216,7 @@
     }
 
     private boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
-        // T+ devices should use destroyAndAwaitReplacement.
+        // T+ devices should use unregisterAfterReplacement.
         if (SdkLevel.isAtLeastT()) return false;
         final long blockTimeOut = Long.valueOf(mResources.get().getInteger(
                 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
@@ -11218,17 +11221,43 @@
     }
 
     @Override
-    public void updateFirewallRule(final int chain, final int uid, final boolean allow) {
+    public void setUidFirewallRule(final int chain, final int uid, final int rule) {
         enforceNetworkStackOrSettingsPermission();
 
+        // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
+        int firewallRule = getFirewallRuleType(chain, rule);
+
+        if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) {
+            throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule);
+        }
+
         try {
-            mBpfNetMaps.setUidRule(chain, uid,
-                    allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
+            mBpfNetMaps.setUidRule(chain, uid, firewallRule);
         } catch (ServiceSpecificException e) {
             throw new IllegalStateException(e);
         }
     }
 
+    private int getFirewallRuleType(int chain, int rule) {
+        final int defaultRule;
+        switch (chain) {
+            case ConnectivityManager.FIREWALL_CHAIN_STANDBY:
+                defaultRule = FIREWALL_RULE_ALLOW;
+                break;
+            case ConnectivityManager.FIREWALL_CHAIN_DOZABLE:
+            case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE:
+            case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
+            case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY:
+                defaultRule = FIREWALL_RULE_DENY;
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported firewall chain: " + chain);
+        }
+        if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule;
+
+        return rule;
+    }
+
     @Override
     public void setFirewallChainEnabled(final int chain, final boolean enable) {
         enforceNetworkStackOrSettingsPermission();
diff --git a/service/src/com/android/server/connectivity/DscpPolicyTracker.java b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
index 43cfc8f..53b276e 100644
--- a/service/src/com/android/server/connectivity/DscpPolicyTracker.java
+++ b/service/src/com/android/server/connectivity/DscpPolicyTracker.java
@@ -16,10 +16,10 @@
 
 package com.android.server.connectivity;
 
-import static android.net.DscpPolicy.STATUS_DELETED;
-import static android.net.DscpPolicy.STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
-import static android.net.DscpPolicy.STATUS_POLICY_NOT_FOUND;
-import static android.net.DscpPolicy.STATUS_SUCCESS;
+import static android.net.NetworkAgent.DSCP_POLICY_STATUS_DELETED;
+import static android.net.NetworkAgent.DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
+import static android.net.NetworkAgent.DSCP_POLICY_STATUS_POLICY_NOT_FOUND;
+import static android.net.NetworkAgent.DSCP_POLICY_STATUS_SUCCESS;
 import static android.system.OsConstants.ETH_P_ALL;
 
 import android.annotation.NonNull;
@@ -112,12 +112,12 @@
         // the maximum number of policies then return INSUFFICIENT_PROCESSING_RESOURCES.
         final int existingIndex = mPolicyIdToBpfMapIndex.get(policy.getPolicyId(), -1);
         if (existingIndex == -1 && mPolicyIdToBpfMapIndex.size() >= MAX_POLICIES) {
-            return STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
+            return DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
         }
 
         // Currently all classifiers are supported, if any are removed return
-        // STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED,
-        // and for any other generic error STATUS_REQUEST_DECLINED
+        // DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED,
+        // and for any other generic error DSCP_POLICY_STATUS_REQUEST_DECLINED
 
         int addIndex = 0;
         // If a policy with a matching ID exists, replace it, otherwise use the next free
@@ -154,24 +154,25 @@
             }
         } catch (ErrnoException e) {
             Log.e(TAG, "Failed to insert policy into map: ", e);
-            return STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
+            return DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES;
         }
 
-        return STATUS_SUCCESS;
+        return DSCP_POLICY_STATUS_SUCCESS;
     }
 
     /**
      * Add the provided DSCP policy to the bpf map. Attach bpf program dscp_policy to iface
      * if not already attached. Response will be sent back to nai with status.
      *
-     * STATUS_SUCCESS - if policy was added successfully
-     * STATUS_INSUFFICIENT_PROCESSING_RESOURCES - if max policies were already set
+     * DSCP_POLICY_STATUS_SUCCESS - if policy was added successfully
+     * DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES - if max policies were already set
      */
     public void addDscpPolicy(NetworkAgentInfo nai, DscpPolicy policy) {
         if (!mAttachedIfaces.contains(nai.linkProperties.getInterfaceName())) {
             if (!attachProgram(nai.linkProperties.getInterfaceName())) {
                 Log.e(TAG, "Unable to attach program");
-                sendStatus(nai, policy.getPolicyId(), STATUS_INSUFFICIENT_PROCESSING_RESOURCES);
+                sendStatus(nai, policy.getPolicyId(),
+                        DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES);
                 return;
             }
         }
@@ -181,11 +182,11 @@
     }
 
     private void removePolicyFromMap(NetworkAgentInfo nai, int policyId, int index) {
-        int status = STATUS_POLICY_NOT_FOUND;
+        int status = DSCP_POLICY_STATUS_POLICY_NOT_FOUND;
         try {
             mBpfDscpIpv4Policies.replaceEntry(new Struct.U32(index), DscpPolicyValue.NONE);
             mBpfDscpIpv6Policies.replaceEntry(new Struct.U32(index), DscpPolicyValue.NONE);
-            status = STATUS_DELETED;
+            status = DSCP_POLICY_STATUS_DELETED;
         } catch (ErrnoException e) {
             Log.e(TAG, "Failed to delete policy from map: ", e);
         }
@@ -199,7 +200,7 @@
     public void removeDscpPolicy(NetworkAgentInfo nai, int policyId) {
         if (!mAttachedIfaces.contains(nai.linkProperties.getInterfaceName())) {
             // Nothing to remove since program is not attached. Send update back for policy id.
-            sendStatus(nai, policyId, STATUS_POLICY_NOT_FOUND);
+            sendStatus(nai, policyId, DSCP_POLICY_STATUS_POLICY_NOT_FOUND);
             return;
         }
 
@@ -222,7 +223,7 @@
         if (!mAttachedIfaces.contains(nai.linkProperties.getInterfaceName())) {
             // Nothing to remove since program is not attached. Send update for policy
             // id 0. The status update must contain a policy ID, and 0 is an invalid id.
-            sendStatus(nai, 0, STATUS_SUCCESS);
+            sendStatus(nai, 0, DSCP_POLICY_STATUS_SUCCESS);
             return;
         }
 
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index b73e2cc..1fc5a8f 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -736,8 +736,8 @@
         }
 
         @Override
-        public void sendDestroyAndAwaitReplacement(final int timeoutMillis) {
-            mHandler.obtainMessage(NetworkAgent.EVENT_DESTROY_AND_AWAIT_REPLACEMENT,
+        public void sendUnregisterAfterReplacement(final int timeoutMillis) {
+            mHandler.obtainMessage(NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT,
                     new Pair<>(NetworkAgentInfo.this, timeoutMillis)).sendToTarget();
         }
     }
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index ea98289..9cd8418 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -22,15 +22,14 @@
 import android.Manifest.permission.MANAGE_TEST_NETWORKS
 import android.content.Context
 import android.net.ConnectivityManager
-import android.net.cts.util.CtsNetUtils
 import android.net.DscpPolicy
-import android.net.DscpPolicy.STATUS_DELETED
-import android.net.DscpPolicy.STATUS_SUCCESS
 import android.net.InetAddresses
 import android.net.IpPrefix
 import android.net.LinkAddress
 import android.net.LinkProperties
 import android.net.NetworkAgent
+import android.net.NetworkAgent.DSCP_POLICY_STATUS_DELETED
+import android.net.NetworkAgent.DSCP_POLICY_STATUS_SUCCESS
 import android.net.NetworkAgentConfig
 import android.net.NetworkCapabilities
 import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
@@ -45,26 +44,18 @@
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
 import android.net.RouteInfo
-import android.net.util.SocketUtils
-import android.os.Build
 import android.os.HandlerThread
-import android.os.Looper
 import android.platform.test.annotations.AppModeFull
 import android.system.Os
-import android.system.OsConstants
 import android.system.OsConstants.AF_INET
-import android.system.OsConstants.IPPROTO_IP
 import android.system.OsConstants.IPPROTO_UDP
 import android.system.OsConstants.SOCK_DGRAM
 import android.system.OsConstants.SOCK_NONBLOCK
-import android.util.Log
 import android.util.Range
 import androidx.test.InstrumentationRegistry
 import androidx.test.runner.AndroidJUnit4
-import com.android.modules.utils.build.SdkLevel
 import com.android.testutils.CompatUtil
 import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.OffsetFilter
 import com.android.testutils.assertParcelingIsLossless
 import com.android.testutils.runAsShell
 import com.android.testutils.SC_V2
@@ -74,26 +65,18 @@
 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnDscpPolicyStatusUpdated
 import com.android.testutils.TestableNetworkCallback
 import org.junit.After
-import org.junit.AfterClass
 import org.junit.Assume.assumeTrue
 import org.junit.Before
-import org.junit.BeforeClass
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.net.Inet4Address
-import java.net.Inet6Address
-import java.net.InetAddress
-import java.net.InetSocketAddress
-import java.net.ServerSocket
 import java.nio.ByteBuffer
 import java.nio.ByteOrder
-import java.util.UUID
 import java.util.regex.Pattern
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
-import kotlin.concurrent.thread
 import kotlin.test.fail
 
 private const val MAX_PACKET_LENGTH = 1500
@@ -149,7 +132,7 @@
         runAsShell(MANAGE_TEST_NETWORKS) {
             val tnm = realContext.getSystemService(TestNetworkManager::class.java)
 
-            iface = tnm.createTunInterface( Array(1){ LinkAddress(LOCAL_IPV4_ADDRESS, 32) } )
+            iface = tnm.createTunInterface(Array(1) { LinkAddress(LOCAL_IPV4_ADDRESS, 32) })
             assertNotNull(iface)
         }
 
@@ -191,7 +174,7 @@
 
     private fun createConnectedNetworkAgent(
         context: Context = realContext,
-        specifier: String? = iface.getInterfaceName(),
+        specifier: String? = iface.getInterfaceName()
     ): Pair<TestableNetworkAgent, TestableNetworkCallback> {
         val callback = TestableNetworkCallback()
         // Ensure this NetworkAgent is never unneeded by filing a request with its specifier.
@@ -233,10 +216,10 @@
     }
 
     fun checkDscpValue(
-        agent : TestableNetworkAgent,
-        callback : TestableNetworkCallback,
-        dscpValue : Int = 0,
-        dstPort : Int = 0,
+        agent: TestableNetworkAgent,
+        callback: TestableNetworkCallback,
+        dscpValue: Int = 0,
+        dstPort: Int = 0
     ) {
         val testString = "test string"
         val testPacket = ByteBuffer.wrap(testString.toByteArray(Charsets.UTF_8))
@@ -263,9 +246,9 @@
 
             val ipAddr = ByteArray(4)
             buffer.get(ipAddr)
-            val srcIp = Inet4Address.getByAddress(ipAddr);
+            val srcIp = Inet4Address.getByAddress(ipAddr)
             buffer.get(ipAddr)
-            val dstIp = Inet4Address.getByAddress(ipAddr);
+            val dstIp = Inet4Address.getByAddress(ipAddr)
             val packetSrcPort = buffer.getShort().toInt()
             val packetDstPort = buffer.getShort().toInt()
 
@@ -280,15 +263,15 @@
     }
 
     fun doRemovePolicyTest(
-        agent : TestableNetworkAgent,
-        callback : TestableNetworkCallback,
-        policyId : Int
+        agent: TestableNetworkAgent,
+        callback: TestableNetworkCallback,
+        policyId: Int
     ) {
         val portNumber = 1111 * policyId
         agent.sendRemoveDscpPolicy(policyId)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(policyId, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
             checkDscpValue(agent, callback, dstPort = portNumber)
         }
     }
@@ -300,7 +283,7 @@
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
         }
 
         checkDscpValue(agent, callback, dscpValue = 1, dstPort = 4444)
@@ -308,7 +291,7 @@
         agent.sendRemoveDscpPolicy(1)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
         }
 
         val policy2 = DscpPolicy.Builder(1, 4)
@@ -317,7 +300,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
         }
 
         checkDscpValue(agent, callback, dscpValue = 4, dstPort = 5555)
@@ -325,7 +308,7 @@
         agent.sendRemoveDscpPolicy(1)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
         }
     }
 
@@ -337,7 +320,7 @@
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 1111)
         }
 
@@ -345,7 +328,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(2, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 2222)
         }
 
@@ -353,7 +336,7 @@
         agent.sendAddDscpPolicy(policy3)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(3, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 3333)
         }
 
@@ -365,12 +348,12 @@
 
     @Test
     fun testRemoveDscpPolicy_RemoveImmediatelyAfterAdd(): Unit =
-            createConnectedNetworkAgent().let{ (agent, callback) ->
+            createConnectedNetworkAgent().let { (agent, callback) ->
         val policy = DscpPolicy.Builder(1, 1).setDestinationPortRange(Range(1111, 1111)).build()
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 1111)
         }
         doRemovePolicyTest(agent, callback, 1)
@@ -379,7 +362,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(2, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 2222)
         }
         doRemovePolicyTest(agent, callback, 2)
@@ -388,7 +371,7 @@
         agent.sendAddDscpPolicy(policy3)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(3, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 3333)
         }
         doRemovePolicyTest(agent, callback, 3)
@@ -402,7 +385,7 @@
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 1111)
         }
 
@@ -410,7 +393,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(2, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 2222)
         }
 
@@ -418,7 +401,7 @@
         agent.sendAddDscpPolicy(policy3)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(3, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 3333)
         }
 
@@ -433,7 +416,7 @@
                 (agent, callback) ->
         agent.sendRemoveDscpPolicy(3)
         // Is there something to add in TestableNetworkCallback to NOT expect a callback?
-        // Or should we send STATUS_DELETED in any case or a different STATUS?
+        // Or should we send DSCP_POLICY_STATUS_DELETED in any case or a different STATUS?
     }
 
     @Test
@@ -443,7 +426,7 @@
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 1111)
         }
 
@@ -452,7 +435,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(2, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 2222)
         }
 
@@ -461,24 +444,24 @@
         agent.sendAddDscpPolicy(policy3)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(3, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 3333)
         }
 
         agent.sendRemoveAllDscpPolicies()
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
             checkDscpValue(agent, callback, dstPort = 1111)
         }
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(2, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
             checkDscpValue(agent, callback, dstPort = 2222)
         }
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(3, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
             checkDscpValue(agent, callback, dstPort = 3333)
         }
     }
@@ -490,7 +473,7 @@
         agent.sendAddDscpPolicy(policy)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
             checkDscpValue(agent, callback, dscpValue = 1, dstPort = 4444)
         }
 
@@ -501,7 +484,7 @@
         agent.sendAddDscpPolicy(policy2)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_SUCCESS, it.status)
+            assertEquals(DSCP_POLICY_STATUS_SUCCESS, it.status)
 
             // Sending packet with old policy should fail
             checkDscpValue(agent, callback, dstPort = 4444)
@@ -511,7 +494,7 @@
         agent.sendRemoveDscpPolicy(1)
         agent.expectCallback<OnDscpPolicyStatusUpdated>().let {
             assertEquals(1, it.policyId)
-            assertEquals(STATUS_DELETED, it.status)
+            assertEquals(DSCP_POLICY_STATUS_DELETED, it.status)
         }
     }
 
@@ -520,14 +503,14 @@
                 (agent, callback) ->
         // Check that policy with partial parameters is lossless.
         val policy = DscpPolicy.Builder(1, 1).setDestinationPortRange(Range(4444, 4444)).build()
-        assertParcelingIsLossless(policy);
+        assertParcelingIsLossless(policy)
 
         // Check that policy with all parameters is lossless.
         val policy2 = DscpPolicy.Builder(1, 1).setDestinationPortRange(Range(4444, 4444))
                 .setSourceAddress(LOCAL_IPV4_ADDRESS)
                 .setDestinationAddress(TEST_TARGET_IPV4_ADDR)
                 .setProtocol(IPPROTO_UDP).build()
-        assertParcelingIsLossless(policy2);
+        assertParcelingIsLossless(policy2)
     }
 }
 
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 53b00db..f007b83 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -1152,7 +1152,7 @@
     }
 
     @Test
-    fun testDestroyAndAwaitReplacement() {
+    fun testUnregisterAfterReplacement() {
         // Keeps an eye on all test networks.
         val matchAllCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
         registerNetworkCallback(makeTestNetworkRequest(), matchAllCallback)
@@ -1180,15 +1180,15 @@
         // Mark the first network as awaiting replacement. This should destroy the underlying
         // native network and send onNetworkDestroyed, but will not send any NetworkCallbacks,
         // because for callback and scoring purposes network1 is still connected.
-        agent1.destroyAndAwaitReplacement(5_000 /* timeoutMillis */)
+        agent1.unregisterAfterReplacement(5_000 /* timeoutMillis */)
         agent1.expectCallback<OnNetworkDestroyed>()
         assertThrows(IOException::class.java) { network1.bindSocket(DatagramSocket()) }
         assertNotNull(mCM.getLinkProperties(network1))
 
-        // Calling destroyAndAwaitReplacement more than once has no effect.
+        // Calling unregisterAfterReplacement more than once has no effect.
         // If it did, this test would fail because the 1ms timeout means that the network would be
         // torn down before the replacement arrives.
-        agent1.destroyAndAwaitReplacement(1 /* timeoutMillis */)
+        agent1.unregisterAfterReplacement(1 /* timeoutMillis */)
 
         // Connect a third network. Because network1 is awaiting replacement, network3 is preferred
         // as soon as it validates (until then, it is outscored by network1).
@@ -1216,14 +1216,14 @@
         matchAllCallback.expectCallback<Losing>(network3)
         testCallback.expectAvailableCallbacks(network4, validated = true)
         mCM.unregisterNetworkCallback(agent4callback)
-        agent3.destroyAndAwaitReplacement(5_000)
+        agent3.unregisterAfterReplacement(5_000)
         agent3.expectCallback<OnNetworkUnwanted>()
         matchAllCallback.expectCallback<Lost>(network3, 1000L)
         agent3.expectCallback<OnNetworkDestroyed>()
 
         // Now mark network4 awaiting replacement with a low timeout, and check that if no
         // replacement arrives, it is torn down.
-        agent4.destroyAndAwaitReplacement(100 /* timeoutMillis */)
+        agent4.unregisterAfterReplacement(100 /* timeoutMillis */)
         matchAllCallback.expectCallback<Lost>(network4, 1000L /* timeoutMs */)
         testCallback.expectCallback<Lost>(network4, 1000L /* timeoutMs */)
         agent4.expectCallback<OnNetworkDestroyed>()
@@ -1234,7 +1234,7 @@
         val (agent5, network5) = connectNetwork()
         matchAllCallback.expectAvailableThenValidatedCallbacks(network5)
         testCallback.expectAvailableThenValidatedCallbacks(network5)
-        agent5.destroyAndAwaitReplacement(5_000 /* timeoutMillis */)
+        agent5.unregisterAfterReplacement(5_000 /* timeoutMillis */)
         agent5.unregister()
         matchAllCallback.expectCallback<Lost>(network5, 1000L /* timeoutMs */)
         testCallback.expectCallback<Lost>(network5, 1000L /* timeoutMs */)
@@ -1257,7 +1257,7 @@
             it.hasCapability(NET_CAPABILITY_VALIDATED)
         }
 
-        wifiAgent.destroyAndAwaitReplacement(5_000 /* timeoutMillis */)
+        wifiAgent.unregisterAfterReplacement(5_000 /* timeoutMillis */)
         wifiAgent.expectCallback<OnNetworkDestroyed>()
 
         // Once the network is awaiting replacement, changing LinkProperties, NetworkCapabilities or