Add txPower to FastPairDevice

Test: m
Ignore-AOSP-First: nearby_not_in_aosp_yet
Change-Id: Ic8106e9dbf42bf8e204b07ff6a928abdf36c4cbc
diff --git a/nearby/framework/java/android/nearby/FastPairDevice.java b/nearby/framework/java/android/nearby/FastPairDevice.java
index e12b4f8..7160533 100644
--- a/nearby/framework/java/android/nearby/FastPairDevice.java
+++ b/nearby/framework/java/android/nearby/FastPairDevice.java
@@ -48,6 +48,7 @@
                 builder.addMedium(in.readInt());
             }
             builder.setRssi(in.readInt());
+            builder.setTxPower(in.readInt());
             if (in.readInt() == 1) {
                 builder.setModelId(in.readString());
             }
@@ -67,6 +68,10 @@
         }
     };
 
+    // The transmit power in dBm. Valid range is [-127, 126]. a
+    // See android.bluetooth.le.ScanResult#getTxPower
+    private int mTxPower;
+
     // Some OEM devices devices don't have model Id.
     @Nullable private final String mModelId;
 
@@ -82,6 +87,7 @@
      * @param name Name of the FastPairDevice. Can be {@code null} if there is no name.
      * @param mediums The {@link Medium}s over which the device is discovered.
      * @param rssi The received signal strength in dBm.
+     * @param txPower The transmit power in dBm. Valid range is [-127, 126].
      * @param modelId The identifier of the Fast Pair device.
      *                Can be {@code null} if there is no Model ID.
      * @param bluetoothAddress The hardware address of this BluetoothDevice.
@@ -90,16 +96,28 @@
     public FastPairDevice(@Nullable String name,
             List<Integer> mediums,
             int rssi,
+            int txPower,
             @Nullable String modelId,
             @NonNull String bluetoothAddress,
             @Nullable byte[] data) {
         super(name, mediums, rssi);
+        this.mTxPower = txPower;
         this.mModelId = modelId;
         this.mBluetoothAddress = bluetoothAddress;
         this.mData = data;
     }
 
     /**
+     * Gets the transmit power in dBm. A value of
+     * android.bluetooth.le.ScanResult#TX_POWER_NOT_PRESENT
+     * indicates that the TX power is not present.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
      * Gets the identifier of the Fast Pair device. Can be {@code null} if there is no Model ID.
      */
     @Nullable
@@ -149,6 +167,7 @@
             stringBuilder.append(mediumToString(medium));
         }
         stringBuilder.append("} rssi=").append(getRssi());
+        stringBuilder.append(" txPower=").append(mTxPower);
         stringBuilder.append(" modelId=").append(mModelId);
         stringBuilder.append(" bluetoothAddress=").append(mBluetoothAddress);
         stringBuilder.append("]");
@@ -162,7 +181,8 @@
             if (!super.equals(other)) {
                 return false;
             }
-            return Objects.equals(mModelId, otherDevice.mModelId)
+            return  mTxPower == otherDevice.mTxPower
+                    && Objects.equals(mModelId, otherDevice.mModelId)
                     && Objects.equals(mBluetoothAddress, otherDevice.mBluetoothAddress)
                     && Arrays.equals(mData, otherDevice.mData);
         }
@@ -172,7 +192,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(
-                getName(), getMediums(), getRssi(), mModelId, mBluetoothAddress,
+                getName(), getMediums(), getRssi(), mTxPower, mModelId, mBluetoothAddress,
                 Arrays.hashCode(mData));
     }
 
@@ -189,6 +209,7 @@
             dest.writeInt(medium);
         }
         dest.writeInt(getRssi());
+        dest.writeInt(mTxPower);
         dest.writeInt(mModelId == null ? 0 : 1);
         if (mModelId != null) {
             dest.writeString(mModelId);
@@ -211,6 +232,7 @@
 
         @Nullable private String mName;
         private int mRssi;
+        private int mTxPower;
         @Nullable private String mModelId;
         private String mBluetoothAddress;
         @Nullable private byte[] mData;
@@ -253,6 +275,17 @@
         }
 
         /**
+         * Sets the txPower.
+         *
+         * @param txPower The transmit power in dBm
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
          * Sets the model Id of this Fast Pair device.
          *
          * @param modelId The identifier of the Fast Pair device. Can be {@code null}
@@ -292,7 +325,7 @@
          */
         @NonNull
         public FastPairDevice build() {
-            return new FastPairDevice(mName, mMediums, mRssi, mModelId,
+            return new FastPairDevice(mName, mMediums, mRssi, mTxPower, mModelId,
                     mBluetoothAddress, mData);
         }
     }
diff --git a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
index f137de4..694e15b 100644
--- a/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
+++ b/nearby/framework/java/android/nearby/NearbyDeviceParcelable.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -54,6 +55,7 @@
                     }
                     builder.setMedium(in.readInt());
                     builder.setRssi(in.readInt());
+                    builder.setTxPower(in.readInt());
                     if (in.readInt() == 1) {
                         builder.setFastPairModelId(in.readString());
                     }
@@ -81,6 +83,7 @@
     @NearbyDevice.Medium
     private final int mMedium;
     private final int mRssi;
+    private final int mTxPower;
 
     @Nullable
     private final String mBluetoothAddress;
@@ -90,12 +93,13 @@
     private final byte[] mData;
 
     private NearbyDeviceParcelable(@ScanRequest.ScanType int scanType, @Nullable String name,
-            int medium, int rssi, @Nullable String fastPairModelId,
+            int medium, int rssi, int txPower, @Nullable String fastPairModelId,
             @Nullable String bluetoothAddress, @Nullable byte[] data) {
         mScanType = scanType;
         mName = name;
         mMedium = medium;
         mRssi = rssi;
+        mTxPower = txPower;
         mFastPairModelId = fastPairModelId;
         mBluetoothAddress = bluetoothAddress;
         mData = data;
@@ -124,6 +128,7 @@
         }
         dest.writeInt(mMedium);
         dest.writeInt(mRssi);
+        dest.writeInt(mTxPower);
         dest.writeInt(mFastPairModelId == null ? 0 : 1);
         if (mFastPairModelId != null) {
             dest.writeString(mFastPairModelId);
@@ -148,6 +153,7 @@
                 + "name=" + mName
                 + ", medium=" + NearbyDevice.mediumToString(mMedium)
                 + ", rssi=" + mRssi
+                + ", txPower=" + mTxPower
                 + ", bluetoothAddress=" + mBluetoothAddress
                 + ", fastPairModelId=" + mFastPairModelId
                 + ", data=" + Arrays.toString(mData)
@@ -161,6 +167,7 @@
             return  Objects.equals(mName, otherNearbyDeviceParcelable.mName)
                     && (mMedium == otherNearbyDeviceParcelable.mMedium)
                     && (mRssi == otherNearbyDeviceParcelable.mRssi)
+                    && (mTxPower == otherNearbyDeviceParcelable.mTxPower)
                     && (Objects.equals(
                             mBluetoothAddress, otherNearbyDeviceParcelable.mBluetoothAddress))
                     && (Objects.equals(
@@ -173,7 +180,8 @@
     @Override
     public int hashCode() {
         return Objects.hash(
-                mName, mMedium, mRssi, mBluetoothAddress, mFastPairModelId, Arrays.hashCode(mData));
+                mName, mMedium, mRssi, mTxPower, mBluetoothAddress,
+                mFastPairModelId, Arrays.hashCode(mData));
     }
 
     /**
@@ -212,6 +220,16 @@
     }
 
     /**
+     * Gets the transmit power in dBm. A value of
+     * android.bluetooth.le.ScanResult#TX_POWER_NOT_PRESENT
+     * indicates that the TX power is not present.
+     */
+    @IntRange(from = -127, to = 126)
+    public int getTxPower() {
+        return mTxPower;
+    }
+
+    /**
      * Gets the Fast Pair identifier. Returns {@code null} if there is no Model ID or this is not a
      * Fast Pair device.
      */
@@ -246,6 +264,7 @@
         @NearbyDevice.Medium
         private int mMedium;
         private int mRssi;
+        private int mTxPower = ScanResult.TX_POWER_NOT_PRESENT;
         @ScanRequest.ScanType int mScanType;
         @Nullable
         private String mFastPairModelId;
@@ -292,12 +311,23 @@
          * @param rssi The received signal strength in dBm.
          */
         @NonNull
-        public Builder setRssi(int rssi) {
+        public Builder setRssi(@IntRange(from = -127, to = 126) int rssi) {
             mRssi = rssi;
             return this;
         }
 
         /**
+         * Sets the txPower.
+         *
+         * @param txPower The transmit power in dBm
+         */
+        @NonNull
+        public Builder setTxPower(@IntRange(from = -127, to = 126) int txPower) {
+            mTxPower = txPower;
+            return this;
+        }
+
+        /**
          * Sets the Fast Pair model Id.
          *
          * @param fastPairModelId Fast Pair device identifier.
@@ -336,8 +366,8 @@
          */
         @NonNull
         public NearbyDeviceParcelable build() {
-            return new NearbyDeviceParcelable(mScanType, mName, mMedium, mRssi, mFastPairModelId,
-                    mBluetoothAddress, mData);
+            return new NearbyDeviceParcelable(mScanType, mName, mMedium, mRssi, mTxPower,
+                    mFastPairModelId, mBluetoothAddress, mData);
         }
     }
 }
diff --git a/nearby/framework/java/android/nearby/NearbyManager.java b/nearby/framework/java/android/nearby/NearbyManager.java
index 4cb2cc8..1c1d59f 100644
--- a/nearby/framework/java/android/nearby/NearbyManager.java
+++ b/nearby/framework/java/android/nearby/NearbyManager.java
@@ -104,6 +104,7 @@
                     .setName(nearbyDeviceParcelable.getName())
                     .addMedium(nearbyDeviceParcelable.getMedium())
                     .setRssi(nearbyDeviceParcelable.getRssi())
+                    .setTxPower(nearbyDeviceParcelable.getTxPower())
                     .setModelId(nearbyDeviceParcelable.getFastPairModelId())
                     .setBluetoothAddress(nearbyDeviceParcelable.getBluetoothAddress())
                     .setData(nearbyDeviceParcelable.getData()).build();
diff --git a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
index a989143..db58476 100644
--- a/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/BleDiscoveryProvider.java
@@ -64,6 +64,7 @@
                     NearbyDeviceParcelable.Builder builder = new NearbyDeviceParcelable.Builder();
                     builder.setMedium(NearbyDevice.Medium.BLE)
                             .setRssi(scanResult.getRssi())
+                            .setTxPower(scanResult.getTxPower())
                             .setBluetoothAddress(scanResult.getDevice().getAddress());
 
                     ScanRecord record = scanResult.getScanRecord();
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
index 82e6615..87fc4cd 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -50,6 +50,7 @@
                 .setName("testDevice")
                 .setMedium(NearbyDevice.Medium.BLE)
                 .setRssi(RSSI)
+                .setTxPower(-90)
                 .setFastPairModelId(FAST_PAIR_MODEL_ID)
                 .setBluetoothAddress(BLUETOOTH_ADDRESS)
                 .setData(SCAN_DATA);
@@ -64,7 +65,7 @@
                 mBuilder.setFastPairModelId(null).setData(null).build();
 
         assertThat(nearbyDeviceParcelable.toString()).isEqualTo(
-                "NearbyDeviceParcelable[name=testDevice, medium=BLE, rssi=-60, "
+                "NearbyDeviceParcelable[name=testDevice, medium=BLE, rssi=-60, txPower=-90, "
                         + "bluetoothAddress="
                         + BLUETOOTH_ADDRESS + ", fastPairModelId=null, data=null]");
     }
@@ -72,7 +73,7 @@
     @Test
     @SdkSuppress(minSdkVersion = 32, codeName = "T")
     public void test_defaultNullFields() {
-        NearbyDeviceParcelable nearbyDeviceParcelable =  new NearbyDeviceParcelable.Builder()
+        NearbyDeviceParcelable nearbyDeviceParcelable = new NearbyDeviceParcelable.Builder()
                 .setMedium(NearbyDevice.Medium.BLE)
                 .setRssi(RSSI)
                 .build();