Add AccountKeys to FastPairAccountDevicesMetadataRequest.

Test: CTS test.
Bug: 204780849
Change-Id: I93d94a89e760189b9a537db4ceabfad75c759e52
Merged-In: I93d94a89e760189b9a537db4ceabfad75c759e52
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..84af445 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairAdvHandler.java
@@ -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/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/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. */