[uwb] Add Ranging report metadata bundle for oem extension
RangingReportMetadata contains session Id and raw ntf data
which is used by oem extesnion for pre-processing
Made api change to send RangingReport instead of
PersistableBundle
Bug: 243555651
Test: atest UwbSupportLibTests, CtsUwbTestCases
Change-Id: I12cbd2997055a93ee8a88a11f687ae0b3eb181bb
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 93f991b..5ce39a1 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -229,7 +229,7 @@
public static interface UwbManager.UwbOemExtensionCallback {
method public void onDeviceStatusNotificationReceived(@NonNull android.os.PersistableBundle);
- method @NonNull public android.os.PersistableBundle onRangingReportReceived(@NonNull android.os.PersistableBundle);
+ method @NonNull public android.uwb.RangingReport onRangingReportReceived(@NonNull android.uwb.RangingReport);
method @NonNull public int onSessionConfigurationComplete(@NonNull android.os.PersistableBundle);
method public void onSessionStatusNotificationReceived(@NonNull android.os.PersistableBundle);
}
diff --git a/framework/java/android/uwb/IUwbOemExtensionCallback.aidl b/framework/java/android/uwb/IUwbOemExtensionCallback.aidl
index 44a5e1a..f099f9a 100644
--- a/framework/java/android/uwb/IUwbOemExtensionCallback.aidl
+++ b/framework/java/android/uwb/IUwbOemExtensionCallback.aidl
@@ -25,5 +25,5 @@
oneway void onSessionStatusNotificationReceived(in PersistableBundle bundle);
oneway void onDeviceStatusNotificationReceived(in PersistableBundle bundle);
int onSessionConfigurationReceived(in PersistableBundle bundle);
- PersistableBundle onRangingReportReceived(in PersistableBundle bundle);
+ RangingReport onRangingReportReceived(in RangingReport bundle);
}
\ No newline at end of file
diff --git a/framework/java/android/uwb/UwbManager.java b/framework/java/android/uwb/UwbManager.java
index 4d12920..d287129 100644
--- a/framework/java/android/uwb/UwbManager.java
+++ b/framework/java/android/uwb/UwbManager.java
@@ -369,11 +369,11 @@
/**
* Invoked when ranging report is generated
*
- * @param rangingReportBundle ranging report generated
+ * @param rangingReport ranging report generated
* @return Oem modified ranging report
*/
- @NonNull PersistableBundle onRangingReportReceived(
- @NonNull PersistableBundle rangingReportBundle);
+ @NonNull RangingReport onRangingReportReceived(
+ @NonNull RangingReport rangingReport);
}
/**
diff --git a/framework/java/android/uwb/UwbOemExtensionCallbackListener.java b/framework/java/android/uwb/UwbOemExtensionCallbackListener.java
index 4a43318..08a089a 100644
--- a/framework/java/android/uwb/UwbOemExtensionCallbackListener.java
+++ b/framework/java/android/uwb/UwbOemExtensionCallbackListener.java
@@ -140,22 +140,22 @@
}
@Override
- public PersistableBundle onRangingReportReceived(PersistableBundle rangingReportBundle)
+ public RangingReport onRangingReportReceived(RangingReport rangingReport)
throws RemoteException {
synchronized (this) {
final long identity = Binder.clearCallingIdentity();
- PersistableBundle vendorRangingReportBundle = rangingReportBundle;
+ RangingReport vendorRangingReport = rangingReport;
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
- FutureTask<PersistableBundle> getOemRangingReport = new FutureTask<>(
- () -> mCallback.onRangingReportReceived(rangingReportBundle)
+ FutureTask<RangingReport> getOemRangingReport = new FutureTask<RangingReport>(
+ () -> mCallback.onRangingReportReceived(rangingReport)
);
executor.submit(getOemRangingReport);
try {
- vendorRangingReportBundle = getOemRangingReport.get(
+ vendorRangingReport = getOemRangingReport.get(
OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
- return vendorRangingReportBundle == null ? rangingReportBundle
- : vendorRangingReportBundle;
+ return vendorRangingReport == null ? rangingReport
+ : vendorRangingReport;
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
@@ -165,7 +165,7 @@
} finally {
Binder.restoreCallingIdentity(identity);
}
- return vendorRangingReportBundle;
+ return vendorRangingReport;
}
}
}
diff --git a/service/java/com/android/server/uwb/UwbSessionNotificationManager.java b/service/java/com/android/server/uwb/UwbSessionNotificationManager.java
index 304457c..2e3be42 100644
--- a/service/java/com/android/server/uwb/UwbSessionNotificationManager.java
+++ b/service/java/com/android/server/uwb/UwbSessionNotificationManager.java
@@ -41,6 +41,7 @@
import com.google.uwb.support.ccc.CccRangingReconfiguredParams;
import com.google.uwb.support.fira.FiraOpenSessionParams;
import com.google.uwb.support.fira.FiraParams;
+import com.google.uwb.support.oemextension.RangingReportMetadata;
import java.util.ArrayList;
import java.util.List;
@@ -67,11 +68,11 @@
RangingReport rangingReport = getRangingReport(rangingData, uwbSession.getProtocolName(),
uwbSession.getParams(), mUwbInjector.getElapsedSinceBootNanos());
- PersistableBundle bundle = new PersistableBundle();
+
if (mUwbInjector.getUwbServiceCore().isOemExtensionCbRegistered()) {
try {
- bundle = mUwbInjector.getUwbServiceCore().getOemExtensionCallback()
- .onRangingReportReceived(bundle);
+ rangingReport = mUwbInjector.getUwbServiceCore().getOemExtensionCallback()
+ .onRangingReportReceived(rangingReport);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -321,9 +322,11 @@
boolean isAoaElevationEnabled = true;
boolean isDestAoaAzimuthEnabled = false;
boolean isDestAoaElevationEnabled = false;
+ long sessionId = 0;
// For FIRA sessions, check if AOA is enabled for the session or not.
if (protocolName.equals(FiraParams.PROTOCOL_NAME)) {
FiraOpenSessionParams openSessionParams = (FiraOpenSessionParams) sessionParams;
+ sessionId = openSessionParams.getSessionId();
switch (openSessionParams.getAoaResultRequest()) {
case FiraParams.AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT:
isAoaAzimuthEnabled = false;
@@ -426,13 +429,18 @@
if (rssi < 0) {
rangingMeasurementBuilder.setRssiDbm(rssi);
}
- // TODO: Fill this with vendor data
+ // TODO: No ranging measurement metadata defined, added for future usage
PersistableBundle rangingMeasurementMetadata = new PersistableBundle();
rangingMeasurementBuilder.setRangingMeasurementMetadata(rangingMeasurementMetadata);
rangingMeasurements.add(rangingMeasurementBuilder.build());
}
- // TODO: Fill this with vendor data
- PersistableBundle rangingReportMetadata = new PersistableBundle();
+
+ PersistableBundle rangingReportMetadata = new RangingReportMetadata.Builder()
+ .setSessionId(sessionId)
+ .setRawNtfData(rangingData.getRawNtfData())
+ .build()
+ .toBundle();
+
if (rangingMeasurements.size() == 1) {
return new RangingReport.Builder()
.addMeasurement(rangingMeasurements.get(0))
diff --git a/service/java/com/android/server/uwb/UwbTestUtils.java b/service/java/com/android/server/uwb/UwbTestUtils.java
index 4387a9e..64de26d 100644
--- a/service/java/com/android/server/uwb/UwbTestUtils.java
+++ b/service/java/com/android/server/uwb/UwbTestUtils.java
@@ -71,7 +71,7 @@
TEST_AOA_DEST_ELEVATION_FOM, TEST_SLOT_IDX, TEST_RSSI);
return new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, TEST_RANGING_MEASURES_TYPE,
- TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements);
+ TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements, new byte[0]);
}
// Helper method to generate a UwbRangingData instance and corresponding RangingMeasurement
diff --git a/service/java/com/android/server/uwb/data/UwbRangingData.java b/service/java/com/android/server/uwb/data/UwbRangingData.java
index 44be8d5..64dbbe6 100644
--- a/service/java/com/android/server/uwb/data/UwbRangingData.java
+++ b/service/java/com/android/server/uwb/data/UwbRangingData.java
@@ -26,10 +26,12 @@
public int mMacAddressMode;
public int mNoOfRangingMeasures;
public UwbTwoWayMeasurement[] mRangingTwoWayMeasures;
+ public byte[] mRawNtfData;
public UwbRangingData(long seqCounter, long sessionId, int rcrIndication,
long currRangingInterval, int rangingMeasuresType, int macAddressMode,
- int noOfRangingMeasures, UwbTwoWayMeasurement[] rangingTwoWayMeasures) {
+ int noOfRangingMeasures, UwbTwoWayMeasurement[] rangingTwoWayMeasures,
+ byte[] rawNtfData) {
this.mSeqCounter = seqCounter;
this.mSessionId = sessionId;
this.mRcrIndication = rcrIndication;
@@ -38,6 +40,7 @@
this.mMacAddressMode = macAddressMode;
this.mNoOfRangingMeasures = noOfRangingMeasures;
this.mRangingTwoWayMeasures = rangingTwoWayMeasures;
+ this.mRawNtfData = rawNtfData;
}
public long getSequenceCounter() {
@@ -72,6 +75,10 @@
return mRangingTwoWayMeasures;
}
+ public byte[] getRawNtfData() {
+ return mRawNtfData;
+ }
+
public String toString() {
if (mRangingMeasuresType == UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY) {
return "UwbRangingData { "
@@ -83,6 +90,7 @@
+ ", MacAddressMode = " + mMacAddressMode
+ ", NoOfRangingMeasures = " + mNoOfRangingMeasures
+ ", RangingTwoWayMeasures = " + Arrays.toString(mRangingTwoWayMeasures)
+ + ", RawNotificationData = " + Arrays.toString(mRawNtfData)
+ '}';
} else {
// TODO(jh0.jang) : ONE WAY RANGING(TDOA)?
diff --git a/service/support_lib/src/com/google/uwb/support/oemextension/RangingReportMetadata.java b/service/support_lib/src/com/google/uwb/support/oemextension/RangingReportMetadata.java
new file mode 100644
index 0000000..49c363d
--- /dev/null
+++ b/service/support_lib/src/com/google/uwb/support/oemextension/RangingReportMetadata.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.uwb.support.oemextension;
+
+import android.os.PersistableBundle;
+import android.uwb.RangingReport;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Ranging report metadata for post-processing with oem extension
+ *
+ * <p> This is passed as bundle with RangingReport
+ * {@link RangingReport#getRangingReportMetadata()}
+ */
+public class RangingReportMetadata {
+ private static final int BUNDLE_VERSION_1 = 1;
+ private static final int BUNDLE_VERSION_CURRENT = BUNDLE_VERSION_1;
+
+ public static final String KEY_BUNDLE_VERSION = "bundle_version";
+ public static final String SESSION_ID = "session_id";
+ public static final String RAW_NTF_DATA = "raw_ntf_data";
+
+ private final long mSessionId;
+ private final byte[] mRawNtfData;
+
+ public static int getBundleVersion() {
+ return BUNDLE_VERSION_CURRENT;
+ }
+
+ public long getSessionId() {
+ return mSessionId;
+ }
+
+ public byte[] getRawNtfData() {
+ return mRawNtfData;
+ }
+
+ private RangingReportMetadata(long sessionId, byte[] rawNtfData) {
+ mSessionId = sessionId;
+ mRawNtfData = rawNtfData;
+ }
+
+ @Nullable
+ private static int[] byteArrayToIntArray(@Nullable byte[] bytes) {
+ if (bytes == null) {
+ return null;
+ }
+ int[] values = new int[bytes.length];
+ for (int i = 0; i < values.length; i++) {
+ values[i] = (bytes[i]);
+ }
+ return values;
+ }
+
+ @Nullable
+ private static byte[] intArrayToByteArray(@Nullable int[] values) {
+ if (values == null) {
+ return null;
+ }
+ byte[] bytes = new byte[values.length];
+ for (int i = 0; i < values.length; i++) {
+ bytes[i] = (byte) values[i];
+ }
+ return bytes;
+ }
+
+ public PersistableBundle toBundle() {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt(KEY_BUNDLE_VERSION, getBundleVersion());
+ bundle.putLong(SESSION_ID, mSessionId);
+ bundle.putIntArray(RAW_NTF_DATA, byteArrayToIntArray(mRawNtfData));
+ return bundle;
+ }
+
+ public static RangingReportMetadata fromBundle(PersistableBundle bundle) {
+ switch (bundle.getInt(KEY_BUNDLE_VERSION)) {
+ case BUNDLE_VERSION_1:
+ return parseVersion1(bundle);
+ default:
+ throw new IllegalArgumentException("Invalid bundle version");
+ }
+ }
+
+ private static RangingReportMetadata parseVersion1(PersistableBundle bundle) {
+ return new RangingReportMetadata.Builder()
+ .setSessionId(bundle.getLong(SESSION_ID))
+ .setRawNtfData(intArrayToByteArray(bundle.getIntArray(RAW_NTF_DATA)))
+ .build();
+ }
+
+ /** Builder */
+ public static class Builder {
+ private long mSessionId;
+ private byte[] mRawNtfData;
+
+ public RangingReportMetadata.Builder setSessionId(long sessionId) {
+ mSessionId = sessionId;
+ return this;
+ }
+
+ public RangingReportMetadata.Builder setRawNtfData(byte[] rawNtfData) {
+ mRawNtfData = rawNtfData;
+ return this;
+ }
+
+ public RangingReportMetadata build() {
+ return new RangingReportMetadata(mSessionId, mRawNtfData);
+ }
+ }
+}
diff --git a/service/support_lib/test/OemExtensionTests.java b/service/support_lib/test/OemExtensionTests.java
index dc469b1..4885dbd 100644
--- a/service/support_lib/test/OemExtensionTests.java
+++ b/service/support_lib/test/OemExtensionTests.java
@@ -20,11 +20,14 @@
import androidx.test.filters.SmallTest;
import com.google.uwb.support.oemextension.DeviceStatus;
+import com.google.uwb.support.oemextension.RangingReportMetadata;
import com.google.uwb.support.oemextension.SessionStatus;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class OemExtensionTests {
@@ -70,4 +73,22 @@
assertEquals(fromBundle.getState(), state);
assertEquals(fromBundle.getReasonCode(), reasonCode);
}
+
+ @Test
+ public void testRangingReportMetadata() {
+ byte[] testRawDataNtf = {0x0a, 0x0b, 0x10, 0x20, 0x6f};
+ long sessionId = 3;
+ RangingReportMetadata rangingReportMetadata = new RangingReportMetadata.Builder()
+ .setSessionId(sessionId)
+ .setRawNtfData(testRawDataNtf)
+ .build();
+
+ assertEquals(rangingReportMetadata.getRawNtfData(), testRawDataNtf);
+
+ RangingReportMetadata fromBundle = RangingReportMetadata
+ .fromBundle(rangingReportMetadata.toBundle());
+
+ assertEquals(fromBundle.getSessionId(), sessionId);
+ assertEquals(Arrays.toString(fromBundle.getRawNtfData()), Arrays.toString(testRawDataNtf));
+ }
}
diff --git a/service/tests/src/com/android/server/uwb/data/UwbRangingDataTest.java b/service/tests/src/com/android/server/uwb/data/UwbRangingDataTest.java
index 33a00e1..5a009a0 100644
--- a/service/tests/src/com/android/server/uwb/data/UwbRangingDataTest.java
+++ b/service/tests/src/com/android/server/uwb/data/UwbRangingDataTest.java
@@ -66,6 +66,7 @@
@Test
public void testInitializeUwbRangingData() throws Exception {
final int noOfRangingMeasures = 1;
+ final byte[] rawNtfData = {0x10, 0x01};
final UwbTwoWayMeasurement[] uwbTwoWayMeasurements =
new UwbTwoWayMeasurement[noOfRangingMeasures];
uwbTwoWayMeasurements[0] = new UwbTwoWayMeasurement(TEST_MAC_ADDRESS, TEST_STATUS, TEST_LOS,
@@ -76,7 +77,7 @@
TEST_AOA_DEST_ELEVATION_FOM, TEST_SLOT_IDX, TEST_RSSI);
mUwbRangingData = new UwbRangingData(TEST_SEQ_COUNTER, TEST_SESSION_ID,
TEST_RCR_INDICATION, TEST_CURR_RANGING_INTERVAL, TEST_RANGING_MEASURES_TYPE,
- TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements);
+ TEST_MAC_ADDRESS_MODE, noOfRangingMeasures, uwbTwoWayMeasurements, rawNtfData);
assertThat(mUwbRangingData.getSequenceCounter()).isEqualTo(TEST_SEQ_COUNTER);
assertThat(mUwbRangingData.getSessionId()).isEqualTo(TEST_SESSION_ID);
@@ -85,6 +86,7 @@
assertThat(mUwbRangingData.getRangingMeasuresType()).isEqualTo(TEST_RANGING_MEASURES_TYPE);
assertThat(mUwbRangingData.getMacAddressMode()).isEqualTo(TEST_MAC_ADDRESS_MODE);
assertThat(mUwbRangingData.getNoOfRangingMeasures()).isEqualTo(1);
+ assertThat(mUwbRangingData.getRawNtfData()).isEqualTo(rawNtfData);
final String testString = "UwbRangingData { "
+ " SeqCounter = " + TEST_SEQ_COUNTER
@@ -95,6 +97,7 @@
+ ", MacAddressMode = " + TEST_MAC_ADDRESS_MODE
+ ", NoOfRangingMeasures = " + noOfRangingMeasures
+ ", RangingTwoWayMeasures = " + Arrays.toString(uwbTwoWayMeasurements)
+ + ", RawNotificationData = " + Arrays.toString(rawNtfData)
+ '}';
assertThat(mUwbRangingData.toString()).isEqualTo(testString);