Merge "Add a TODO to import python deps" into tm-dev
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 53d485d..7b97cec 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -236,7 +236,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 +270,7 @@
     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 VALIDATION_STATUS_NOT_VALID = 2; // 0x2
     field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
   }
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..07b6227 100644
--- a/framework/src/android/net/NetworkAgent.java
+++ b/framework/src/android/net/NetworkAgent.java
@@ -440,7 +440,7 @@
      * 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 +984,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/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..ab5f5d3 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3648,7 +3648,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 +4213,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));
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/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