Add half sheet apk to nearby

Test: start activity show avaiable device to pairing click connect to
start pairing process pair success
Bug: 202335820

Change-Id: I454527f11a396ecf8acd55649dc740ed2d09c6fc
diff --git a/nearby/service/Android.bp b/nearby/service/Android.bp
index 63e2748..b80d677 100644
--- a/nearby/service/Android.bp
+++ b/nearby/service/Android.bp
@@ -27,6 +27,9 @@
     name: "nearby-service-string-res",
     srcs: [
         "java/**/Constant.java",
+        "java/**/UserActionHandlerBase.java",
+        "java/**/UserActionHandler.java",
+        "java/**/FastPairConstants.java",
     ],
 }
 
@@ -55,6 +58,7 @@
     static_libs: [
         "androidx.annotation_annotation",
         "androidx.core_core",
+        "androidx.localbroadcastmanager_localbroadcastmanager",
         "guava",
         "libprotobuf-java-lite",
         "fast-pair-lite-protos",
diff --git a/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java b/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java
index c50e219..67d87e3 100644
--- a/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java
+++ b/nearby/service/java/com/android/server/nearby/common/fastpair/service/UserActionHandlerBase.java
@@ -23,6 +23,7 @@
 
     public static final String EXTRA_ITEM_ID = PREFIX + "EXTRA_ITEM_ID";
     public static final String EXTRA_COMPANION_APP = ACTION_PREFIX + "EXTRA_COMPANION_APP";
+    public static final String EXTRA_MAC_ADDRESS = PREFIX + "EXTRA_MAC_ADDRESS";
 
 }
 
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
index bf73360..1477d95 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/Constant.java
@@ -22,4 +22,22 @@
 public class Constant {
     public static final String EXTRA_BINDER = "com.android.server.nearby.fastpair.BINDER";
     public static final String EXTRA_BUNDLE = "com.android.server.nearby.fastpair.BUNDLE_EXTRA";
+    public static final String SUCCESS_STATE = "SUCCESS";
+    public static final String FAIL_STATE = "FAIL";
+    public static final String DISMISS = "DISMISS";
+    public static final String NEED_CONFIRM_PASSKEY = "NEED CONFIRM PASSKEY";
+    // device support assistant additional setup
+    public static final String NEED_ADDITIONAL_SETUP = "NEED ADDITIONAL SETUP";
+    public static final String SHOW_PAIRING_WITHOUT_INTERACTION =
+            "SHOW_PAIRING_WITHOUT_INTERACTION";
+    public static final String ACTION_FAST_PAIR_HALF_SHEET_CANCEL =
+            "com.android.nearby.ACTION_FAST_PAIR_HALF_SHEET_CANCEL";
+    public static final String ACTION_FAST_PAIR_HALF_SHEET_BAN_STATE_RESET =
+            "com.android.nearby.ACTION_FAST_PAIR_BAN_STATE_RESET";
+    public static final String EXTRA_HALF_SHEET_INFO =
+            "com.android.nearby.halfsheet.HALF_SHEET";
+    public static final String EXTRA_HALF_SHEET_TYPE =
+            "com.android.nearby.halfsheet.HALF_SHEET_TYPE";
+    public static final String DEVICE_PAIRING_FRAGMENT_TYPE = "DEVICE_PAIRING";
+
 }
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 56650ce..247339e 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairManager.java
@@ -16,8 +16,12 @@
 
 package com.android.server.nearby.fastpair;
 
+
+import static com.android.server.nearby.fastpair.Constant.DEVICE_PAIRING_FRAGMENT_TYPE;
 import static com.android.server.nearby.fastpair.Constant.EXTRA_BINDER;
 import static com.android.server.nearby.fastpair.Constant.EXTRA_BUNDLE;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_INFO;
+import static com.android.server.nearby.fastpair.Constant.EXTRA_HALF_SHEET_TYPE;
 
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
@@ -35,6 +39,7 @@
 import android.nearby.ScanCallback;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.util.Base64;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -58,6 +63,8 @@
 import com.android.server.nearby.fastpair.pairinghandler.PairingProgressHandlerBase;
 import com.android.server.nearby.util.Environment;
 
+import com.google.protobuf.ByteString;
+
 import java.security.GeneralSecurityException;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -69,6 +76,7 @@
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
 
+import service.proto.Cache;
 import service.proto.Rpcs;
 
 /**
@@ -80,9 +88,12 @@
     private static final String ACTION_PREFIX = UserActionHandler.PREFIX;
     private static final int WAIT_FOR_UNLOCK_MILLIS = 5000;
     private static final String ACTIVITY_INTENT_ACTION = "android.nearby.SHOW_HALFSHEET";
-    /** A notification ID which should be dismissed*/
+    /** A notification ID which should be dismissed */
     public static final String EXTRA_NOTIFICATION_ID = ACTION_PREFIX + "EXTRA_NOTIFICATION_ID";
     public static final String ACTION_RESOURCES_APK = "android.nearby.SHOW_HALFSHEET";
+    // Temp action deleted when the scanner is ready
+    public static final String ACTION_START_PAIRING = "NEARBY_START_PAIRING";
+    public static final String EXTRA_ADDRESS = "ADDRESS";
 
     private static Executor sFastPairExecutor;
 
@@ -96,6 +107,17 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                 Log.d("FastPairService", " screen on");
+            } else if (intent.getAction().equals(ACTION_START_PAIRING)) {
+                String address = intent.getStringExtra(EXTRA_ADDRESS);
+                String testPublicKey =
+                        "E4kxROcAj2SPlqrxHgXOm_yF-XIMSS91pFrfmeLcxULWyn0nK8i52PPkoC4r"
+                                + "LKRM2kZzNgT8bhDwK5njJAjiOg";
+                showHalfSheet(Cache.ScanFastPairStoreItem.newBuilder().setAddress(address)
+                        .setAntiSpoofingPublicKey(ByteString.copyFrom(
+                                Base64.decode(testPublicKey, Base64.URL_SAFE
+                                        | Base64.NO_WRAP | Base64.NO_PADDING)))
+                        .build());
+                Log.d("FastPairService", "start pair " + address);
             } else {
                 Log.d("FastPairService", " screen off");
             }
@@ -128,12 +150,14 @@
 
         }
     };
+
     /**
      * Function called when nearby service start.
      */
     public void initiate() {
         mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
         mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+        mIntentFilter.addAction("NEARBY_START_PAIRING");
 
         mLocatorContextWrapper.getContext()
                 .registerReceiver(mScreenBroadcastReceiver, mIntentFilter);
@@ -228,7 +252,9 @@
                         item.getFastPairInformation().getDataOnlyConnection());
             }
             FastPairConnection connection = new FastPairDualConnection(
-                    context, item.getMacAddress(), prefsBuilder.build(), null);
+                    context, item.getMacAddress(),
+                    // Change to prefsBuilder.build when the api integration complete
+                    Preferences.builderFromGmsLog().build(), null);
             pairingProgressHandlerBase.onPairingSetupCompleted();
 
             FastPairConnection.SharedSecret sharedSecret;
@@ -239,7 +265,7 @@
                                         : item.getAuthenticationPublicKeySecp256R1());
 
                 byte[] key = pairingProgressHandlerBase.getKeyForLocalCache(accountKey,
-                                connection, sharedSecret);
+                        connection, sharedSecret);
 
                 // We don't cache initial pairing case here but cache it when upload to footprints.
                 if (key != null) {
@@ -308,7 +334,8 @@
         return manager == null ? null : manager.getAdapter();
     }
 
-    /** Gets the package name of HalfSheet.apk
+    /**
+     * Gets the package name of HalfSheet.apk
      * getHalfSheetApkPkgName may invoke PackageManager multiple times and it does not have
      * race condition check. Since there is no lock for mHalfSheetApkPkgName.
      */
@@ -318,8 +345,8 @@
         }
         List<ResolveInfo> resolveInfos = mLocatorContextWrapper.getContext()
                 .getPackageManager().queryIntentActivities(
-                new Intent(ACTION_RESOURCES_APK),
-                PackageManager.MATCH_SYSTEM_ONLY);
+                        new Intent(ACTION_RESOURCES_APK),
+                        PackageManager.MATCH_SYSTEM_ONLY);
 
         // remove apps that don't live in the nearby apex
         resolveInfos.removeIf(info ->
@@ -352,14 +379,19 @@
      * Invokes half sheet in the other apk. This function can only be called in Nearby because other
      * app can't get the correct component name.
      */
-    void showHalfSheet() {
+    void showHalfSheet(Cache.ScanFastPairStoreItem scanFastPairStoreItem) {
         if (mLocatorContextWrapper != null) {
             String packageName = getHalfSheetApkPkgName();
             HalfSheetCallback callback = new HalfSheetCallback();
+            callback.setmFastPairController(Locator
+                    .getFromContextWrapper(mLocatorContextWrapper, FastPairController.class));
             Bundle bundle = new Bundle();
             bundle.putBinder(EXTRA_BINDER, callback);
             mLocatorContextWrapper.getContext()
                     .startActivityAsUser(new Intent(ACTIVITY_INTENT_ACTION)
+                                    .putExtra(EXTRA_HALF_SHEET_INFO,
+                                            scanFastPairStoreItem.toByteArray())
+                                    .putExtra(EXTRA_HALF_SHEET_TYPE, DEVICE_PAIRING_FRAGMENT_TYPE)
                                     .putExtra(EXTRA_BUNDLE, bundle)
                                     .setComponent(new ComponentName(packageName,
                                             packageName + ".HalfSheetActivity")),
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java b/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java
index 5444e82..e92bb8a 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/FastPairModule.java
@@ -18,9 +18,12 @@
 
 import android.content.Context;
 
+import com.android.server.nearby.common.eventloop.EventLoop;
 import com.android.server.nearby.common.locator.Locator;
 import com.android.server.nearby.common.locator.Module;
 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 java.time.Clock;
 import java.time.Instant;
@@ -37,10 +40,16 @@
     public void configure(Context context, Class<?> type, Locator locator) {
         if (type.equals(FastPairCacheManager.class)) {
             locator.bind(FastPairCacheManager.class, new FastPairCacheManager(context));
+        } else if (type.equals(FootprintsDeviceManager.class)) {
+            locator.bind(FootprintsDeviceManager.class, new FootprintsDeviceManager());
+        } else if (type.equals(EventLoop.class)) {
+            locator.bind(EventLoop.class, EventLoop.newInstance("NearbyFastPair"));
         } else if (type.equals(FastPairController.class)) {
             locator.bind(FastPairController.class, new FastPairController(context));
         } else if (type.equals(FastPairCacheManager.class)) {
             locator.bind(FastPairCacheManager.class, new FastPairCacheManager(context));
+        } else if (type.equals(FastPairHalfSheetManager.class)) {
+            locator.bind(FastPairHalfSheetManager.class, new FastPairHalfSheetManager());
         } else if (type.equals(Clock.class)) {
             locator.bind(Clock.class, new Clock() {
                 @Override
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java b/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java
index f2b0d59..674633d 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/UserActionHandler.java
@@ -25,4 +25,7 @@
 
     public static final String EXTRA_DISCOVERY_ITEM = PREFIX + "EXTRA_DISCOVERY_ITEM";
     public static final String EXTRA_FAST_PAIR_SECRET = PREFIX + "EXTRA_FAST_PAIR_SECRET";
+    public static final String ACTION_FAST_PAIR = ACTION_PREFIX + "ACTION_FAST_PAIR";
+    public static final String EXTRA_PRIVATE_BLE_ADDRESS =
+            ACTION_PREFIX + "EXTRA_PRIVATE_BLE_ADDRESS";
 }
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
index d59305b..4c43965 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/FastPairHalfSheetManager.java
@@ -17,6 +17,7 @@
 package com.android.server.nearby.fastpair.halfsheet;
 
 import android.bluetooth.BluetoothDevice;
+import android.util.Log;
 
 import com.android.server.nearby.fastpair.cache.DiscoveryItem;
 
@@ -29,7 +30,7 @@
      * Shows pairing fail half sheet.
      */
     public void showPairingFailed() {
-
+        Log.d("FastPairHalfSheetManager", "show fail half sheet");
     }
 
     /**
@@ -42,30 +43,38 @@
     /**
      * Show passkey confirmation info on half sheet
      */
-    public void showPasskeyConfirmation(BluetoothDevice device, int passkey) {}
+    public void showPasskeyConfirmation(BluetoothDevice device, int passkey) {
+    }
 
     /**
      * This function will handle pairing steps for half sheet.
      */
-    public void showPairingHalfSheet(DiscoveryItem item) {}
+    public void showPairingHalfSheet(DiscoveryItem item) {
+        Log.d("FastPairHalfSheetManager", "show pairing half sheet");
+    }
 
     /**
      * Shows pairing success info.
      */
-    public void showPairingSuccessHalfSheet(String address){}
+    public void showPairingSuccessHalfSheet(String address) {
+        Log.d("FastPairHalfSheetManager", "show success half sheet");
+    }
 
     /**
      * Removes dismiss runnable.
      */
-    public void disableDismissRunnable(){}
+    public void disableDismissRunnable() {
+    }
 
     /**
      * Destroys the bluetooth pairing controller.
      */
-    public void destroyBluetoothPairController(){}
+    public void destroyBluetoothPairController() {
+    }
 
     /**
      * Notify manager the pairing has finished.
      */
-    public void notifyPairingProcessDone(boolean success, String address, DiscoveryItem item) {}
+    public void notifyPairingProcessDone(boolean success, String address, DiscoveryItem item) {
+    }
 }
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java
index fd9e460..2c792ed 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/halfsheet/HalfSheetCallback.java
@@ -16,15 +16,37 @@
 
 package com.android.server.nearby.fastpair.halfsheet;
 
+import android.content.Intent;
 import android.nearby.IFastPairHalfSheetCallback;
 import android.util.Log;
 
+import com.android.server.nearby.fastpair.FastPairController;
+
+
 /**
  * Callback to send ux action back to nearby service.
  */
-public class HalfSheetCallback  extends IFastPairHalfSheetCallback.Stub {
+public class HalfSheetCallback extends IFastPairHalfSheetCallback.Stub {
+    private FastPairController mFastPairController;
+
+    public HalfSheetCallback() {
+    }
+
+    /**
+     * Set function for Fast Pair controller.
+     */
+    public void setmFastPairController(FastPairController fastPairController) {
+        mFastPairController = fastPairController;
+    }
+
+    /**
+     * Half Sheet connection button clicked.
+     */
     @Override
-    public void onHalfSheetConnectionConfirm() {
+    public void onHalfSheetConnectionConfirm(Intent intent) {
         Log.d("FastPairHalfSheet", "Call back receiver");
+        if (mFastPairController != null) {
+            mFastPairController.pair(intent);
+        }
     }
 }
diff --git a/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java
index 760b4e0..ccd7e5e 100644
--- a/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java
+++ b/nearby/service/java/com/android/server/nearby/fastpair/pairinghandler/PairingProgressHandlerBase.java
@@ -76,7 +76,8 @@
 
 
         Log.v("PairingHandler",
-                "PairingProgressHandler:Create %s for pairing");
+                "PairingProgressHandler:Create "
+                        + item.getMacAddress() + " for pairing");
         return pairingProgressHandlerBase;
     }
 
@@ -134,7 +135,7 @@
      * <li>1, optIn footprint for initial pairing.
      * <li>2, write the device name to provider
      * <li>2.1, generate default personalized name for initial pairing or get the personalized name
-     *     from footprint for subsequent pairing.
+     * from footprint for subsequent pairing.
      * <li>2.2, set alias name for the bluetooth device.
      * <li>2.3, update the device name for connection to write into provider for initial pair.
      * <li>3, suppress battery notifications until oobe finishes.
@@ -180,7 +181,7 @@
      */
     public void onPairingSuccess(String address) {
         Log.v("PairingHandler", "PairingProgressHandler:onPairingSuccess with address: "
-                        + maskBluetoothAddress(address));
+                + maskBluetoothAddress(address));
     }
 
     private static void optInFootprintsForInitialPairing(
diff --git a/nearby/service/proto/src/fastpair/cache.proto b/nearby/service/proto/src/fastpair/cache.proto
index bf80b58..12731fb 100644
--- a/nearby/service/proto/src/fastpair/cache.proto
+++ b/nearby/service/proto/src/fastpair/cache.proto
@@ -304,3 +304,158 @@
 
   reserved 5;
 }
+
+// A locally cached Fast Pair device associating an account key with the
+// bluetooth address of the device.
+message StoredFastPairItem {
+  // The device's public mac address.
+  string mac_address = 1;
+
+  // The account key written to the device.
+  bytes account_key = 2;
+
+  // When user need to update provider name, enable this value to trigger
+  // writing new name to provider.
+  bool need_to_update_provider_name = 3;
+
+  // The retry times to update name into provider.
+  int32 update_name_retries = 4;
+
+  // Latest firmware version from the server.
+  string latest_firmware_version = 5;
+
+  // The firmware version that is on the device.
+  string device_firmware_version = 6;
+
+  // The timestamp from the last time we fetched the firmware version from the
+  // device.
+  int64 last_check_firmware_timestamp_millis = 7;
+
+  // The timestamp from the last time we fetched the firmware version from
+  // server.
+  int64 last_server_query_timestamp_millis = 8;
+
+  // Only allows one bloom filter check process to create gatt connection and
+  // try to read the firmware version value.
+  bool can_read_firmware = 9;
+
+  // Device's model id.
+  string model_id = 10;
+
+  // Features that this Fast Pair device supports.
+  repeated FastPairFeature features = 11;
+
+  // Keeps the stored discovery item in local cache, we can have most
+  // information of fast pair device locally without through footprints, i.e. we
+  // can have most fast pair features locally.
+  StoredDiscoveryItem discovery_item = 12;
+
+  // When true, the latest uploaded event to FMA is connected. We use
+  // it as the previous ACL state when getting the BluetoothAdapter STATE_OFF to
+  // determine if need to upload the disconnect event to FMA.
+  bool fma_state_is_connected = 13;
+
+  // Device's buffer size range.
+  repeated BufferSizeRange buffer_size_range = 18;
+
+  // The additional account key if this device could be associated with multiple
+  // accounts. Notes that for this device, the account_key field is the basic
+  // one which will not be associated with the accounts.
+  repeated bytes additional_account_key = 19;
+
+  // Deprecated fields.
+  reserved 14, 15, 16, 17;
+}
+
+// Contains information about Fast Pair devices stored through our scanner.
+// Next ID: 29
+message ScanFastPairStoreItem {
+  // Device's model id.
+  string model_id = 1;
+
+  // Device's RSSI value
+  int32 rssi = 2;
+
+  // Device's tx power
+  int32 tx_power = 3;
+
+  // Bytes of item icon in PNG format displayed in Discovery item list.
+  bytes icon_png = 4;
+
+  // A FIFE URL of the item icon displayed in Discovery item list.
+  string icon_fife_url = 28;
+
+  // Device name like "Bose QC 35".
+  string device_name = 5;
+
+  // Client timestamp when user last saw Fast Pair device.
+  int64 last_observation_timestamp_millis = 6;
+
+  // Action url after user click the notification.
+  string action_url = 7;
+
+  // Device's bluetooth address.
+  string address = 8;
+
+  // The computed threshold rssi value that would trigger FastPair notifications
+  int32 threshold_rssi = 9;
+
+  // Populated with the contents of the bloom filter in the event that
+  // the scanned device is advertising a bloom filter instead of a model id
+  bytes bloom_filter = 10;
+
+  // Device name from the BLE scan record
+  string ble_device_name = 11;
+
+  // Strings used for the FastPair UI
+  FastPairStrings fast_pair_strings = 12;
+
+  // A key used to authenticate advertising device.
+  // See NearbyItem.authentication_public_key_secp256r1 for more information.
+  bytes anti_spoofing_public_key = 13;
+
+  // When true, Fast Pair will only create a bond with the device and not
+  // attempt to connect any profiles (for example, A2DP or HFP).
+  bool data_only_connection = 14;
+
+  // The type of the manufacturer (first party, third party, etc).
+  int32 manufacturer_type_num = 15;
+
+  // Additional images that are attached specifically for true wireless Fast
+  // Pair devices.
+  TrueWirelessHeadsetImages true_wireless_images = 16;
+
+  // When true, this device can support assistant function.
+  bool assistant_supported = 17;
+
+  // Optional, the name of the company producing this Fast Pair device.
+  string company_name = 18;
+
+  // Features supported by the Fast Pair device.
+  FastPairFeature features = 19;
+
+  // The interaction type that this scan should trigger
+  InteractionType interaction_type = 20;
+
+  // The copy of the advertisement bytes, used to pass along to other
+  // apps that use Fast Pair as the discovery vehicle.
+  bytes full_ble_record = 21;
+
+  // Companion app related information
+  CompanionAppDetails companion_detail = 22;
+
+  // Client timestamp when user first saw Fast Pair device.
+  int64 first_observation_timestamp_millis = 23;
+
+  // The type of the device (wearable, headphones, etc).
+  int32 device_type_num = 24;
+
+  // The type of notification (app launch smart setup, etc).
+  NotificationType notification_type = 25;
+
+  // The customized title.
+  string customized_title = 26;
+
+  // The customized description.
+  string customized_description = 27;
+}
diff --git a/nearby/service/proto/src/fastpair/rpcs.proto b/nearby/service/proto/src/fastpair/rpcs.proto
index 384d471..0399d09 100644
--- a/nearby/service/proto/src/fastpair/rpcs.proto
+++ b/nearby/service/proto/src/fastpair/rpcs.proto
@@ -313,3 +313,17 @@
   string fast_pair_tv_connect_device_no_account_description = 24;
 }
 
+// The buffer size range of a Fast Pair devices support dynamic buffer size.
+message BufferSizeRange {
+  // The max buffer size in ms.
+  int32 max_size = 1;
+
+  // The min buffer size in ms.
+  int32 min_size = 2;
+
+  // The default buffer size in ms.
+  int32 default_size = 3;
+
+  // The codec of this buffer size range.
+  int32 codec = 4;
+}