Merge "Revert "Fix the command to run CtsSeekerDiscoverProviderTest."" into tm-dev am: 36053b6182 am: 81c779994b
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Nearby/+/17046183
Change-Id: I57cd2b81a4426cff4079aef94c73c926d041795a
diff --git a/nearby/framework/java/android/nearby/FastPairDataProviderBase.java b/nearby/framework/java/android/nearby/FastPairDataProviderBase.java
index f7af7b8..57467b7 100644
--- a/nearby/framework/java/android/nearby/FastPairDataProviderBase.java
+++ b/nearby/framework/java/android/nearby/FastPairDataProviderBase.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.nearby.aidl.ByteArrayParcel;
import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataRequestParcel;
@@ -40,7 +41,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* Base class for fast pair providers outside the system server.
@@ -223,7 +226,18 @@
}
/**
- * Class for reading FastPairAccountDevicesMetadataRequest.
+ * Class for reading FastPairAccountDevicesMetadataRequest, which specifies the Fast Pair
+ * account and the allow list of the FastPair device keys saved to the account (i.e., FastPair
+ * accountKeys).
+ *
+ * A Fast Pair accountKey is created when a Fast Pair device is saved to an account. It is per
+ * Fast Pair device per account.
+ *
+ * To retrieve all Fast Pair accountKeys saved to an account, the caller needs to set
+ * account with an empty allow list.
+ *
+ * To retrieve metadata of a selected list of Fast Pair devices saved to an account, the caller
+ * needs to set account with a non-empty allow list.
*/
public static class FastPairAccountDevicesMetadataRequest {
@@ -233,10 +247,34 @@
final FastPairAccountDevicesMetadataRequestParcel metaDataRequestParcel) {
this.mMetadataRequestParcel = metaDataRequestParcel;
}
- /** Get account. */
+
+ /**
+ * Get FastPair account, whose Fast Pair devices' metadata is requested.
+ *
+ * @return a FastPair account.
+ */
public @NonNull Account getAccount() {
return this.mMetadataRequestParcel.account;
}
+
+ /**
+ * Get allowlist of Fast Pair devices using a collection of accountKeys.
+ * Note that as a special case, empty list actually means all FastPair devices under the
+ * account instead of none.
+ *
+ * @return allowlist of Fast Pair devices using a collection of accountKeys.
+ */
+ public @NonNull Collection<byte[]> getAccountKeys() {
+ if (this.mMetadataRequestParcel.accountKeys == null) {
+ return new ArrayList<byte[]>(0);
+ }
+ List<byte[]> accountKeys =
+ new ArrayList<>(this.mMetadataRequestParcel.accountKeys.length);
+ for (ByteArrayParcel accountKey : this.mMetadataRequestParcel.accountKeys) {
+ accountKeys.add(accountKey.byteArray);
+ }
+ return accountKeys;
+ }
}
/** Class for reading FastPairEligibleAccountsRequest. */
diff --git a/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl
new file mode 100644
index 0000000..53c73bd
--- /dev/null
+++ b/nearby/framework/java/android/nearby/aidl/ByteArrayParcel.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nearby.aidl;
+
+/**
+ * This is to support 2D byte arrays.
+ * {@hide}
+ */
+parcelable ByteArrayParcel {
+ byte[] byteArray;
+}
\ No newline at end of file
diff --git a/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl
index 2cff632..5953935 100644
--- a/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl
+++ b/nearby/framework/java/android/nearby/aidl/FastPairAccountDevicesMetadataRequestParcel.aidl
@@ -17,6 +17,7 @@
package android.nearby.aidl;
import android.accounts.Account;
+import android.nearby.aidl.ByteArrayParcel;
/**
* Request details for Metadata of Fast Pair devices associated with an account.
@@ -24,4 +25,5 @@
*/
parcelable FastPairAccountDevicesMetadataRequestParcel {
Account account;
+ ByteArrayParcel[] accountKeys;
}
\ No newline at end of file
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
index 6a296c2..60db6f5 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -27,13 +27,13 @@
import android.nearby.NearbyDevice;
import android.util.Log;
+import com.android.server.nearby.common.ble.decode.FastPairDecoder;
import com.android.server.nearby.common.bloomfilter.BloomFilter;
import com.android.server.nearby.common.bloomfilter.FastPairBloomFilterHasher;
import com.android.server.nearby.common.locator.Locator;
import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
import com.android.server.nearby.provider.FastPairDataProvider;
import com.android.server.nearby.util.DataUtils;
-import com.android.server.nearby.util.FastPairDecoder;
import com.android.server.nearby.util.Hex;
import java.util.List;
@@ -100,8 +100,8 @@
}
for (Account account : accountList) {
List<Data.FastPairDeviceWithAccountKey> listDevices =
- FastPairDataProvider.getInstance().loadFastPairDevicesWithAccountKey(
- account);
+ FastPairDataProvider.getInstance()
+ .loadFastPairDeviceWithAccountKey(account);
Data.FastPairDeviceWithAccountKey recognizedDevice =
findRecognizedDevice(listDevices,
new BloomFilter(bloomFilterByteArray,
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
index 3a3c962..380c759 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
@@ -41,6 +41,7 @@
import androidx.annotation.NonNull;
+import com.android.server.nearby.common.ble.decode.FastPairDecoder;
import com.android.server.nearby.common.bluetooth.BluetoothException;
import com.android.server.nearby.common.bluetooth.fastpair.FastPairConnection;
import com.android.server.nearby.common.bluetooth.fastpair.FastPairDualConnection;
@@ -58,7 +59,6 @@
import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
import com.android.server.nearby.fastpair.pairinghandler.PairingProgressHandlerBase;
-import com.android.server.nearby.util.FastPairDecoder;
import com.android.server.nearby.util.ForegroundThread;
import com.android.server.nearby.util.Hex;
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java
index 4f279a5..b8a9796 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/cache/DiscoveryItem.java
@@ -31,6 +31,7 @@
import com.android.server.nearby.common.ble.util.RangingUtils;
import com.android.server.nearby.common.fastpair.IconUtils;
import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -67,6 +68,15 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ItemState {}
+ public DiscoveryItem(LocatorContextWrapper locatorContextWrapper,
+ Cache.StoredDiscoveryItem mStoredDiscoveryItem) {
+ this.mFastPairCacheManager =
+ locatorContextWrapper.getLocator().get(FastPairCacheManager.class);
+ this.mClock =
+ locatorContextWrapper.getLocator().get(Clock.class);
+ this.mStoredDiscoveryItem = mStoredDiscoveryItem;
+ }
+
public DiscoveryItem(Context context, Cache.StoredDiscoveryItem mStoredDiscoveryItem) {
this.mFastPairCacheManager = Locator.get(context, FastPairCacheManager.class);
this.mClock = Locator.get(context, Clock.class);
diff --git a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
index 03484a0..f4db578 100644
--- a/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/FastPairDataProvider.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.content.Context;
import android.nearby.FastPairDataProviderBase;
+import android.nearby.aidl.ByteArrayParcel;
import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataRequestParcel;
import android.nearby.aidl.FastPairEligibleAccountsRequestParcel;
@@ -32,6 +33,7 @@
import com.android.server.nearby.common.bloomfilter.BloomFilter;
import com.android.server.nearby.fastpair.footprint.FastPairUploadInfo;
+import java.util.ArrayList;
import java.util.List;
import service.proto.Data;
@@ -142,16 +144,38 @@
}
/**
- * Loads FastPair devices for a given account.
+ * Loads FastPair device accountKeys for a given account, but not other detailed fields.
*
* @throws IllegalStateException If ProxyFastPairDataProvider is not available.
*/
- public List<Data.FastPairDeviceWithAccountKey> loadFastPairDevicesWithAccountKey(
+ public List<Data.FastPairDeviceWithAccountKey> loadFastPairDeviceWithAccountKey(
Account account) {
+ return loadFastPairDeviceWithAccountKey(account, new ArrayList<byte[]>(0));
+ }
+
+ /**
+ * Loads FastPair devices for a list of accountKeys of a given account.
+ *
+ * @param account The account of the FastPair devices.
+ * @param accountKeys The allow list of FastPair devices if it is not empty. Otherwise, the
+ * function returns accountKeys of all FastPair devices under the account,
+ * without detailed fields.
+ *
+ * @throws IllegalStateException If ProxyFastPairDataProvider is not available.
+ */
+ public List<Data.FastPairDeviceWithAccountKey> loadFastPairDeviceWithAccountKey(
+ Account account, List<byte[]> accountKeys) {
if (mProxyFastPairDataProvider != null) {
FastPairAccountDevicesMetadataRequestParcel requestParcel =
new FastPairAccountDevicesMetadataRequestParcel();
requestParcel.account = account;
+ requestParcel.accountKeys = new ByteArrayParcel[accountKeys.size()];
+ int i = 0;
+ for (byte[] accountKey : accountKeys) {
+ requestParcel.accountKeys[i] = new ByteArrayParcel();
+ requestParcel.accountKeys[i].byteArray = accountKey;
+ i = i + 1;
+ }
return Utils.convertToFastPairDevicesWithAccountKey(
mProxyFastPairDataProvider.loadFastPairAccountDevicesMetadata(requestParcel));
}
diff --git a/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java b/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java
deleted file mode 100644
index 6021ff6..0000000
--- a/nearby/service/java/com/android/server/nearby/util/FastPairDecoder.java
+++ /dev/null
@@ -1,258 +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 com.android.server.nearby.util;
-
-import android.annotation.Nullable;
-import android.bluetooth.le.ScanRecord;
-import android.os.ParcelUuid;
-import android.util.SparseArray;
-
-import com.android.server.nearby.common.ble.BleFilter;
-import com.android.server.nearby.common.ble.BleRecord;
-
-import java.util.Arrays;
-
-/**
- * Parses Fast Pair information out of {@link BleRecord}s.
- *
- * <p>There are 2 different packet formats that are supported, which is used can be determined by
- * packet length:
- *
- * <p>For 3-byte packets, the full packet is the model ID.
- *
- * <p>For all other packets, the first byte is the header, followed by the model ID, followed by
- * zero or more extra fields. Each field has its own header byte followed by the field value. The
- * packet header is formatted as 0bVVVLLLLR (V = version, L = model ID length, R = reserved) and
- * each extra field header is 0bLLLLTTTT (L = field length, T = field type).
- */
-public class FastPairDecoder {
-
- private static final int FIELD_TYPE_BLOOM_FILTER = 0;
- private static final int FIELD_TYPE_BLOOM_FILTER_SALT = 1;
- private static final int FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION = 2;
- private static final int FIELD_TYPE_BATTERY = 3;
- private static final int FIELD_TYPE_BATTERY_NO_NOTIFICATION = 4;
- public static final int FIELD_TYPE_CONNECTION_STATE = 5;
- private static final int FIELD_TYPE_RANDOM_RESOLVABLE_DATA = 6;
-
-
- /** FE2C is the 16-bit Service UUID. The rest is the base UUID. See BluetoothUuid (hidden). */
- private static final ParcelUuid FAST_PAIR_SERVICE_PARCEL_UUID =
- ParcelUuid.fromString("0000FE2C-0000-1000-8000-00805F9B34FB");
-
- /** The filter you use to scan for Fast Pair BLE advertisements. */
- public static final BleFilter FILTER =
- new BleFilter.Builder().setServiceData(FAST_PAIR_SERVICE_PARCEL_UUID,
- new byte[0]).build();
-
- // NOTE: Ensure that all bitmasks are always ints, not bytes so that bitshifting works correctly
- // without needing worry about signing errors.
- private static final int HEADER_VERSION_BITMASK = 0b11100000;
- private static final int HEADER_LENGTH_BITMASK = 0b00011110;
- private static final int HEADER_VERSION_OFFSET = 5;
- private static final int HEADER_LENGTH_OFFSET = 1;
-
- private static final int EXTRA_FIELD_LENGTH_BITMASK = 0b11110000;
- private static final int EXTRA_FIELD_TYPE_BITMASK = 0b00001111;
- private static final int EXTRA_FIELD_LENGTH_OFFSET = 4;
- private static final int EXTRA_FIELD_TYPE_OFFSET = 0;
-
- private static final int MIN_ID_LENGTH = 3;
- private static final int MAX_ID_LENGTH = 14;
- private static final int HEADER_INDEX = 0;
- private static final int HEADER_LENGTH = 1;
- private static final int FIELD_HEADER_LENGTH = 1;
-
- // Not using java.util.IllegalFormatException because it is unchecked.
- private static class IllegalFormatException extends Exception {
- private IllegalFormatException(String message) {
- super(message);
- }
- }
-
- /**
- * Gets model id data from broadcast
- */
- @Nullable
- public static byte[] getModelId(@Nullable byte[] serviceData) {
- if (serviceData == null) {
- return null;
- }
-
- if (serviceData.length >= MIN_ID_LENGTH) {
- if (serviceData.length == MIN_ID_LENGTH) {
- // If the length == 3, all bytes are the ID. See flag docs for more about
- // endianness.
- return serviceData;
- } else {
- // Otherwise, the first byte is a header which contains the length of the big-endian
- // model ID that follows. The model ID will be trimmed if it contains leading zeros.
- int idIndex = 1;
- int end = idIndex + getIdLength(serviceData);
- while (serviceData[idIndex] == 0 && end - idIndex > MIN_ID_LENGTH) {
- idIndex++;
- }
- return Arrays.copyOfRange(serviceData, idIndex, end);
- }
- }
- return null;
- }
-
- /** Gets the FastPair service data array if available, otherwise returns null. */
- @Nullable
- public static byte[] getServiceDataArray(BleRecord bleRecord) {
- return bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
- }
-
- /** Gets the FastPair service data array if available, otherwise returns null. */
- @Nullable
- public static byte[] getServiceDataArray(ScanRecord scanRecord) {
- return scanRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
- }
-
- /** Gets the bloom filter from the extra fields if available, otherwise returns null. */
- @Nullable
- public static byte[] getBloomFilter(@Nullable byte[] serviceData) {
- return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER);
- }
-
- /** Gets the bloom filter salt from the extra fields if available, otherwise returns null. */
- @Nullable
- public static byte[] getBloomFilterSalt(byte[] serviceData) {
- return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_SALT);
- }
-
- /**
- * Gets the suppress notification with bloom filter from the extra fields if available,
- * otherwise returns null.
- */
- @Nullable
- public static byte[] getBloomFilterNoNotification(@Nullable byte[] serviceData) {
- return getExtraField(serviceData, FIELD_TYPE_BLOOM_FILTER_NO_NOTIFICATION);
- }
-
- /**
- * Get random resolvableData
- */
- @Nullable
- public static byte[] getRandomResolvableData(byte[] serviceData) {
- return getExtraField(serviceData, FIELD_TYPE_RANDOM_RESOLVABLE_DATA);
- }
-
- @Nullable
- private static byte[] getExtraField(@Nullable byte[] serviceData, int fieldId) {
- if (serviceData == null || serviceData.length < HEADER_INDEX + HEADER_LENGTH) {
- return null;
- }
- try {
- return getExtraFields(serviceData).get(fieldId);
- } catch (IllegalFormatException e) {
- return null;
- }
- }
-
- /** Gets extra field data at the end of the packet, defined by the extra field header. */
- private static SparseArray<byte[]> getExtraFields(byte[] serviceData)
- throws IllegalFormatException {
- SparseArray<byte[]> extraFields = new SparseArray<>();
- if (getVersion(serviceData) != 0) {
- return extraFields;
- }
- int headerIndex = getFirstExtraFieldHeaderIndex(serviceData);
- while (headerIndex < serviceData.length) {
- int length = getExtraFieldLength(serviceData, headerIndex);
- int index = headerIndex + FIELD_HEADER_LENGTH;
- int type = getExtraFieldType(serviceData, headerIndex);
- int end = index + length;
- if (extraFields.get(type) == null) {
- if (end <= serviceData.length) {
- extraFields.put(type, Arrays.copyOfRange(serviceData, index, end));
- } else {
- throw new IllegalFormatException(
- "Invalid length, " + end + " is longer than service data size "
- + serviceData.length);
- }
- }
- headerIndex = end;
- }
- return extraFields;
- }
-
- /** Checks whether or not a valid ID is included in the service data packet. */
- public static boolean hasBeaconIdBytes(BleRecord bleRecord) {
- byte[] serviceData = bleRecord.getServiceData(FAST_PAIR_SERVICE_PARCEL_UUID);
- return checkModelId(serviceData);
- }
-
- /** Check whether byte array is FastPair model id or not. */
- public static boolean checkModelId(@Nullable byte[] scanResult) {
- return scanResult != null
- // The 3-byte format has no header byte (all bytes are the ID).
- && (scanResult.length == MIN_ID_LENGTH
- // Header byte exists. We support only format version 0. (A different version
- // indicates
- // a breaking change in the format.)
- || (scanResult.length > MIN_ID_LENGTH
- && getVersion(scanResult) == 0
- && isIdLengthValid(scanResult)));
- }
-
- /** Checks whether or not bloom filter is included in the service data packet. */
- public static boolean hasBloomFilter(BleRecord bleRecord) {
- return (getBloomFilter(getServiceDataArray(bleRecord)) != null
- || getBloomFilterNoNotification(getServiceDataArray(bleRecord)) != null);
- }
-
- /** Checks whether or not bloom filter is included in the service data packet. */
- public static boolean hasBloomFilter(ScanRecord scanRecord) {
- return (getBloomFilter(getServiceDataArray(scanRecord)) != null
- || getBloomFilterNoNotification(getServiceDataArray(scanRecord)) != null);
- }
-
- private static int getVersion(byte[] serviceData) {
- return serviceData.length == MIN_ID_LENGTH
- ? 0
- : (serviceData[HEADER_INDEX] & HEADER_VERSION_BITMASK) >> HEADER_VERSION_OFFSET;
- }
-
- private static int getIdLength(byte[] serviceData) {
- return serviceData.length == MIN_ID_LENGTH
- ? MIN_ID_LENGTH
- : (serviceData[HEADER_INDEX] & HEADER_LENGTH_BITMASK) >> HEADER_LENGTH_OFFSET;
- }
-
- private static int getFirstExtraFieldHeaderIndex(byte[] serviceData) {
- return HEADER_INDEX + HEADER_LENGTH + getIdLength(serviceData);
- }
-
- private static int getExtraFieldLength(byte[] serviceData, int extraFieldIndex) {
- return (serviceData[extraFieldIndex] & EXTRA_FIELD_LENGTH_BITMASK)
- >> EXTRA_FIELD_LENGTH_OFFSET;
- }
-
- private static int getExtraFieldType(byte[] serviceData, int extraFieldIndex) {
- return (serviceData[extraFieldIndex] & EXTRA_FIELD_TYPE_BITMASK) >> EXTRA_FIELD_TYPE_OFFSET;
- }
-
- private static boolean isIdLengthValid(byte[] serviceData) {
- int idLength = getIdLength(serviceData);
- return MIN_ID_LENGTH <= idLength
- && idLength <= MAX_ID_LENGTH
- && idLength + HEADER_LENGTH <= serviceData.length;
- }
-}
-
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
index 71fc330..fd9e294 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/FastPairDataProviderBaseTest.java
@@ -30,6 +30,7 @@
import android.nearby.FastPairDeviceMetadata;
import android.nearby.FastPairDiscoveryItem;
import android.nearby.FastPairEligibleAccount;
+import android.nearby.aidl.ByteArrayParcel;
import android.nearby.aidl.FastPairAccountDevicesMetadataRequestParcel;
import android.nearby.aidl.FastPairAccountKeyDeviceMetadataParcel;
import android.nearby.aidl.FastPairAntispoofkeyDeviceMetadataParcel;
@@ -85,6 +86,7 @@
private static final Account MANAGE_ACCOUNT = new Account("ghi@gmail.com", "type3");
private static final Account ACCOUNTDEVICES_METADATA_ACCOUNT =
new Account("jk@gmail.com", "type4");
+ private static final int NUM_ACCOUNT_DEVICES = 2;
private static final int ERROR_CODE_BAD_REQUEST =
FastPairDataProviderBase.ERROR_CODE_BAD_REQUEST;
@@ -125,6 +127,7 @@
private static final String WAIT_LAUNCH_COMPANION_APP_DESCRIPTION =
"WAIT_LAUNCH_COMPANION_APP_DESCRIPTION";
private static final byte[] ACCOUNT_KEY = new byte[] {3};
+ private static final byte[] ACCOUNT_KEY_2 = new byte[] {9, 3};
private static final byte[] SHA256_ACCOUNT_KEY_PUBLIC_ADDRESS = new byte[] {2, 8};
private static final byte[] REQUEST_MODEL_ID = new byte[] {1, 2, 3};
private static final byte[] ANTI_SPOOFING_KEY = new byte[] {4, 5, 6};
@@ -533,6 +536,11 @@
new FastPairAccountDevicesMetadataRequestParcel();
requestParcel.account = ACCOUNTDEVICES_METADATA_ACCOUNT;
+ requestParcel.accountKeys = new ByteArrayParcel[NUM_ACCOUNT_DEVICES];
+ requestParcel.accountKeys[0] = new ByteArrayParcel();
+ requestParcel.accountKeys[1] = new ByteArrayParcel();
+ requestParcel.accountKeys[0].byteArray = ACCOUNT_KEY;
+ requestParcel.accountKeys[1].byteArray = ACCOUNT_KEY_2;
return requestParcel;
}
@@ -793,6 +801,9 @@
private static void ensureHappyPathAsExpected(
FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest request) {
assertThat(request.getAccount()).isEqualTo(ACCOUNTDEVICES_METADATA_ACCOUNT);
+ assertThat(request.getAccountKeys().size()).isEqualTo(ACCOUNTKEY_DEVICE_NUM);
+ assertThat(request.getAccountKeys()).contains(ACCOUNT_KEY);
+ assertThat(request.getAccountKeys()).contains(ACCOUNT_KEY_2);
}
/* Verifies Happy Path FastPairEligibleAccountsRequest. */
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java
new file mode 100644
index 0000000..2ade5f2
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBaseTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.fastpair.pairinghandler;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import androidx.annotation.Nullable;
+
+import com.android.server.nearby.common.locator.Locator;
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+import com.android.server.nearby.fastpair.cache.FastPairCacheManager;
+import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager;
+import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager;
+import com.android.server.nearby.fastpair.notification.FastPairNotificationManager;
+import com.android.server.nearby.fastpair.testing.FakeDiscoveryItems;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+
+import service.proto.Cache;
+import service.proto.Rpcs;
+
+public class PairingProgressHandlerBaseTest {
+ @Mock
+ Locator mLocator;
+ @Mock
+ LocatorContextWrapper mContextWrapper;
+ @Mock
+ Clock mClock;
+ @Mock
+ FastPairCacheManager mFastPairCacheManager;
+ @Mock
+ FootprintsDeviceManager mFootprintsDeviceManager;
+ private static final byte[] ACCOUNT_KEY = new byte[]{0x01, 0x02};
+
+ @Before
+ public void setup() {
+
+ MockitoAnnotations.initMocks(this);
+ when(mContextWrapper.getLocator()).thenReturn(mLocator);
+ mLocator.overrideBindingForTest(FastPairCacheManager.class,
+ mFastPairCacheManager);
+ mLocator.overrideBindingForTest(Clock.class, mClock);
+ }
+
+ @Test
+ public void createHandler_halfSheetSubsequentPairing_notificationPairingHandlerCreated() {
+
+ DiscoveryItem discoveryItem = FakeDiscoveryItems.newFastPairDiscoveryItem(mContextWrapper);
+ discoveryItem.setStoredItemForTest(
+ discoveryItem.getStoredItemForTest().toBuilder()
+ .setAuthenticationPublicKeySecp256R1(ByteString.copyFrom(ACCOUNT_KEY))
+ .setFastPairInformation(
+ Cache.FastPairInformation.newBuilder()
+ .setDeviceType(Rpcs.DeviceType.HEADPHONES).build())
+ .build());
+
+ PairingProgressHandlerBase progressHandler =
+ createProgressHandler(ACCOUNT_KEY, discoveryItem, /* isRetroactivePair= */ false);
+
+ assertThat(progressHandler).isInstanceOf(NotificationPairingProgressHandler.class);
+ }
+
+ @Test
+ public void createHandler_halfSheetInitialPairing_halfSheetPairingHandlerCreated() {
+ // No account key
+ DiscoveryItem discoveryItem = FakeDiscoveryItems.newFastPairDiscoveryItem(mContextWrapper);
+ discoveryItem.setStoredItemForTest(
+ discoveryItem.getStoredItemForTest().toBuilder()
+ .setFastPairInformation(
+ Cache.FastPairInformation.newBuilder()
+ .setDeviceType(Rpcs.DeviceType.HEADPHONES).build())
+ .build());
+
+ PairingProgressHandlerBase progressHandler =
+ createProgressHandler(null, discoveryItem, /* isRetroactivePair= */ false);
+
+ assertThat(progressHandler).isInstanceOf(HalfSheetPairingProgressHandler.class);
+ }
+
+ private PairingProgressHandlerBase createProgressHandler(
+ @Nullable byte[] accountKey, DiscoveryItem fastPairItem, boolean isRetroactivePair) {
+ FastPairNotificationManager fastPairNotificationManager =
+ new FastPairNotificationManager(mContextWrapper, fastPairItem, true);
+ FastPairHalfSheetManager fastPairHalfSheetManager =
+ new FastPairHalfSheetManager(mContextWrapper);
+ mLocator.overrideBindingForTest(FastPairHalfSheetManager.class, fastPairHalfSheetManager);
+ PairingProgressHandlerBase pairingProgressHandlerBase =
+ PairingProgressHandlerBase.create(
+ mContextWrapper,
+ fastPairItem,
+ fastPairItem.getAppPackageName(),
+ accountKey,
+ mFootprintsDeviceManager,
+ fastPairNotificationManager,
+ fastPairHalfSheetManager,
+ isRetroactivePair);
+ return pairingProgressHandlerBase;
+ }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java
new file mode 100644
index 0000000..aa7e6f6
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/testing/FakeDiscoveryItems.java
@@ -0,0 +1,55 @@
+/*
+ * 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.fastpair.testing;
+
+import com.android.server.nearby.common.locator.LocatorContextWrapper;
+import com.android.server.nearby.fastpair.cache.DiscoveryItem;
+
+import service.proto.Cache;
+
+public class FakeDiscoveryItems {
+ public static final String DEFAULT_MAC_ADDRESS = "00:11:22:33:44:55";
+ public static final long DEFAULT_TIMESTAMP = 1000000000L;
+ public static final String DEFAULT_DESCRIPITON = "description";
+ public static final String TRIGGER_ID = "trigger.id";
+ private static final String FAST_PAIR_ID = "id";
+ private static final int RSSI = -80;
+ private static final int TX_POWER = -10;
+ public static DiscoveryItem newFastPairDiscoveryItem(LocatorContextWrapper contextWrapper) {
+ return new DiscoveryItem(contextWrapper, newFastPairDeviceStoredItem());
+ }
+
+ public static Cache.StoredDiscoveryItem newFastPairDeviceStoredItem() {
+ return newFastPairDeviceStoredItem(TRIGGER_ID);
+ }
+
+ public static Cache.StoredDiscoveryItem newFastPairDeviceStoredItem(String triggerId) {
+ Cache.StoredDiscoveryItem.Builder item = Cache.StoredDiscoveryItem.newBuilder();
+ item.setState(Cache.StoredDiscoveryItem.State.STATE_ENABLED);
+ item.setId(FAST_PAIR_ID);
+ item.setDescription(DEFAULT_DESCRIPITON);
+ item.setType(Cache.NearbyType.NEARBY_DEVICE);
+ item.setTriggerId(triggerId);
+ item.setMacAddress(DEFAULT_MAC_ADDRESS);
+ item.setFirstObservationTimestampMillis(DEFAULT_TIMESTAMP);
+ item.setLastObservationTimestampMillis(DEFAULT_TIMESTAMP);
+ item.setRssi(RSSI);
+ item.setTxPower(TX_POWER);
+ return item.build();
+ }
+
+}