Loading android/app/jni/com_android_bluetooth_gatt.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -1155,8 +1155,10 @@ public: void OnDistanceMeasurementResult(RawAddress address, uint32_t centimeter, uint32_t error_centimeter, int azimuth_angle, int error_azimuth_angle, int altitude_angle, int error_altitude_angle, uint64_t elapsedRealtimeNanos, int8_t confidence_level, uint8_t method) { int error_altitude_angle, uint64_t elapsed_realtime_nanos, int8_t confidence_level, double delay_spread_meters, uint8_t detected_attack_level, double velocity_meters_per_second, uint8_t method) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mDistanceMeasurementCallbacksObj) { Loading @@ -1166,7 +1168,8 @@ public: sCallbackEnv->CallVoidMethod( mDistanceMeasurementCallbacksObj, method_onDistanceMeasurementResult, addr.get(), centimeter, error_centimeter, azimuth_angle, error_azimuth_angle, altitude_angle, error_altitude_angle, elapsedRealtimeNanos, confidence_level, method); error_altitude_angle, elapsed_realtime_nanos, confidence_level, delay_spread_meters, detected_attack_level, velocity_meters_per_second, method); } }; Loading Loading @@ -2914,7 +2917,7 @@ static int register_com_android_bluetooth_gatt_distance_measurement(JNIEnv* env) &method_onDistanceMeasurementStarted}, {"onDistanceMeasurementStopped", "(Ljava/lang/String;II)V", &method_onDistanceMeasurementStopped}, {"onDistanceMeasurementResult", "(Ljava/lang/String;IIIIIIJII)V", {"onDistanceMeasurementResult", "(Ljava/lang/String;IIIIIIJIDIDI)V", &method_onDistanceMeasurementResult}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/gatt/DistanceMeasurementNativeInterface", Loading android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java +28 −6 Original line number Diff line number Diff line Loading @@ -52,6 +52,10 @@ public class DistanceMeasurementManager { private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 3000; private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 200; // sync with system/gd/hic/DistanceMeasurementManager private static final int INVALID_AZIMUTH_ANGLE_DEGREE = -1; private static final int INVALID_ALTITUDE_ANGLE_DEGREE = -91; private final AdapterService mAdapterService; private final HandlerThread mHandlerThread; private final DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface; Loading Loading @@ -500,6 +504,9 @@ public class DistanceMeasurementManager { int errorAltitudeAngle, long elapsedRealtimeNanos, int confidenceLevel, double delaySpreadMeters, int detectedAttackLevel, double velocityMetersPerSecond, int method) { logd( "onDistanceMeasurementResult " Loading @@ -511,16 +518,31 @@ public class DistanceMeasurementManager { DistanceMeasurementResult.Builder builder = new DistanceMeasurementResult.Builder(centimeter / 100.0, errorCentimeter / 100.0) .setMeasurementTimestampNanos(elapsedRealtimeNanos); if (confidenceLevel != -1) { builder.setConfidenceLevel(confidenceLevel / 100.0); } DistanceMeasurementResult result = builder.build(); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiResult(address, result); handleRssiResult(address, builder.build()); break; case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: handleCsResult(address, result); if (azimuthAngle != INVALID_AZIMUTH_ANGLE_DEGREE) { builder.setAzimuthAngle(azimuthAngle); builder.setErrorAzimuthAngle(errorAzimuthAngle); } if (altitudeAngle != INVALID_ALTITUDE_ANGLE_DEGREE) { builder.setAltitudeAngle(altitudeAngle); builder.setErrorAltitudeAngle(errorAltitudeAngle); } if (confidenceLevel != -1) { builder.setConfidenceLevel(confidenceLevel / 100.0); } if (delaySpreadMeters >= 0) { builder.setDelaySpreadMeters(delaySpreadMeters); } if (velocityMetersPerSecond >= 0) { builder.setVelocityMetersPerSecond(velocityMetersPerSecond); } builder.setDetectedAttackLevel(detectedAttackLevel); handleCsResult(address, builder.build()); break; default: Log.w(TAG, "onDistanceMeasurementResult: invalid method " + method); Loading android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java +6 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ public class DistanceMeasurementNativeInterface { int errorAltitudeAngle, long elapsedRealtimeNanos, int confidenceLevel, double delayedSpreadMeters, int detectedAttackLevel, double velocityMetersPerSecond, int method) { mDistanceMeasurementManager.onDistanceMeasurementResult( address, Loading @@ -118,6 +121,9 @@ public class DistanceMeasurementNativeInterface { errorAltitudeAngle, elapsedRealtimeNanos, confidenceLevel, delayedSpreadMeters, detectedAttackLevel, velocityMetersPerSecond, method); } Loading android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java +24 −3 Original line number Diff line number Diff line Loading @@ -210,18 +210,29 @@ public class DistanceMeasurementManagerTest { IDENTITY_ADDRESS, 100, 0, 100, 0, 45, 0, 0, 0, 0, 10000, 1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 1.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING); ArgumentCaptor<DistanceMeasurementResult> result = ArgumentCaptor.forClass(DistanceMeasurementResult.class); verify(mCallback).onResult(eq(mDevice), result.capture()); assertThat(result.getValue().getResultMeters()).isEqualTo(1.00); assertThat(result.getValue().getAzimuthAngle()).isEqualTo(100); assertThat(result.getValue().getAltitudeAngle()).isEqualTo(45); assertThat(result.getValue().getMeasurementTimestampNanos()).isEqualTo(10000); assertThat(result.getValue().getConfidenceLevel()).isEqualTo(0.01); assertThat(result.getValue().getDelaySpreadMeters()).isEqualTo(10.0); assertThat(result.getValue().getDetectedAttackLevel()) .isEqualTo(DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE); assertThat(result.getValue().getVelocityMetersPerSecond()).isEqualTo(1.0); } @Test Loading Loading @@ -267,6 +278,9 @@ public class DistanceMeasurementManagerTest { -1, 1000L, -1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 0.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); ArgumentCaptor<DistanceMeasurementResult> result = ArgumentCaptor.forClass(DistanceMeasurementResult.class); Loading @@ -278,6 +292,10 @@ public class DistanceMeasurementManagerTest { assertThat(result.getValue().getAltitudeAngle()).isEqualTo(Double.NaN); assertThat(result.getValue().getErrorAltitudeAngle()).isEqualTo(Double.NaN); assertThat(result.getValue().getMeasurementTimestampNanos()).isEqualTo(1000L); assertThat(result.getValue().getDelaySpreadMeters()).isEqualTo(Double.NaN); assertThat(result.getValue().getDetectedAttackLevel()) .isEqualTo(DistanceMeasurementResult.NADM_UNKNOWN); assertThat(result.getValue().getVelocityMetersPerSecond()).isEqualTo(Double.NaN); } @Test Loading Loading @@ -306,6 +324,9 @@ public class DistanceMeasurementManagerTest { -1, 1000L, -1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 0.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); DistanceMeasurementResult result = new DistanceMeasurementResult.Builder(1.00, 1.00).build(); Loading system/gd/hal/ranging_hal.h +6 −0 Original line number Diff line number Diff line Loading @@ -281,9 +281,15 @@ struct ProcedureDataV2 { struct RangingResult { double result_meters_; double error_meters_; // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence // of estimated distance. The value is -1 when unavailable. int8_t confidence_level_; double delay_spread_meters_; uint8_t detected_attack_level_; double velocity_meters_per_second_; int64_t elapsed_timestamp_nanos_; }; class RangingHalCallback { Loading Loading
android/app/jni/com_android_bluetooth_gatt.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -1155,8 +1155,10 @@ public: void OnDistanceMeasurementResult(RawAddress address, uint32_t centimeter, uint32_t error_centimeter, int azimuth_angle, int error_azimuth_angle, int altitude_angle, int error_altitude_angle, uint64_t elapsedRealtimeNanos, int8_t confidence_level, uint8_t method) { int error_altitude_angle, uint64_t elapsed_realtime_nanos, int8_t confidence_level, double delay_spread_meters, uint8_t detected_attack_level, double velocity_meters_per_second, uint8_t method) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mDistanceMeasurementCallbacksObj) { Loading @@ -1166,7 +1168,8 @@ public: sCallbackEnv->CallVoidMethod( mDistanceMeasurementCallbacksObj, method_onDistanceMeasurementResult, addr.get(), centimeter, error_centimeter, azimuth_angle, error_azimuth_angle, altitude_angle, error_altitude_angle, elapsedRealtimeNanos, confidence_level, method); error_altitude_angle, elapsed_realtime_nanos, confidence_level, delay_spread_meters, detected_attack_level, velocity_meters_per_second, method); } }; Loading Loading @@ -2914,7 +2917,7 @@ static int register_com_android_bluetooth_gatt_distance_measurement(JNIEnv* env) &method_onDistanceMeasurementStarted}, {"onDistanceMeasurementStopped", "(Ljava/lang/String;II)V", &method_onDistanceMeasurementStopped}, {"onDistanceMeasurementResult", "(Ljava/lang/String;IIIIIIJII)V", {"onDistanceMeasurementResult", "(Ljava/lang/String;IIIIIIJIDIDI)V", &method_onDistanceMeasurementResult}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/gatt/DistanceMeasurementNativeInterface", Loading
android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java +28 −6 Original line number Diff line number Diff line Loading @@ -52,6 +52,10 @@ public class DistanceMeasurementManager { private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 3000; private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 200; // sync with system/gd/hic/DistanceMeasurementManager private static final int INVALID_AZIMUTH_ANGLE_DEGREE = -1; private static final int INVALID_ALTITUDE_ANGLE_DEGREE = -91; private final AdapterService mAdapterService; private final HandlerThread mHandlerThread; private final DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface; Loading Loading @@ -500,6 +504,9 @@ public class DistanceMeasurementManager { int errorAltitudeAngle, long elapsedRealtimeNanos, int confidenceLevel, double delaySpreadMeters, int detectedAttackLevel, double velocityMetersPerSecond, int method) { logd( "onDistanceMeasurementResult " Loading @@ -511,16 +518,31 @@ public class DistanceMeasurementManager { DistanceMeasurementResult.Builder builder = new DistanceMeasurementResult.Builder(centimeter / 100.0, errorCentimeter / 100.0) .setMeasurementTimestampNanos(elapsedRealtimeNanos); if (confidenceLevel != -1) { builder.setConfidenceLevel(confidenceLevel / 100.0); } DistanceMeasurementResult result = builder.build(); switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiResult(address, result); handleRssiResult(address, builder.build()); break; case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: handleCsResult(address, result); if (azimuthAngle != INVALID_AZIMUTH_ANGLE_DEGREE) { builder.setAzimuthAngle(azimuthAngle); builder.setErrorAzimuthAngle(errorAzimuthAngle); } if (altitudeAngle != INVALID_ALTITUDE_ANGLE_DEGREE) { builder.setAltitudeAngle(altitudeAngle); builder.setErrorAltitudeAngle(errorAltitudeAngle); } if (confidenceLevel != -1) { builder.setConfidenceLevel(confidenceLevel / 100.0); } if (delaySpreadMeters >= 0) { builder.setDelaySpreadMeters(delaySpreadMeters); } if (velocityMetersPerSecond >= 0) { builder.setVelocityMetersPerSecond(velocityMetersPerSecond); } builder.setDetectedAttackLevel(detectedAttackLevel); handleCsResult(address, builder.build()); break; default: Log.w(TAG, "onDistanceMeasurementResult: invalid method " + method); Loading
android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java +6 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,9 @@ public class DistanceMeasurementNativeInterface { int errorAltitudeAngle, long elapsedRealtimeNanos, int confidenceLevel, double delayedSpreadMeters, int detectedAttackLevel, double velocityMetersPerSecond, int method) { mDistanceMeasurementManager.onDistanceMeasurementResult( address, Loading @@ -118,6 +121,9 @@ public class DistanceMeasurementNativeInterface { errorAltitudeAngle, elapsedRealtimeNanos, confidenceLevel, delayedSpreadMeters, detectedAttackLevel, velocityMetersPerSecond, method); } Loading
android/app/tests/unit/src/com/android/bluetooth/gatt/DistanceMeasurementManagerTest.java +24 −3 Original line number Diff line number Diff line Loading @@ -210,18 +210,29 @@ public class DistanceMeasurementManagerTest { IDENTITY_ADDRESS, 100, 0, 100, 0, 45, 0, 0, 0, 0, 10000, 1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 1.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING); ArgumentCaptor<DistanceMeasurementResult> result = ArgumentCaptor.forClass(DistanceMeasurementResult.class); verify(mCallback).onResult(eq(mDevice), result.capture()); assertThat(result.getValue().getResultMeters()).isEqualTo(1.00); assertThat(result.getValue().getAzimuthAngle()).isEqualTo(100); assertThat(result.getValue().getAltitudeAngle()).isEqualTo(45); assertThat(result.getValue().getMeasurementTimestampNanos()).isEqualTo(10000); assertThat(result.getValue().getConfidenceLevel()).isEqualTo(0.01); assertThat(result.getValue().getDelaySpreadMeters()).isEqualTo(10.0); assertThat(result.getValue().getDetectedAttackLevel()) .isEqualTo(DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE); assertThat(result.getValue().getVelocityMetersPerSecond()).isEqualTo(1.0); } @Test Loading Loading @@ -267,6 +278,9 @@ public class DistanceMeasurementManagerTest { -1, 1000L, -1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 0.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); ArgumentCaptor<DistanceMeasurementResult> result = ArgumentCaptor.forClass(DistanceMeasurementResult.class); Loading @@ -278,6 +292,10 @@ public class DistanceMeasurementManagerTest { assertThat(result.getValue().getAltitudeAngle()).isEqualTo(Double.NaN); assertThat(result.getValue().getErrorAltitudeAngle()).isEqualTo(Double.NaN); assertThat(result.getValue().getMeasurementTimestampNanos()).isEqualTo(1000L); assertThat(result.getValue().getDelaySpreadMeters()).isEqualTo(Double.NaN); assertThat(result.getValue().getDetectedAttackLevel()) .isEqualTo(DistanceMeasurementResult.NADM_UNKNOWN); assertThat(result.getValue().getVelocityMetersPerSecond()).isEqualTo(Double.NaN); } @Test Loading Loading @@ -306,6 +324,9 @@ public class DistanceMeasurementManagerTest { -1, 1000L, -1, /* delayedSpreadMeters= */ 10.0, /* detectedAttackLevel= */ DistanceMeasurementResult.NADM_ATTACK_IS_POSSIBLE, /* velocityMetersPerSecond= */ 0.0, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); DistanceMeasurementResult result = new DistanceMeasurementResult.Builder(1.00, 1.00).build(); Loading
system/gd/hal/ranging_hal.h +6 −0 Original line number Diff line number Diff line Loading @@ -281,9 +281,15 @@ struct ProcedureDataV2 { struct RangingResult { double result_meters_; double error_meters_; // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence // of estimated distance. The value is -1 when unavailable. int8_t confidence_level_; double delay_spread_meters_; uint8_t detected_attack_level_; double velocity_meters_per_second_; int64_t elapsed_timestamp_nanos_; }; class RangingHalCallback { Loading