Add Unit Test for FastPairDualConnection.
Bug: 204780849
Test: unit test
Change-Id: Id80761023e388aa298eeef7a192016ce6327e9ea
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java
index c98848d..8b466fa 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnection.java
@@ -701,7 +701,7 @@
/* keyBasedPairingInfo= */ null,
/* passkeyConfirmationHandler= */ null,
mTimingLogger),
- device,
+ maskBluetoothAddress(device),
getSupportedProfiles(device),
/* numConnectionAttempts= */ 1,
/* enablePairingBehavior= */ false,
@@ -1053,7 +1053,7 @@
try {
attemptConnectProfiles(
pairer,
- device,
+ maskBluetoothAddress(device),
profiles,
mPreferences.getNumConnectAttempts(),
/* enablePairingBehavior= */ false);
@@ -1200,7 +1200,7 @@
new ScopedTiming(mTimingLogger, "Connect to profile directly")) {
attemptConnectProfiles(
pairer,
- device,
+ maskBluetoothAddress(device),
supportedProfiles,
mPreferences.getEnablePairFlowShowUiWithoutProfileConnection()
? mPreferences.getNumConnectAttempts()
@@ -1216,16 +1216,17 @@
}
}
- private void attemptConnectProfiles(
+ @VisibleForTesting
+ void attemptConnectProfiles(
BluetoothAudioPairer pairer,
- BluetoothDevice device,
+ String deviceMaskedBluetoothAddress,
short[] profiles,
int numConnectionAttempts,
boolean enablePairingBehavior)
throws PairingException {
attemptConnectProfiles(
pairer,
- device,
+ deviceMaskedBluetoothAddress,
profiles,
numConnectionAttempts,
enablePairingBehavior,
@@ -1234,7 +1235,7 @@
private void attemptConnectProfiles(
BluetoothAudioPairer pairer,
- BluetoothDevice device,
+ String deviceMaskedBluetoothAddress,
short[] profiles,
int numConnectionAttempts,
boolean enablePairingBehavior,
@@ -1277,7 +1278,7 @@
| ConnectException e) {
Log.w(TAG,
"Error connecting to profile=" + profile
- + " for device=" + maskBluetoothAddress(device)
+ + " for device=" + deviceMaskedBluetoothAddress
+ " (attempt " + i + " of " + mPreferences
.getNumConnectAttempts(), e);
mEventLogger.logCurrentEventFailed(e);
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java
new file mode 100644
index 0000000..44bab71
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/bluetooth/fastpair/FastPairDualConnectionTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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 com.android.server.nearby.common.bluetooth.fastpair;
+
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.GATT_ERROR_CODE_TIMEOUT;
+import static com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection.appendMoreErrorCode;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.Mockito.doNothing;
+
+import android.bluetooth.BluetoothDevice;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.nearby.common.bluetooth.BluetoothException;
+import com.android.server.nearby.common.bluetooth.BluetoothGattException;
+import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.BluetoothOperationTimeoutException;
+
+import com.google.common.collect.Iterables;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Unit tests for {@link FastPairDualConnection}.
+ */
+@Presubmit
+@SmallTest
+public class FastPairDualConnectionTest extends TestCase {
+
+ private static final String BLE_ADDRESS = "BLE_ADDRESS";
+ private static final String MASKED_BLE_ADDRESS = "MASKED_BLE_ADDRESS";
+ private static final short[] PROFILES = {Constants.A2DP_SINK_SERVICE_UUID};
+ private static final int NUM_CONNECTION_ATTEMPTS = 1;
+ private static final boolean ENABLE_PAIRING_BEHAVIOR = true;
+
+ private TestEventLogger mEventLogger;
+ @Mock private TimingLogger mTimingLogger;
+ @Mock private BluetoothAudioPairer mBluetoothAudioPairer;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ MockitoAnnotations.initMocks(this);
+
+ doNothing().when(mBluetoothAudioPairer).connect(anyShort(), anyBoolean());
+ mEventLogger = new TestEventLogger();
+ }
+
+ private FastPairDualConnection newFastPairDualConnection(
+ String bleAddress, Preferences.Builder prefsBuilder) {
+ return new FastPairDualConnection(
+ ApplicationProvider.getApplicationContext(),
+ bleAddress,
+ prefsBuilder.build(),
+ mEventLogger,
+ mTimingLogger);
+ }
+
+ private FastPairDualConnection newFastPairDualConnection2(
+ String bleAddress, Preferences.Builder prefsBuilder) {
+ return new FastPairDualConnection(
+ ApplicationProvider.getApplicationContext(),
+ bleAddress,
+ prefsBuilder.build(),
+ mEventLogger);
+ }
+
+ @SdkSuppress(minSdkVersion = 32, codeName = "T")
+ public void testFastPairDualConnectionConstructor() {
+ assertThat(newFastPairDualConnection(BLE_ADDRESS, Preferences.builder())).isNotNull();
+ }
+
+ @SdkSuppress(minSdkVersion = 32, codeName = "T")
+ public void testFastPairDualConnectionConstructor2() {
+ assertThat(newFastPairDualConnection2(BLE_ADDRESS, Preferences.builder())).isNotNull();
+ }
+
+ @SdkSuppress(minSdkVersion = 32, codeName = "T")
+ public void testAttemptConnectProfiles() {
+ try {
+ new FastPairDualConnection(
+ ApplicationProvider.getApplicationContext(),
+ BLE_ADDRESS,
+ Preferences.builder().build(),
+ mEventLogger,
+ mTimingLogger)
+ .attemptConnectProfiles(
+ mBluetoothAudioPairer,
+ MASKED_BLE_ADDRESS,
+ PROFILES,
+ NUM_CONNECTION_ATTEMPTS,
+ ENABLE_PAIRING_BEHAVIOR);
+ } catch (PairingException e) {
+ // Mocked pair doesn't throw Pairing Exception.
+ }
+ }
+
+
+ @SdkSuppress(minSdkVersion = 32, codeName = "T")
+ public void appendMoreErrorCode_gattError() {
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+ new BluetoothGattException("Test", 133)))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + 133);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+ new BluetoothGattException("Test", 257)))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + 257);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED, new BluetoothException("Test")))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED,
+ new BluetoothOperationTimeoutException("Test")))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_ADDRESS_ROTATED + GATT_ERROR_CODE_TIMEOUT);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+ new BluetoothGattException("Test", 41)))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + 41);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+ new BluetoothGattException("Test", 788)))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + 788);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST, new BluetoothException("Test")))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST);
+ assertThat(
+ appendMoreErrorCode(
+ GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST,
+ new BluetoothOperationTimeoutException("Test")))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST + GATT_ERROR_CODE_TIMEOUT);
+ assertThat(appendMoreErrorCode(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST, /* cause= */ null))
+ .isEqualTo(GATT_ERROR_CODE_FAST_PAIR_SIGNAL_LOST);
+ }
+
+ static class TestEventLogger implements EventLogger {
+
+ private List<Item> mLogs = new ArrayList<>();
+
+ @Override
+ public void logEventSucceeded(Event event) {
+ mLogs.add(new Item(event));
+ }
+
+ @Override
+ public void logEventFailed(Event event, Exception e) {
+ mLogs.add(new ItemFailed(event, e));
+ }
+
+ List<Item> getErrorLogs() {
+ return mLogs.stream().filter(item -> item instanceof ItemFailed)
+ .collect(Collectors.toList());
+ }
+
+ List<Item> getLogs() {
+ return mLogs;
+ }
+
+ List<Item> getLast() {
+ return mLogs.subList(mLogs.size() - 1, mLogs.size());
+ }
+
+ BluetoothDevice getDevice() {
+ return Iterables.getLast(mLogs).mEvent.getBluetoothDevice();
+ }
+
+ public static class Item {
+
+ final Event mEvent;
+
+ Item(Event event) {
+ this.mEvent = event;
+ }
+
+ @Override
+ public String toString() {
+ return "Item{" + "event=" + mEvent + '}';
+ }
+ }
+
+ public static class ItemFailed extends Item {
+
+ final Exception mException;
+
+ ItemFailed(Event event, Exception e) {
+ super(event);
+ this.mException = e;
+ }
+
+ @Override
+ public String toString() {
+ return "ItemFailed{" + "event=" + mEvent + ", exception=" + mException + '}';
+ }
+ }
+ }
+}