uwb(service): Implement CR 396 and 346

Supports more range data notification thresholds.

Also, adds a range ntf control capabilities  for the device to expose
what ntf control capabilities are controlled.

Bug: 235355249
Test: atest UwbSupportLibTests ServiceUwbTests
Change-Id: I311ae45345be4f49c471d504a20f18c2e6f71d91
diff --git a/service/java/com/android/server/uwb/config/CapabilityParam.java b/service/java/com/android/server/uwb/config/CapabilityParam.java
index 28fe294..baab7cc 100644
--- a/service/java/com/android/server/uwb/config/CapabilityParam.java
+++ b/service/java/com/android/server/uwb/config/CapabilityParam.java
@@ -160,4 +160,9 @@
     public static final int RANGE_DATA_NTF_CONFIG_ENABLE = 1 << 0;
     public static final int RANGE_DATA_NTF_CONFIG_DISABLE = 1 << 1;
     public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG = 1 << 2;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG = 1 << 3;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG = 1 << 4;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG = 1 << 5;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG = 1 << 6;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG = 1 << 7;
 }
diff --git a/service/java/com/android/server/uwb/config/ConfigParam.java b/service/java/com/android/server/uwb/config/ConfigParam.java
index 99cbc1b..1eeeb2a 100644
--- a/service/java/com/android/server/uwb/config/ConfigParam.java
+++ b/service/java/com/android/server/uwb/config/ConfigParam.java
@@ -61,7 +61,8 @@
     public static final int RANGING_TIME_STRUCT = 0x1A;
     public static final int SLOTS_PER_RR = 0x1B;
     public static final int TX_ADAPTIVE_PAYLOAD_POWER = 0x1C;
-    //public static final int TX_ANTENNA_SELECTION = 0x1D;
+    // TODO: Ensure this value is correct in the final 2.0 specification.
+    public static final int RANGE_DATA_NTF_AOA_BOUND = 0x1D;
     public static final int RESPONDER_SLOT_INDEX = 0x1E;
     public static final int PRF_MODE = 0x1F;
     public static final int SCHEDULED_MODE = 0x22;
@@ -84,6 +85,8 @@
     public static final int STS_LENGTH = 0x35;
     public static final int SESSION_KEY = 0x36;
     public static final int SUBSESSION_KEY = 0x37;
+
+    // Android specific params.
     public static final int NUM_RANGE_MEASUREMENTS = NB_OF_RANGE_MEASUREMENTS;
     public static final int NUM_AOA_AZIMUTH_MEASUREMENTS = NB_OF_AZIMUTH_MEASUREMENTS;
     public static final int NUM_AOA_ELEVATION_MEASUREMENTS = NB_OF_ELEVATION_MEASUREMENTS;
diff --git a/service/java/com/android/server/uwb/data/UwbUciConstants.java b/service/java/com/android/server/uwb/data/UwbUciConstants.java
index 2218bea..000d90d 100644
--- a/service/java/com/android/server/uwb/data/UwbUciConstants.java
+++ b/service/java/com/android/server/uwb/data/UwbUciConstants.java
@@ -111,7 +111,7 @@
             FiraParams.RANGE_DATA_NTF_CONFIG_DISABLE;
     public static final int RANGE_DATA_NTF_CONFIG_ENABLE = FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE;
     public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY =
-            FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+            FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
 
     public static final int RANGING_DEVICE_ROLE_RESPONDER =
             FiraParams.RANGING_DEVICE_ROLE_RESPONDER;
diff --git a/service/java/com/android/server/uwb/params/FiraDecoder.java b/service/java/com/android/server/uwb/params/FiraDecoder.java
index 47f33b4..da49a31 100644
--- a/service/java/com/android/server/uwb/params/FiraDecoder.java
+++ b/service/java/com/android/server/uwb/params/FiraDecoder.java
@@ -45,6 +45,11 @@
 import static com.android.server.uwb.config.CapabilityParam.PROVISIONED_STS_RESPONDER_SPECIFIC_SUBSESSION_KEY;
 import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_DISABLE;
 import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE;
+import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG;
+import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG;
+import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG;
+import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG;
+import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG;
 import static com.android.server.uwb.config.CapabilityParam.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
 import static com.android.server.uwb.config.CapabilityParam.RESPONDER;
 import static com.android.server.uwb.config.CapabilityParam.RSSI_REPORTING;
@@ -338,7 +343,37 @@
                     RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG)) {
                 rangeDataNtfConfigCapabilityFlag.add(
                         FiraParams.RangeDataNtfConfigCapabilityFlag
-                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY);
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG);
+            }
+            if (isBitSet(rangeDataNtfConfigUci,
+                    RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG)) {
+                rangeDataNtfConfigCapabilityFlag.add(
+                        FiraParams.RangeDataNtfConfigCapabilityFlag
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG);
+            }
+            if (isBitSet(rangeDataNtfConfigUci,
+                    RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG)) {
+                rangeDataNtfConfigCapabilityFlag.add(
+                        FiraParams.RangeDataNtfConfigCapabilityFlag
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG);
+            }
+            if (isBitSet(rangeDataNtfConfigUci,
+                    RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG)) {
+                rangeDataNtfConfigCapabilityFlag.add(
+                        FiraParams.RangeDataNtfConfigCapabilityFlag
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG);
+            }
+            if (isBitSet(rangeDataNtfConfigUci,
+                    RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG)) {
+                rangeDataNtfConfigCapabilityFlag.add(
+                        FiraParams.RangeDataNtfConfigCapabilityFlag
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG);
+            }
+            if (isBitSet(rangeDataNtfConfigUci,
+                    RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG)) {
+                rangeDataNtfConfigCapabilityFlag.add(
+                        FiraParams.RangeDataNtfConfigCapabilityFlag
+                                .HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG);
             }
             builder.setRangeDataNtfConfigCapabilities(rangeDataNtfConfigCapabilityFlag);
         } catch (IllegalArgumentException e) {
diff --git a/service/java/com/android/server/uwb/params/FiraEncoder.java b/service/java/com/android/server/uwb/params/FiraEncoder.java
index 60f4ff7..20e0778 100644
--- a/service/java/com/android/server/uwb/params/FiraEncoder.java
+++ b/service/java/com/android/server/uwb/params/FiraEncoder.java
@@ -16,9 +16,15 @@
 
 package com.android.server.uwb.params;
 
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG;
+
 import android.uwb.UwbAddress;
 
 import com.android.server.uwb.config.ConfigParam;
+import com.android.server.uwb.util.UwbUtil;
 
 import com.google.uwb.support.base.Params;
 import com.google.uwb.support.fira.FiraOpenSessionParams;
@@ -41,6 +47,13 @@
         return null;
     }
 
+    private static boolean hasAoaBoundInRangeDataNfConfig(int rangeDataNtfConfig) {
+        return rangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG
+                || rangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG
+                || rangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG
+                || rangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG;
+    }
+
     private TlvBuffer getTlvBufferFromFiraOpenSessionParams(Params baseParam) {
         FiraOpenSessionParams params = (FiraOpenSessionParams) baseParam;
         ByteBuffer dstAddressList = ByteBuffer.allocate(1024);
@@ -51,7 +64,7 @@
         int resultReportConfig = getResultReportConfig(params);
         int rangingRoundControl = getRangingRoundControl(params);
 
-        TlvBuffer tlvBuffer = new TlvBuffer.Builder()
+        TlvBuffer.Builder tlvBufferBuilder = new TlvBuffer.Builder()
                 .putByte(ConfigParam.DEVICE_TYPE, (byte) params.getDeviceType())
                 .putByte(ConfigParam.RANGING_ROUND_USAGE, (byte) params.getRangingRoundUsage())
                 .putByte(ConfigParam.STS_CONFIG, (byte) params.getStsConfig())
@@ -112,9 +125,27 @@
                 .putByte(ConfigParam.NUM_AOA_AZIMUTH_MEASUREMENTS,
                         (byte) params.getNumOfMsrmtFocusOnAoaAzimuth())
                 .putByte(ConfigParam.NUM_AOA_ELEVATION_MEASUREMENTS,
-                        (byte) params.getNumOfMsrmtFocusOnAoaElevation())
-                .build();
-        return tlvBuffer;
+                        (byte) params.getNumOfMsrmtFocusOnAoaElevation());
+        if (hasAoaBoundInRangeDataNfConfig(params.getRangeDataNtfConfig())) {
+            tlvBufferBuilder.putByteArray(ConfigParam.RANGE_DATA_NTF_AOA_BOUND, new byte[]{
+                    // TODO (b/235355249): Verify this conversion. This is using AOA value
+                    // in UwbTwoWayMeasurement to external RangingMeasurement conversion as
+                    // reference.
+                    (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                            UwbUtil.radianTodegree(
+                                    params.getRangeDataNtfAoaAzimuthLower()), 9, 7), 8),
+                    (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                            UwbUtil.radianTodegree(
+                                    params.getRangeDataNtfAoaAzimuthUpper()), 9, 7), 8),
+                    (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                            UwbUtil.radianTodegree(
+                                    params.getRangeDataNtfAoaElevationLower()), 9, 7), 8),
+                    (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                            UwbUtil.radianTodegree(
+                                    params.getRangeDataNtfAoaElevationLower()), 9, 7), 8),
+            });
+        }
+        return tlvBufferBuilder.build();
     }
 
     private TlvBuffer getTlvBufferFromFiraRangingReconfigureParams(Params baseParam) {
@@ -124,6 +155,10 @@
         Integer rangeDataNtfConfig = params.getRangeDataNtfConfig();
         Integer rangeDataProximityNear = params.getRangeDataProximityNear();
         Integer rangeDataProximityFar = params.getRangeDataProximityFar();
+        Double rangeDataAoaAzimuthLower = params.getRangeDataAoaAzimuthLower();
+        Double rangeDataAoaAzimuthUpper = params.getRangeDataAoaAzimuthUpper();
+        Double rangeDataAoaElevationLower = params.getRangeDataAoaElevationLower();
+        Double rangeDataAoaElevationUpper = params.getRangeDataAoaElevationUpper();
 
         if (blockStrideLength != null) {
             tlvBuilder.putByte(ConfigParam.BLOCK_STRIDE_LENGTH,
@@ -145,6 +180,41 @@
                     (short) rangeDataProximityFar.intValue());
         }
 
+        if (rangeDataNtfConfig != null && hasAoaBoundInRangeDataNfConfig(rangeDataNtfConfig)) {
+            if ((rangeDataAoaAzimuthLower != null && rangeDataAoaAzimuthUpper != null)
+                    || (rangeDataAoaElevationLower != null && rangeDataAoaElevationUpper != null)) {
+                rangeDataAoaAzimuthLower = rangeDataAoaAzimuthLower != null
+                        ? rangeDataAoaAzimuthLower
+                        : FiraParams.RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT;
+                rangeDataAoaAzimuthUpper = rangeDataAoaAzimuthUpper != null
+                        ? rangeDataAoaAzimuthUpper
+                        : FiraParams.RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT;
+                rangeDataAoaElevationLower = rangeDataAoaElevationLower != null
+                        ? rangeDataAoaElevationLower
+                        : FiraParams.RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT;
+                rangeDataAoaElevationUpper = rangeDataAoaElevationUpper != null
+                        ? rangeDataAoaElevationUpper
+                        : FiraParams.RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT;
+                tlvBuilder.putByteArray(ConfigParam.RANGE_DATA_NTF_AOA_BOUND, new byte[]{
+                        // TODO (b/235355249): Verify this conversion. This is using AOA value
+                        // in UwbTwoWayMeasurement to external RangingMeasurement conversion as
+                        // reference.
+                        (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                                UwbUtil.radianTodegree(
+                                        rangeDataAoaAzimuthLower.floatValue()), 9, 7), 8),
+                        (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                                UwbUtil.radianTodegree(
+                                        rangeDataAoaAzimuthUpper.floatValue()), 9, 7), 8),
+                        (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                                UwbUtil.radianTodegree(
+                                        rangeDataAoaElevationLower.floatValue()), 9, 7), 8),
+                        (byte) UwbUtil.twos_compliment(UwbUtil.convertFloatToQFormat(
+                                UwbUtil.radianTodegree(
+                                        rangeDataAoaElevationUpper.floatValue()), 9, 7), 8),
+                });
+            }
+        }
+
         return tlvBuilder.build();
     }
 
diff --git a/service/java/com/android/server/uwb/util/UwbUtil.java b/service/java/com/android/server/uwb/util/UwbUtil.java
index 96a9021..d1f94cb 100755
--- a/service/java/com/android/server/uwb/util/UwbUtil.java
+++ b/service/java/com/android/server/uwb/util/UwbUtil.java
@@ -68,6 +68,10 @@
         return (float) ((angleInDegrees) * Math.PI / 180.0);
     }
 
+    public static float radianTodegree(double angleInRadians) {
+        return (float) ((angleInRadians) * 180 / Math.PI);
+    }
+
     /**
      * Fixed point Q format to float conversion. In Q format  Fixed point integer,
      * integer and fractional bits are specified together.
@@ -99,7 +103,7 @@
      * Get Two's complement of a number for signed conversion
      *
      * @param nInput Integer
-     * @param nBits  number of bits in number
+     * @param nBits  number of bits an number
      * @return two complement of given number value
      */
     public static int twos_compliment(int nInput, int nBits) {
diff --git a/service/support_lib/src/com/google/uwb/support/fira/FiraOpenSessionParams.java b/service/support_lib/src/com/google/uwb/support/fira/FiraOpenSessionParams.java
index b6a830b..d17852c 100644
--- a/service/support_lib/src/com/google/uwb/support/fira/FiraOpenSessionParams.java
+++ b/service/support_lib/src/com/google/uwb/support/fira/FiraOpenSessionParams.java
@@ -27,6 +27,7 @@
 import android.uwb.UwbAddress;
 import android.uwb.UwbManager;
 
+import androidx.annotation.FloatRange;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -109,6 +110,10 @@
     @RangeDataNtfConfig private final int mRangeDataNtfConfig;
     private final int mRangeDataNtfProximityNear;
     private final int mRangeDataNtfProximityFar;
+    private double mRangeDataNtfAoaAzimuthLower;
+    private double mRangeDataNtfAoaAzimuthUpper;
+    private double mRangeDataNtfAoaElevationLower;
+    private double mRangeDataNtfAoaElevationUpper;
     private final boolean mHasTimeOfFlightReport;
     private final boolean mHasAngleOfArrivalAzimuthReport;
     private final boolean mHasAngleOfArrivalElevationReport;
@@ -164,6 +169,14 @@
     private static final String KEY_RANGE_DATA_NTF_CONFIG = "range_data_ntf_config";
     private static final String KEY_RANGE_DATA_NTF_PROXIMITY_NEAR = "range_data_ntf_proximity_near";
     private static final String KEY_RANGE_DATA_NTF_PROXIMITY_FAR = "range_data_ntf_proximity_far";
+    private static final String KEY_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER =
+            "range_data_ntf_aoa_azimuth_lower";
+    private static final String KEY_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER =
+            "range_data_ntf_aoa_azimuth_upper";
+    private static final String KEY_RANGE_DATA_NTF_AOA_ELEVATION_LOWER =
+            "range_data_ntf_aoa_elevation_lower";
+    private static final String KEY_RANGE_DATA_NTF_AOA_ELEVATION_UPPER =
+            "range_data_ntf_aoa_elevation_upper";
     private static final String KEY_HAS_TIME_OF_FLIGHT_REPORT = "has_time_of_flight_report";
     private static final String KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT =
             "has_angle_of_arrival_azimuth_report";
@@ -226,6 +239,10 @@
             @RangeDataNtfConfig int rangeDataNtfConfig,
             int rangeDataNtfProximityNear,
             int rangeDataNtfProximityFar,
+            double rangeDataNtfAoaAzimuthLower,
+            double rangeDataNtfAoaAzimuthUpper,
+            double rangeDataNtfAoaElevationLower,
+            double rangeDataNtfAoaElevationUpper,
             boolean hasTimeOfFlightReport,
             boolean hasAngleOfArrivalAzimuthReport,
             boolean hasAngleOfArrivalElevationReport,
@@ -278,6 +295,10 @@
         mRangeDataNtfConfig = rangeDataNtfConfig;
         mRangeDataNtfProximityNear = rangeDataNtfProximityNear;
         mRangeDataNtfProximityFar = rangeDataNtfProximityFar;
+        mRangeDataNtfAoaAzimuthLower = rangeDataNtfAoaAzimuthLower;
+        mRangeDataNtfAoaAzimuthUpper = rangeDataNtfAoaAzimuthUpper;
+        mRangeDataNtfAoaElevationLower = rangeDataNtfAoaElevationLower;
+        mRangeDataNtfAoaElevationUpper = rangeDataNtfAoaElevationUpper;
         mHasTimeOfFlightReport = hasTimeOfFlightReport;
         mHasAngleOfArrivalAzimuthReport = hasAngleOfArrivalAzimuthReport;
         mHasAngleOfArrivalElevationReport = hasAngleOfArrivalElevationReport;
@@ -490,6 +511,22 @@
         return mRangeDataNtfProximityFar;
     }
 
+    public double getRangeDataNtfAoaAzimuthLower() {
+        return mRangeDataNtfAoaAzimuthLower;
+    }
+
+    public double getRangeDataNtfAoaAzimuthUpper() {
+        return mRangeDataNtfAoaAzimuthUpper;
+    }
+
+    public double getRangeDataNtfAoaElevationLower() {
+        return mRangeDataNtfAoaElevationLower;
+    }
+
+    public double getRangeDataNtfAoaElevationUpper() {
+        return mRangeDataNtfAoaElevationUpper;
+    }
+
     public boolean hasTimeOfFlightReport() {
         return mHasTimeOfFlightReport;
     }
@@ -610,6 +647,10 @@
         bundle.putInt(KEY_RANGE_DATA_NTF_CONFIG, mRangeDataNtfConfig);
         bundle.putInt(KEY_RANGE_DATA_NTF_PROXIMITY_NEAR, mRangeDataNtfProximityNear);
         bundle.putInt(KEY_RANGE_DATA_NTF_PROXIMITY_FAR, mRangeDataNtfProximityFar);
+        bundle.putDouble(KEY_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER, mRangeDataNtfAoaAzimuthLower);
+        bundle.putDouble(KEY_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER, mRangeDataNtfAoaAzimuthUpper);
+        bundle.putDouble(KEY_RANGE_DATA_NTF_AOA_ELEVATION_LOWER, mRangeDataNtfAoaElevationLower);
+        bundle.putDouble(KEY_RANGE_DATA_NTF_AOA_ELEVATION_UPPER, mRangeDataNtfAoaElevationUpper);
         bundle.putBoolean(KEY_HAS_TIME_OF_FLIGHT_REPORT, mHasTimeOfFlightReport);
         bundle.putBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT, mHasAngleOfArrivalAzimuthReport);
         bundle.putBoolean(
@@ -702,6 +743,14 @@
                 .setRangeDataNtfConfig(bundle.getInt(KEY_RANGE_DATA_NTF_CONFIG))
                 .setRangeDataNtfProximityNear(bundle.getInt(KEY_RANGE_DATA_NTF_PROXIMITY_NEAR))
                 .setRangeDataNtfProximityFar(bundle.getInt(KEY_RANGE_DATA_NTF_PROXIMITY_FAR))
+                .setRangeDataNtfAoaAzimuthLower(
+                        bundle.getDouble(KEY_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER))
+                .setRangeDataNtfAoaAzimuthUpper(
+                        bundle.getDouble(KEY_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER))
+                .setRangeDataNtfAoaElevationLower(
+                        bundle.getDouble(KEY_RANGE_DATA_NTF_AOA_ELEVATION_LOWER))
+                .setRangeDataNtfAoaElevationUpper(
+                        bundle.getDouble(KEY_RANGE_DATA_NTF_AOA_ELEVATION_UPPER))
                 .setHasTimeOfFlightReport(bundle.getBoolean(KEY_HAS_TIME_OF_FLIGHT_REPORT))
                 .setHasAngleOfArrivalAzimuthReport(
                         bundle.getBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT))
@@ -847,10 +896,22 @@
         @RangeDataNtfConfig private int mRangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE;
 
         /** UCI spec default: 0 (No low-bound filtering) */
-        private int mRangeDataNtfProximityNear = 0;
+        private int mRangeDataNtfProximityNear = RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT;
 
         /** UCI spec default: 20000 cm (or 200 meters) */
-        private int mRangeDataNtfProximityFar = 20000;
+        private int mRangeDataNtfProximityFar = RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT;
+
+        /** UCI spec default: -180 (No low-bound filtering) */
+        private double mRangeDataNtfAoaAzimuthLower = RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT;
+
+        /** UCI spec default: +180 (No upper-bound filtering) */
+        private double mRangeDataNtfAoaAzimuthUpper = RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT;
+
+        /** UCI spec default: -180 (No low-bound filtering) */
+        private double mRangeDataNtfAoaElevationLower = RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT;
+
+        /** UCI spec default: +180 (No upper-bound filtering) */
+        private double mRangeDataNtfAoaElevationUpper = RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT;
 
         /** UCI spec default: RESULT_REPORT_CONFIG bit 0 is 1 */
         private boolean mHasTimeOfFlightReport = true;
@@ -919,6 +980,10 @@
             mRangeDataNtfConfig = builder.mRangeDataNtfConfig;
             mRangeDataNtfProximityNear = builder.mRangeDataNtfProximityNear;
             mRangeDataNtfProximityFar = builder.mRangeDataNtfProximityFar;
+            mRangeDataNtfAoaAzimuthLower = builder.mRangeDataNtfAoaAzimuthLower;
+            mRangeDataNtfAoaAzimuthUpper = builder.mRangeDataNtfAoaAzimuthUpper;
+            mRangeDataNtfAoaElevationLower = builder.mRangeDataNtfAoaElevationLower;
+            mRangeDataNtfAoaElevationUpper = builder.mRangeDataNtfAoaElevationUpper;
             mHasTimeOfFlightReport = builder.mHasTimeOfFlightReport;
             mHasAngleOfArrivalAzimuthReport = builder.mHasAngleOfArrivalAzimuthReport;
             mHasAngleOfArrivalElevationReport = builder.mHasAngleOfArrivalElevationReport;
@@ -971,6 +1036,10 @@
             mRangeDataNtfConfig = params.mRangeDataNtfConfig;
             mRangeDataNtfProximityNear = params.mRangeDataNtfProximityNear;
             mRangeDataNtfProximityFar = params.mRangeDataNtfProximityFar;
+            mRangeDataNtfAoaAzimuthLower = params.mRangeDataNtfAoaAzimuthLower;
+            mRangeDataNtfAoaAzimuthUpper = params.mRangeDataNtfAoaAzimuthUpper;
+            mRangeDataNtfAoaElevationLower = params.mRangeDataNtfAoaElevationLower;
+            mRangeDataNtfAoaElevationUpper = params.mRangeDataNtfAoaElevationUpper;
             mHasTimeOfFlightReport = params.mHasTimeOfFlightReport;
             mHasAngleOfArrivalAzimuthReport = params.mHasAngleOfArrivalAzimuthReport;
             mHasAngleOfArrivalElevationReport = params.mHasAngleOfArrivalElevationReport;
@@ -1202,17 +1271,53 @@
         }
 
         public FiraOpenSessionParams.Builder setRangeDataNtfProximityNear(
-                int rangeDataNtfProximityNear) {
+                @IntRange(from = RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT,
+                        to = RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT)
+                        int rangeDataNtfProximityNear) {
             mRangeDataNtfProximityNear = rangeDataNtfProximityNear;
             return this;
         }
 
         public FiraOpenSessionParams.Builder setRangeDataNtfProximityFar(
-                int rangeDataNtfProximityFar) {
+                @IntRange(from = RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT,
+                        to = RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT)
+                        int rangeDataNtfProximityFar) {
             mRangeDataNtfProximityFar = rangeDataNtfProximityFar;
             return this;
         }
 
+        public FiraOpenSessionParams.Builder setRangeDataNtfAoaAzimuthLower(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT)
+                        double rangeDataNtfAoaAzimuthLower) {
+            mRangeDataNtfAoaAzimuthLower = rangeDataNtfAoaAzimuthLower;
+            return this;
+        }
+
+        public FiraOpenSessionParams.Builder setRangeDataNtfAoaAzimuthUpper(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT)
+                        double rangeDataNtfAoaAzimuthUpper) {
+            mRangeDataNtfAoaAzimuthUpper = rangeDataNtfAoaAzimuthUpper;
+            return this;
+        }
+
+        public FiraOpenSessionParams.Builder setRangeDataNtfAoaElevationLower(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT)
+                        double rangeDataNtfAoaElevationLower) {
+            mRangeDataNtfAoaElevationLower = rangeDataNtfAoaElevationLower;
+            return this;
+        }
+
+        public FiraOpenSessionParams.Builder setRangeDataNtfAoaElevationUpper(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT)
+                        double rangeDataNtfAoaElevationUpper) {
+            mRangeDataNtfAoaElevationUpper = rangeDataNtfAoaElevationUpper;
+            return this;
+        }
+
         public FiraOpenSessionParams.Builder setHasTimeOfFlightReport(
                 boolean hasTimeOfFlightReport) {
             mHasTimeOfFlightReport = hasTimeOfFlightReport;
@@ -1324,10 +1429,69 @@
             }
         }
 
+        private void checkRangeDataNtfConfig() {
+            if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_DISABLE) {
+                checkArgument(mRangeDataNtfProximityNear
+                        == RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT);
+                checkArgument(mRangeDataNtfProximityFar
+                        == RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT);
+                checkArgument(mRangeDataNtfAoaAzimuthLower
+                        == RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaAzimuthUpper
+                        == RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaElevationLower
+                        == RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaElevationUpper
+                        == RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT);
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG
+                    || mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG) {
+                checkArgument(
+                        mRangeDataNtfProximityNear != RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT
+                        || mRangeDataNtfProximityFar != RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT);
+                checkArgument(mRangeDataNtfAoaAzimuthLower
+                        == RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaAzimuthUpper
+                        == RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaElevationLower
+                        == RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT);
+                checkArgument(mRangeDataNtfAoaElevationUpper
+                        == RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT);
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG
+                    || mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG) {
+                checkArgument(mRangeDataNtfProximityNear
+                        == RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT);
+                checkArgument(mRangeDataNtfProximityFar
+                        == RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT);
+                checkArgument(mRangeDataNtfAoaAzimuthLower
+                            != RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT
+                        || mRangeDataNtfAoaAzimuthUpper
+                            != RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT
+                        || mRangeDataNtfAoaElevationLower
+                            != RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT
+                        || mRangeDataNtfAoaElevationUpper
+                            != RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT);
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG
+                    || mRangeDataNtfConfig
+                    == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG) {
+                checkArgument(
+                        mRangeDataNtfProximityNear != RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT
+                        || mRangeDataNtfProximityFar != RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT
+                        || mRangeDataNtfAoaAzimuthLower
+                            != RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT
+                        || mRangeDataNtfAoaAzimuthUpper
+                            != RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT
+                        || mRangeDataNtfAoaElevationLower
+                            != RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT
+                        || mRangeDataNtfAoaElevationUpper
+                            != RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT);
+            }
+        }
+
         public FiraOpenSessionParams build() {
             checkAddress();
             checkStsConfig();
             checkInterleavingRatio();
+            checkRangeDataNtfConfig();
             return new FiraOpenSessionParams(
                     mProtocolVersion.get(),
                     mSessionId.get(),
@@ -1373,6 +1537,10 @@
                     mRangeDataNtfConfig,
                     mRangeDataNtfProximityNear,
                     mRangeDataNtfProximityFar,
+                    mRangeDataNtfAoaAzimuthLower,
+                    mRangeDataNtfAoaAzimuthUpper,
+                    mRangeDataNtfAoaElevationLower,
+                    mRangeDataNtfAoaElevationUpper,
                     mHasTimeOfFlightReport,
                     mHasAngleOfArrivalAzimuthReport,
                     mHasAngleOfArrivalElevationReport,
diff --git a/service/support_lib/src/com/google/uwb/support/fira/FiraParams.java b/service/support_lib/src/com/google/uwb/support/fira/FiraParams.java
index 4c22dfe..3c572c1 100644
--- a/service/support_lib/src/com/google/uwb/support/fira/FiraParams.java
+++ b/service/support_lib/src/com/google/uwb/support/fira/FiraParams.java
@@ -381,13 +381,23 @@
             value = {
                 RANGE_DATA_NTF_CONFIG_DISABLE,
                 RANGE_DATA_NTF_CONFIG_ENABLE,
-                RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY,
+                RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG,
+                RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG,
+                RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG,
+                RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG,
+                RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG,
+                RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG,
             })
     public @interface RangeDataNtfConfig {}
 
     public static final int RANGE_DATA_NTF_CONFIG_DISABLE = 0;
     public static final int RANGE_DATA_NTF_CONFIG_ENABLE = 1;
-    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY = 2;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG = 2;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG = 3;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG = 4;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG = 5;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG = 6;
+    public static final int RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG = 7;
 
     /** MAC address mode: short (2 bytes) or extended (8 bytes) */
     @IntDef(
@@ -547,6 +557,13 @@
     public static final int DEVICE_CLASS_2 = 2; // Controller
     public static final int DEVICE_CLASS_3 = 3; // Controlee
 
+    public static final int RANGE_DATA_NTF_PROXIMITY_NEAR_DEFAULT = 0;
+    public static final int RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT = 20000;
+    public static final double RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT = -Math.PI;
+    public static final double RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT = Math.PI;
+    public static final double RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT = -Math.PI;
+    public static final double RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT = Math.PI;
+
     public enum AoaCapabilityFlag implements FlagEnum {
         HAS_AZIMUTH_SUPPORT(1),
         HAS_ELEVATION_SUPPORT(1 << 1),
@@ -759,8 +776,20 @@
     public enum RangeDataNtfConfigCapabilityFlag implements FlagEnum {
         HAS_RANGE_DATA_NTF_CONFIG_DISABLE(1 << RANGE_DATA_NTF_CONFIG_DISABLE),
         HAS_RANGE_DATA_NTF_CONFIG_ENABLE(1 << RANGE_DATA_NTF_CONFIG_ENABLE),
-        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY(
-                1 << RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY);
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG),
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG),
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG),
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG),
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG),
+        HAS_RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG(
+                1 << RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG);
+
+
 
         private final long mValue;
 
diff --git a/service/support_lib/src/com/google/uwb/support/fira/FiraRangingReconfigureParams.java b/service/support_lib/src/com/google/uwb/support/fira/FiraRangingReconfigureParams.java
index a203dde..25aa83b 100644
--- a/service/support_lib/src/com/google/uwb/support/fira/FiraRangingReconfigureParams.java
+++ b/service/support_lib/src/com/google/uwb/support/fira/FiraRangingReconfigureParams.java
@@ -24,6 +24,7 @@
 import android.uwb.RangingSession;
 import android.uwb.UwbAddress;
 
+import androidx.annotation.FloatRange;
 import androidx.annotation.Nullable;
 
 /**
@@ -44,6 +45,10 @@
     @Nullable @RangeDataNtfConfig private final Integer mRangeDataNtfConfig;
     @Nullable private final Integer mRangeDataProximityNear;
     @Nullable private final Integer mRangeDataProximityFar;
+    @Nullable private final Double mRangeDataAoaAzimuthLower;
+    @Nullable private final Double mRangeDataAoaAzimuthUpper;
+    @Nullable private final Double mRangeDataAoaElevationLower;
+    @Nullable private final Double mRangeDataAoaElevationUpper;
 
     private static final String KEY_ACTION = "action";
     private static final String KEY_MAC_ADDRESS_MODE = "mac_address_mode";
@@ -55,6 +60,14 @@
             "update_range_data_proximity_near";
     private static final String KEY_UPDATE_RANGE_DATA_NTF_PROXIMITY_FAR =
             "update_range_data_proximity_far";
+    private static final String KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER =
+            "range_data_aoa_azimuth_lower";
+    private static final String KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER =
+            "range_data_aoa_azimuth_upper";
+    private static final String KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_LOWER =
+            "range_data_aoa_elevation_lower";
+    private static final String KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_UPPER =
+            "range_data_aoa_elevation_upper";
 
     private FiraRangingReconfigureParams(
             @Nullable @MulticastListUpdateAction Integer action,
@@ -63,7 +76,11 @@
             @Nullable Integer blockStrideLength,
             @Nullable Integer rangeDataNtfConfig,
             @Nullable Integer rangeDataProximityNear,
-            @Nullable Integer rangeDataProximityFar) {
+            @Nullable Integer rangeDataProximityFar,
+            @Nullable Double rangeDataAoaAzimuthLower,
+            @Nullable Double rangeDataAoaAzimuthUpper,
+            @Nullable Double rangeDataAoaElevationLower,
+            @Nullable Double rangeDataAoaElevationUpper) {
         mAction = action;
         mAddressList = addressList;
         mSubSessionIdList = subSessionIdList;
@@ -71,6 +88,10 @@
         mRangeDataNtfConfig = rangeDataNtfConfig;
         mRangeDataProximityNear = rangeDataProximityNear;
         mRangeDataProximityFar = rangeDataProximityFar;
+        mRangeDataAoaAzimuthLower = rangeDataAoaAzimuthLower;
+        mRangeDataAoaAzimuthUpper = rangeDataAoaAzimuthUpper;
+        mRangeDataAoaElevationLower = rangeDataAoaElevationLower;
+        mRangeDataAoaElevationUpper = rangeDataAoaElevationUpper;
     }
 
     @Override
@@ -114,6 +135,26 @@
         return mRangeDataProximityFar;
     }
 
+    @Nullable
+    public Double getRangeDataAoaAzimuthLower() {
+        return mRangeDataAoaAzimuthLower;
+    }
+
+    @Nullable
+    public Double getRangeDataAoaAzimuthUpper() {
+        return mRangeDataAoaAzimuthUpper;
+    }
+
+    @Nullable
+    public Double getRangeDataAoaElevationLower() {
+        return mRangeDataAoaElevationLower;
+    }
+
+    @Nullable
+    public Double getRangeDataAoaElevationUpper() {
+        return mRangeDataAoaElevationUpper;
+    }
+
     @Override
     public PersistableBundle toBundle() {
         PersistableBundle bundle = super.toBundle();
@@ -151,6 +192,26 @@
             bundle.putInt(KEY_UPDATE_RANGE_DATA_NTF_PROXIMITY_FAR, mRangeDataProximityFar);
         }
 
+        if (mRangeDataAoaAzimuthLower != null) {
+            bundle.putDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER,
+                    mRangeDataAoaAzimuthLower);
+        }
+
+        if (mRangeDataAoaAzimuthUpper != null) {
+            bundle.putDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER,
+                    mRangeDataAoaAzimuthUpper);
+        }
+
+        if (mRangeDataAoaElevationLower != null) {
+            bundle.putDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_LOWER,
+                    mRangeDataAoaElevationLower);
+        }
+
+        if (mRangeDataAoaElevationUpper != null) {
+            bundle.putDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_UPPER,
+                    mRangeDataAoaElevationUpper);
+        }
+
         return bundle;
     }
 
@@ -205,6 +266,25 @@
                     bundle.getInt(KEY_UPDATE_RANGE_DATA_NTF_PROXIMITY_FAR));
         }
 
+        if (bundle.containsKey(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER)) {
+            builder.setRangeDataAoaAzimuthLower(
+                    bundle.getDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_LOWER));
+        }
+
+        if (bundle.containsKey(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER)) {
+            builder.setRangeDataAoaAzimuthUpper(
+                    bundle.getDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_AZIMUTH_UPPER));
+        }
+
+        if (bundle.containsKey(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_LOWER)) {
+            builder.setRangeDataAoaElevationLower(
+                    bundle.getDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_LOWER));
+        }
+
+        if (bundle.containsKey(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_UPPER)) {
+            builder.setRangeDataAoaElevationUpper(
+                    bundle.getDouble(KEY_UPDATE_RANGE_DATA_NTF_AOA_ELEVATION_UPPER));
+        }
         return builder.build();
     }
 
@@ -219,6 +299,10 @@
         @Nullable private Integer mRangeDataNtfConfig = null;
         @Nullable private Integer mRangeDataProximityNear = null;
         @Nullable private Integer mRangeDataProximityFar = null;
+        @Nullable private Double mRangeDataAoaAzimuthLower = null;
+        @Nullable private Double mRangeDataAoaAzimuthUpper = null;
+        @Nullable private Double mRangeDataAoaElevationLower = null;
+        @Nullable private Double mRangeDataAoaElevationUpper = null;
 
         public FiraRangingReconfigureParams.Builder setAction(
                 @MulticastListUpdateAction int action) {
@@ -258,6 +342,38 @@
             return this;
         }
 
+        public Builder setRangeDataAoaAzimuthLower(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT)
+                        double rangeDataAoaAzimuthLower) {
+            mRangeDataAoaAzimuthLower = rangeDataAoaAzimuthLower;
+            return this;
+        }
+
+        public Builder setRangeDataAoaAzimuthUpper(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_AZIMUTH_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_AZIMUTH_UPPER_DEFAULT)
+                        double rangeDataAoaAzimuthUpper) {
+            mRangeDataAoaAzimuthUpper = rangeDataAoaAzimuthUpper;
+            return this;
+        }
+
+        public Builder setRangeDataAoaElevationLower(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT)
+                        double rangeDataAoaElevationLower) {
+            mRangeDataAoaElevationLower = rangeDataAoaElevationLower;
+            return this;
+        }
+
+        public Builder setRangeDataAoaElevationUpper(
+                @FloatRange(from = RANGE_DATA_NTF_AOA_ELEVATION_LOWER_DEFAULT,
+                        to = RANGE_DATA_NTF_AOA_ELEVATION_UPPER_DEFAULT)
+                        double rangeDataAoaElevationUpper) {
+            mRangeDataAoaElevationUpper = rangeDataAoaElevationUpper;
+            return this;
+        }
+
         private void checkAddressList() {
             checkArgument(mAddressList != null && mAddressList.length > 0);
             for (UwbAddress uwbAddress : mAddressList) {
@@ -269,6 +385,45 @@
                     mSubSessionIdList == null || mSubSessionIdList.length == mAddressList.length);
         }
 
+        private void checkRangeDataNtfConfig() {
+            if (mRangeDataNtfConfig == null) {
+                return;
+            }
+            if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_DISABLE) {
+                checkArgument(mRangeDataProximityNear == null);
+                checkArgument(mRangeDataProximityFar == null);
+                checkArgument(mRangeDataAoaAzimuthLower == null);
+                checkArgument(mRangeDataAoaAzimuthUpper == null);
+                checkArgument(mRangeDataAoaElevationLower == null);
+                checkArgument(mRangeDataAoaElevationUpper == null);
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG
+                    || mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_EDGE_TRIG) {
+                checkArgument(mRangeDataProximityNear != null
+                        || mRangeDataProximityFar != null);
+                checkArgument(mRangeDataAoaAzimuthLower == null);
+                checkArgument(mRangeDataAoaAzimuthUpper == null);
+                checkArgument(mRangeDataAoaElevationLower == null);
+                checkArgument(mRangeDataAoaElevationUpper == null);
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_LEVEL_TRIG
+                    || mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_AOA_EDGE_TRIG) {
+                checkArgument(mRangeDataProximityNear == null);
+                checkArgument(mRangeDataProximityFar == null);
+                checkArgument((mRangeDataAoaAzimuthLower != null
+                        && mRangeDataAoaAzimuthUpper != null)
+                        || (mRangeDataAoaElevationLower != null
+                        && mRangeDataAoaElevationUpper != null));
+            } else if (mRangeDataNtfConfig == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG
+                    || mRangeDataNtfConfig
+                    == RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG) {
+                checkArgument(mRangeDataProximityNear != null
+                        || mRangeDataProximityFar != null
+                        || (mRangeDataAoaAzimuthLower != null
+                            && mRangeDataAoaAzimuthUpper != null)
+                        || (mRangeDataAoaElevationLower != null
+                            && mRangeDataAoaElevationUpper != null));
+            }
+        }
+
         public FiraRangingReconfigureParams build() {
             if (mAction != null) {
                 checkAddressList();
@@ -277,13 +432,22 @@
                         mBlockStrideLength == null
                                 && mRangeDataNtfConfig == null
                                 && mRangeDataProximityNear == null
-                                && mRangeDataProximityFar == null);
+                                && mRangeDataProximityFar == null
+                                && mRangeDataAoaAzimuthLower == null
+                                && mRangeDataAoaAzimuthUpper == null
+                                && mRangeDataAoaElevationLower == null
+                                && mRangeDataAoaElevationUpper == null);
             } else {
+                checkRangeDataNtfConfig();
                 checkArgument(
                         mBlockStrideLength != null
                                 || mRangeDataNtfConfig != null
                                 || mRangeDataProximityNear != null
-                                || mRangeDataProximityFar != null);
+                                || mRangeDataProximityFar != null
+                                || mRangeDataAoaAzimuthLower == null
+                                || mRangeDataAoaAzimuthUpper == null
+                                || mRangeDataAoaElevationLower == null
+                                || mRangeDataAoaElevationUpper == null);
             }
 
             return new FiraRangingReconfigureParams(
@@ -293,7 +457,11 @@
                     mBlockStrideLength,
                     mRangeDataNtfConfig,
                     mRangeDataProximityNear,
-                    mRangeDataProximityFar);
+                    mRangeDataProximityFar,
+                    mRangeDataAoaAzimuthLower,
+                    mRangeDataAoaAzimuthUpper,
+                    mRangeDataAoaElevationLower,
+                    mRangeDataAoaElevationUpper);
         }
     }
 }
diff --git a/service/support_lib/test/FiraTests.java b/service/support_lib/test/FiraTests.java
index cb7b13c..07483f2 100644
--- a/service/support_lib/test/FiraTests.java
+++ b/service/support_lib/test/FiraTests.java
@@ -28,7 +28,8 @@
 import static com.google.uwb.support.fira.FiraParams.PREAMBLE_DURATION_T32_SYMBOLS;
 import static com.google.uwb.support.fira.FiraParams.PRF_MODE_HPRF;
 import static com.google.uwb.support.fira.FiraParams.PSDU_DATA_RATE_7M80;
-import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_INITIATOR;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLEE;
 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE;
@@ -120,9 +121,13 @@
         boolean isKeyRotationEnabled = true;
         int keyRotationRate = 15;
         int aoaResultRequest = AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED;
-        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG;
         int rangeDataNtfProximityNear = 50;
         int rangeDataNtfProximityFar = 200;
+        double rangeDataNtfAoaAzimuthLower = -0.5;
+        double rangeDataNtfAoaAzimuthUpper = +1.5;
+        double rangeDataNtfAoaElevationLower = -1.5;
+        double rangeDataNtfAoaElevationUpper = +2.5;
         boolean hasTimeOfFlightReport = true;
         boolean hasAngleOfArrivalAzimuthReport = true;
         boolean hasAngleOfArrivalElevationReport = true;
@@ -177,6 +182,10 @@
                         .setRangeDataNtfConfig(rangeDataNtfConfig)
                         .setRangeDataNtfProximityNear(rangeDataNtfProximityNear)
                         .setRangeDataNtfProximityFar(rangeDataNtfProximityFar)
+                        .setRangeDataNtfAoaAzimuthLower(rangeDataNtfAoaAzimuthLower)
+                        .setRangeDataNtfAoaAzimuthUpper(rangeDataNtfAoaAzimuthUpper)
+                        .setRangeDataNtfAoaElevationLower(rangeDataNtfAoaElevationLower)
+                        .setRangeDataNtfAoaElevationUpper(rangeDataNtfAoaElevationUpper)
                         .setHasTimeOfFlightReport(hasTimeOfFlightReport)
                         .setHasAngleOfArrivalAzimuthReport(hasAngleOfArrivalAzimuthReport)
                         .setHasAngleOfArrivalElevationReport(hasAngleOfArrivalElevationReport)
@@ -236,6 +245,12 @@
         assertEquals(params.getRangeDataNtfConfig(), rangeDataNtfConfig);
         assertEquals(params.getRangeDataNtfProximityNear(), rangeDataNtfProximityNear);
         assertEquals(params.getRangeDataNtfProximityFar(), rangeDataNtfProximityFar);
+        assertEquals(params.getRangeDataNtfAoaAzimuthLower(), rangeDataNtfAoaAzimuthLower, 0.0d);
+        assertEquals(params.getRangeDataNtfAoaAzimuthUpper(), rangeDataNtfAoaAzimuthUpper, 0.0d);
+        assertEquals(params.getRangeDataNtfAoaElevationLower(), rangeDataNtfAoaElevationLower,
+                0.0d);
+        assertEquals(params.getRangeDataNtfAoaElevationUpper(), rangeDataNtfAoaElevationUpper,
+                0.0d);
         assertEquals(params.hasTimeOfFlightReport(), hasTimeOfFlightReport);
         assertEquals(params.hasAngleOfArrivalAzimuthReport(), hasAngleOfArrivalAzimuthReport);
         assertEquals(params.hasAngleOfArrivalElevationReport(), hasAngleOfArrivalElevationReport);
@@ -291,8 +306,16 @@
         assertEquals(fromBundle.getKeyRotationRate(), keyRotationRate);
         assertEquals(fromBundle.getAoaResultRequest(), aoaResultRequest);
         assertEquals(fromBundle.getRangeDataNtfConfig(), rangeDataNtfConfig);
-        assertEquals(fromBundle.getRangeDataNtfProximityNear(), rangeDataNtfProximityNear);
-        assertEquals(fromBundle.getRangeDataNtfProximityFar(), rangeDataNtfProximityFar);
+        assertEquals(fromBundle.getRangeDataNtfProximityNear(), rangeDataNtfProximityNear, 0.0d);
+        assertEquals(fromBundle.getRangeDataNtfProximityFar(), rangeDataNtfProximityFar, 0.0d);
+        assertEquals(fromBundle.getRangeDataNtfAoaAzimuthLower(), rangeDataNtfAoaAzimuthLower,
+                0.0d);
+        assertEquals(fromBundle.getRangeDataNtfAoaAzimuthUpper(), rangeDataNtfAoaAzimuthUpper,
+                0.0d);
+        assertEquals(fromBundle.getRangeDataNtfAoaElevationLower(), rangeDataNtfAoaElevationLower,
+                0.0d);
+        assertEquals(fromBundle.getRangeDataNtfAoaElevationUpper(), rangeDataNtfAoaElevationUpper,
+                0.0d);
         assertEquals(fromBundle.hasTimeOfFlightReport(), hasTimeOfFlightReport);
         assertEquals(fromBundle.hasAngleOfArrivalAzimuthReport(), hasAngleOfArrivalAzimuthReport);
         assertEquals(
@@ -316,9 +339,13 @@
         UwbAddress uwbAddress2 = UwbAddress.fromBytes(new byte[] {4, 5});
         UwbAddress[] addressList = new UwbAddress[] {uwbAddress1, uwbAddress2};
         int blockStrideLength = 5;
-        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_EDGE_TRIG;
         int rangeDataProximityNear = 100;
         int rangeDataProximityFar = 500;
+        double rangeDataAoaAzimuthLower = -0.5;
+        double rangeDataAoaAzimuthUpper = +1.5;
+        double rangeDataAoaElevationLower = -1.5;
+        double rangeDataAoaElevationUpper = +2.5;
 
         int[] subSessionIdList = new int[] {3, 4};
         FiraRangingReconfigureParams params =
@@ -345,16 +372,37 @@
                         .setRangeDataNtfConfig(rangeDataNtfConfig)
                         .setRangeDataProximityNear(rangeDataProximityNear)
                         .setRangeDataProximityFar(rangeDataProximityFar)
+                        .setRangeDataAoaAzimuthLower(rangeDataAoaAzimuthLower)
+                        .setRangeDataAoaAzimuthUpper(rangeDataAoaAzimuthUpper)
+                        .setRangeDataAoaElevationLower(rangeDataAoaElevationLower)
+                        .setRangeDataAoaElevationUpper(rangeDataAoaElevationUpper)
                         .build();
         assertEquals((int) params.getBlockStrideLength(), blockStrideLength);
         assertEquals((int) params.getRangeDataNtfConfig(), rangeDataNtfConfig);
         assertEquals((int) params.getRangeDataProximityNear(), rangeDataProximityNear);
         assertEquals((int) params.getRangeDataProximityFar(), rangeDataProximityFar);
+        assertEquals((double) params.getRangeDataAoaAzimuthLower(), rangeDataAoaAzimuthLower,
+                0.0d);
+        assertEquals((double) params.getRangeDataAoaAzimuthUpper(), rangeDataAoaAzimuthUpper,
+                0.0d);
+        assertEquals((double) params.getRangeDataAoaElevationLower(), rangeDataAoaElevationLower,
+                0.0d);
+        assertEquals((double) params.getRangeDataAoaElevationUpper(), rangeDataAoaElevationUpper,
+                0.0d);
+
         fromBundle = FiraRangingReconfigureParams.fromBundle(params.toBundle());
         assertEquals((int) fromBundle.getBlockStrideLength(), blockStrideLength);
         assertEquals((int) fromBundle.getRangeDataNtfConfig(), rangeDataNtfConfig);
         assertEquals((int) fromBundle.getRangeDataProximityNear(), rangeDataProximityNear);
         assertEquals((int) fromBundle.getRangeDataProximityFar(), rangeDataProximityFar);
+        assertEquals((double) fromBundle.getRangeDataAoaAzimuthLower(), rangeDataAoaAzimuthLower,
+                0.0d);
+        assertEquals((double) fromBundle.getRangeDataAoaAzimuthUpper(), rangeDataAoaAzimuthUpper,
+                0.0d);
+        assertEquals((double) fromBundle.getRangeDataAoaElevationLower(),
+                rangeDataAoaElevationLower, 0.0d);
+        assertEquals((double) fromBundle.getRangeDataAoaElevationUpper(),
+                rangeDataAoaElevationUpper, 0.0d);
 
         verifyProtocolPresent(params);
         verifyBundlesEqual(params, fromBundle);
diff --git a/service/tests/src/com/android/server/uwb/UwbConfigurationManagerTest.java b/service/tests/src/com/android/server/uwb/UwbConfigurationManagerTest.java
index 0372810..d6cffe4 100644
--- a/service/tests/src/com/android/server/uwb/UwbConfigurationManagerTest.java
+++ b/service/tests/src/com/android/server/uwb/UwbConfigurationManagerTest.java
@@ -26,7 +26,7 @@
 import static com.google.uwb.support.fira.FiraParams.PREAMBLE_DURATION_T32_SYMBOLS;
 import static com.google.uwb.support.fira.FiraParams.PRF_MODE_HPRF;
 import static com.google.uwb.support.fira.FiraParams.PSDU_DATA_RATE_7M80;
-import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_INITIATOR;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLEE;
 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE;
@@ -188,7 +188,7 @@
         boolean isKeyRotationEnabled = true;
         int keyRotationRate = 15;
         int aoaResultRequest = AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED;
-        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+        int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
         int rangeDataNtfProximityNear = 50;
         int rangeDataNtfProximityFar = 200;
         boolean hasTimeOfFlightReport = true;
diff --git a/service/tests/src/com/android/server/uwb/UwbServiceCoreTest.java b/service/tests/src/com/android/server/uwb/UwbServiceCoreTest.java
index 725c264..4ab3b88 100644
--- a/service/tests/src/com/android/server/uwb/UwbServiceCoreTest.java
+++ b/service/tests/src/com/android/server/uwb/UwbServiceCoreTest.java
@@ -27,7 +27,7 @@
 import static com.google.uwb.support.fira.FiraParams.MULTICAST_LIST_UPDATE_ACTION_ADD;
 import static com.google.uwb.support.fira.FiraParams.MULTICAST_LIST_UPDATE_ACTION_DELETE;
 import static com.google.uwb.support.fira.FiraParams.MULTI_NODE_MODE_UNICAST;
-import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_RESPONDER;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLLER;
 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE;
@@ -412,7 +412,7 @@
         final FiraRangingReconfigureParams parameters =
                 new FiraRangingReconfigureParams.Builder()
                         .setBlockStrideLength(6)
-                        .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY)
+                        .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG)
                         .setRangeDataProximityFar(6)
                         .setRangeDataProximityNear(4)
                         .build();
diff --git a/service/tests/src/com/android/server/uwb/UwbServiceImplTest.java b/service/tests/src/com/android/server/uwb/UwbServiceImplTest.java
index 7fc9df6..27cfc42 100644
--- a/service/tests/src/com/android/server/uwb/UwbServiceImplTest.java
+++ b/service/tests/src/com/android/server/uwb/UwbServiceImplTest.java
@@ -24,7 +24,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.uwb.support.fira.FiraParams.PACS_PROFILE_SERVICE_ID;
-import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
@@ -231,7 +231,7 @@
         final FiraRangingReconfigureParams parameters =
                 new FiraRangingReconfigureParams.Builder()
                         .setBlockStrideLength(6)
-                        .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY)
+                        .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG)
                         .setRangeDataProximityFar(6)
                         .setRangeDataProximityNear(4)
                         .build();
diff --git a/service/tests/src/com/android/server/uwb/params/FiraEncoderTest.java b/service/tests/src/com/android/server/uwb/params/FiraEncoderTest.java
index d4574b2..bbfc847 100644
--- a/service/tests/src/com/android/server/uwb/params/FiraEncoderTest.java
+++ b/service/tests/src/com/android/server/uwb/params/FiraEncoderTest.java
@@ -19,7 +19,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.uwb.support.fira.FiraParams.MULTI_NODE_MODE_UNICAST;
-import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY;
+import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_RESPONDER;
 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLLER;
 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE;
@@ -53,6 +53,7 @@
             new FiraOpenSessionParams.Builder()
                     .setProtocolVersion(FiraParams.PROTOCOL_VERSION_1_1)
                     .setSessionId(1)
+                    .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG)
                     .setDeviceType(RANGING_DEVICE_TYPE_CONTROLLER)
                     .setDeviceRole(RANGING_DEVICE_ROLE_RESPONDER)
                     .setDeviceAddress(UwbAddress.fromBytes(new byte[] { 0x4, 0x6}))
@@ -64,25 +65,33 @@
                         0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F})
                     .setSubsessionKey(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F})
-                    .setStaticStsIV(new byte[]{0x1a, 0x55, 0x77, 0x47, 0x7e, 0x7d});
+                    .setStaticStsIV(new byte[]{0x1a, 0x55, 0x77, 0x47, 0x7e, 0x7d})
+                    .setRangeDataNtfAoaAzimuthLower(-1.5)
+                    .setRangeDataNtfAoaAzimuthUpper(2.5)
+                    .setRangeDataNtfAoaElevationLower(-2.5)
+                    .setRangeDataNtfAoaElevationUpper(3);
 
     private static final byte[] TEST_FIRA_OPEN_SESSION_TLV_DATA =
             UwbUtil.getByteArray("000101010101020100030100040109050101060206040702060408"
-                    + "0260090904C80000000B01000C01030D01010E01010F0200001002204E11010012010314010"
+                    + "0260090904C80000000B01000C01030D01010E01040F0200001002204E11010012010314010"
                     + "A1501021601001701011B011E1C01001F01002301002401002501322601002702780528061A"
                     + "5577477E7D2901012A0200002B04000000002C01002D01002E01012F01013004000000003101"
                     + "003501013610000102030405060708090A0B0C0D0E0F3710000102030405060708090A0B0C0D"
-                    + "0E0FE30100E40100E50100");
+                    + "0E0FE30100E40100E501001D04079E6161");
 
     private static final FiraRangingReconfigureParams.Builder TEST_FIRA_RECONFIGURE_PARAMS =
             new FiraRangingReconfigureParams.Builder()
                     .setBlockStrideLength(6)
-                    .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY)
+                    .setRangeDataNtfConfig(RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_AOA_LEVEL_TRIG)
                     .setRangeDataProximityFar(6)
-                    .setRangeDataProximityNear(4);
+                    .setRangeDataProximityNear(4)
+                    .setRangeDataAoaAzimuthLower(-1.5)
+                    .setRangeDataAoaAzimuthUpper(2.5)
+                    .setRangeDataAoaElevationLower(-2.5)
+                    .setRangeDataAoaElevationUpper(3);
 
     private static final byte[] TEST_FIRA_RECONFIGURE_TLV_DATA =
-            UwbUtil.getByteArray("2D01060E01020F02040010020600");
+            UwbUtil.getByteArray("2D01060E01040F020400100206001D04079E61F1");
 
     private final FiraEncoder mFiraEncoder = new FiraEncoder();
 
@@ -91,7 +100,7 @@
         FiraOpenSessionParams params = TEST_FIRA_OPEN_SESSION_PARAMS.build();
         TlvBuffer tlvs = mFiraEncoder.getTlvBuffer(params);
 
-        assertThat(tlvs.getNoOfParams()).isEqualTo(46);
+        assertThat(tlvs.getNoOfParams()).isEqualTo(47);
         assertThat(tlvs.getByteArray()).isEqualTo(TEST_FIRA_OPEN_SESSION_TLV_DATA);
     }
 
@@ -100,7 +109,7 @@
         FiraRangingReconfigureParams params = TEST_FIRA_RECONFIGURE_PARAMS.build();
         TlvBuffer tlvs = mFiraEncoder.getTlvBuffer(params);
 
-        assertThat(tlvs.getNoOfParams()).isEqualTo(4);
+        assertThat(tlvs.getNoOfParams()).isEqualTo(5);
         assertThat(tlvs.getByteArray()).isEqualTo(TEST_FIRA_RECONFIGURE_TLV_DATA);
     }
 
@@ -109,7 +118,7 @@
         FiraOpenSessionParams params = TEST_FIRA_OPEN_SESSION_PARAMS.build();
         TlvBuffer tlvs = TlvEncoder.getEncoder(FiraParams.PROTOCOL_NAME).getTlvBuffer(params);
 
-        assertThat(tlvs.getNoOfParams()).isEqualTo(46);
+        assertThat(tlvs.getNoOfParams()).isEqualTo(47);
         assertThat(tlvs.getByteArray()).isEqualTo(TEST_FIRA_OPEN_SESSION_TLV_DATA);
     }
 
@@ -118,7 +127,7 @@
         FiraRangingReconfigureParams params = TEST_FIRA_RECONFIGURE_PARAMS.build();
         TlvBuffer tlvs = TlvEncoder.getEncoder(FiraParams.PROTOCOL_NAME).getTlvBuffer(params);
 
-        assertThat(tlvs.getNoOfParams()).isEqualTo(4);
+        assertThat(tlvs.getNoOfParams()).isEqualTo(5);
         assertThat(tlvs.getByteArray()).isEqualTo(TEST_FIRA_RECONFIGURE_TLV_DATA);
     }
 }