1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.uwb.support; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertThrows; 22 23 import android.os.PersistableBundle; 24 25 import androidx.test.ext.junit.runners.AndroidJUnit4; 26 import androidx.test.filters.SmallTest; 27 28 import com.google.uwb.support.fira.FiraParams; 29 import com.google.uwb.support.fira.FiraSpecificationParams; 30 import com.google.uwb.support.radar.RadarData; 31 import com.google.uwb.support.radar.RadarOpenSessionParams; 32 import com.google.uwb.support.radar.RadarParams; 33 import com.google.uwb.support.radar.RadarParams.RadarCapabilityFlag; 34 import com.google.uwb.support.radar.RadarSpecificationParams; 35 import com.google.uwb.support.radar.RadarSweepData; 36 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 40 import java.util.ArrayList; 41 import java.util.EnumSet; 42 import java.util.List; 43 44 @SmallTest 45 @RunWith(AndroidJUnit4.class) 46 public class RadarTests { 47 private static final int SESSION_ID = 77; 48 private static final long SEQUENCE_NUMBER = 10; 49 private static final long TIMESTAMP = 1000; 50 private static final byte[] VENDOR_SPECIFIC_DATA = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05}; 51 private static final byte[] SAMPLE_DATA = new byte[] {0x05, 0x04, 0x03, 0x02, 0x01}; 52 private static final PersistableBundle INVALID_BUNDLE = 53 new FiraSpecificationParams.Builder().build().toBundle(); 54 55 @Test testOpenSessionParams_missingRequiredParams()56 public void testOpenSessionParams_missingRequiredParams() { 57 assertThrows( 58 IllegalStateException.class, () -> new RadarOpenSessionParams.Builder().build()); 59 } 60 61 @Test testOpenSessionParams_fromBundleWithInvalidProtocol()62 public void testOpenSessionParams_fromBundleWithInvalidProtocol() { 63 assertThrows( 64 IllegalArgumentException.class, 65 () -> RadarOpenSessionParams.fromBundle(INVALID_BUNDLE)); 66 } 67 68 @Test testOpenSessionParams()69 public void testOpenSessionParams() { 70 @RadarParams.BurstPeriod int burstPeriod = 100; 71 @RadarParams.SweepPeriod int sweepPeriod = 40; 72 @RadarParams.SweepsPerBurst int sweepsPerBurst = 16; 73 @RadarParams.SamplesPerSweep int samplesPerSweep = 128; 74 @FiraParams.UwbChannel int channelNumber = FiraParams.UWB_CHANNEL_9; 75 @RadarParams.SweepOffset int sweepOffset = -1; 76 @FiraParams.RframeConfig int rframeConfig = FiraParams.RFRAME_CONFIG_SP0; 77 @RadarParams.PreambleDuration 78 int preambleDuration = RadarParams.PREAMBLE_DURATION_T1024_SYMBOLS; 79 @RadarParams.PreambleCodeIndex int preambleCodeIndex = 90; 80 @RadarParams.SessionPriority int sessionPriority = 255; 81 @RadarParams.BitsPerSample int bitsPerSample = RadarParams.BITS_PER_SAMPLES_64; 82 @FiraParams.PrfMode int prfMode = FiraParams.PRF_MODE_HPRF; 83 @RadarParams.NumberOfBursts int numberOfBursts = 1000; 84 @RadarParams.RadarDataType 85 int radarDataType = RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES; 86 87 RadarOpenSessionParams params = 88 new RadarOpenSessionParams.Builder() 89 .setSessionId(SESSION_ID) 90 .setBurstPeriod(burstPeriod) 91 .setSweepPeriod(sweepPeriod) 92 .setSweepsPerBurst(sweepsPerBurst) 93 .setSamplesPerSweep(samplesPerSweep) 94 .setChannelNumber(channelNumber) 95 .setSweepOffset(sweepOffset) 96 .setRframeConfig(rframeConfig) 97 .setPreambleDuration(preambleDuration) 98 .setPreambleCodeIndex(preambleCodeIndex) 99 .setSessionPriority(sessionPriority) 100 .setBitsPerSample(bitsPerSample) 101 .setPrfMode(prfMode) 102 .setNumberOfBursts(numberOfBursts) 103 .setRadarDataType(radarDataType) 104 .build(); 105 106 assertEquals(params.getSessionId(), SESSION_ID); 107 assertEquals(params.getSessionType(), RadarParams.SESSION_TYPE_RADAR); 108 assertEquals(params.getBurstPeriod(), burstPeriod); 109 assertEquals(params.getSweepPeriod(), sweepPeriod); 110 assertEquals(params.getSweepsPerBurst(), sweepsPerBurst); 111 assertEquals(params.getSamplesPerSweep(), samplesPerSweep); 112 assertEquals(params.getChannelNumber(), channelNumber); 113 assertEquals(params.getSweepOffset(), sweepOffset); 114 assertEquals(params.getRframeConfig(), rframeConfig); 115 assertEquals(params.getPreambleDuration(), preambleDuration); 116 assertEquals(params.getPreambleCodeIndex(), preambleCodeIndex); 117 assertEquals(params.getSessionPriority(), sessionPriority); 118 assertEquals(params.getBitsPerSample(), bitsPerSample); 119 assertEquals(params.getPrfMode(), prfMode); 120 assertEquals(params.getNumberOfBursts(), numberOfBursts); 121 assertEquals(params.getRadarDataType(), radarDataType); 122 123 RadarOpenSessionParams fromBundle = RadarOpenSessionParams.fromBundle(params.toBundle()); 124 125 assertEquals(fromBundle.getSessionId(), SESSION_ID); 126 assertEquals(fromBundle.getSessionType(), RadarParams.SESSION_TYPE_RADAR); 127 assertEquals(fromBundle.getBurstPeriod(), burstPeriod); 128 assertEquals(fromBundle.getSweepPeriod(), sweepPeriod); 129 assertEquals(fromBundle.getSweepsPerBurst(), sweepsPerBurst); 130 assertEquals(fromBundle.getSamplesPerSweep(), samplesPerSweep); 131 assertEquals(fromBundle.getChannelNumber(), channelNumber); 132 assertEquals(fromBundle.getSweepOffset(), sweepOffset); 133 assertEquals(fromBundle.getRframeConfig(), rframeConfig); 134 assertEquals(fromBundle.getPreambleDuration(), preambleDuration); 135 assertEquals(fromBundle.getPreambleCodeIndex(), preambleCodeIndex); 136 assertEquals(fromBundle.getSessionPriority(), sessionPriority); 137 assertEquals(fromBundle.getBitsPerSample(), bitsPerSample); 138 assertEquals(fromBundle.getPrfMode(), prfMode); 139 assertEquals(fromBundle.getNumberOfBursts(), numberOfBursts); 140 assertEquals(fromBundle.getRadarDataType(), radarDataType); 141 assertEquals(params, fromBundle); 142 143 RadarOpenSessionParams.Builder builder = new RadarOpenSessionParams.Builder(params); 144 RadarOpenSessionParams fromBuilder = builder.build(); 145 146 assertEquals(params, fromBuilder); 147 148 fromBuilder = new RadarOpenSessionParams.Builder(builder).build(); 149 150 assertEquals(params, fromBuilder); 151 } 152 153 @Test testSpecificationParams_fromBundleWithInvalidProtocol()154 public void testSpecificationParams_fromBundleWithInvalidProtocol() { 155 assertThrows( 156 IllegalArgumentException.class, 157 () -> RadarSpecificationParams.fromBundle(INVALID_BUNDLE)); 158 } 159 160 @Test testSpecificationParams()161 public void testSpecificationParams() { 162 EnumSet<RadarCapabilityFlag> radarCapabilities = 163 EnumSet.of(RadarCapabilityFlag.HAS_RADAR_SWEEP_SAMPLES_SUPPORT); 164 RadarSpecificationParams.Builder paramsBuilder = new RadarSpecificationParams.Builder(); 165 paramsBuilder.setRadarCapabilities(radarCapabilities); 166 paramsBuilder.addRadarCapability(RadarCapabilityFlag.HAS_RADAR_SWEEP_SAMPLES_SUPPORT); 167 168 RadarSpecificationParams params = paramsBuilder.build(); 169 170 assertEquals(radarCapabilities, params.getRadarCapabilities()); 171 172 RadarSpecificationParams fromBundle = 173 RadarSpecificationParams.fromBundle(params.toBundle()); 174 175 assertEquals(radarCapabilities, fromBundle.getRadarCapabilities()); 176 assertEquals(params, fromBundle); 177 } 178 179 @Test testSpecificationParams_emptyCapabilities()180 public void testSpecificationParams_emptyCapabilities() { 181 RadarSpecificationParams params = new RadarSpecificationParams.Builder().build(); 182 assertEquals(EnumSet.noneOf(RadarCapabilityFlag.class), params.getRadarCapabilities()); 183 184 RadarSpecificationParams fromBundle = 185 RadarSpecificationParams.fromBundle(params.toBundle()); 186 assertEquals(EnumSet.noneOf(RadarCapabilityFlag.class), fromBundle.getRadarCapabilities()); 187 } 188 189 @Test testRadarSweepData_missingRequiredParams()190 public void testRadarSweepData_missingRequiredParams() { 191 assertThrows(IllegalStateException.class, () -> new RadarSweepData.Builder().build()); 192 } 193 194 @Test testRadarSweepData_fromBundleWithInvalidProtocol()195 public void testRadarSweepData_fromBundleWithInvalidProtocol() { 196 assertThrows( 197 IllegalArgumentException.class, () -> RadarSweepData.fromBundle(INVALID_BUNDLE)); 198 } 199 200 @Test testRadarSweepData_invalidParamsSequenceNumber()201 public void testRadarSweepData_invalidParamsSequenceNumber() { 202 RadarSweepData.Builder builder = 203 new RadarSweepData.Builder() 204 .setSequenceNumber(-1) // Invalid as timestamp must be greater than 0. 205 .setTimestamp(10) 206 .setSampleData(new byte[] {0x01}); 207 assertThrows(IllegalArgumentException.class, () -> builder.build()); 208 } 209 210 @Test testRadarSweepData_invalidParamsTimestamp()211 public void testRadarSweepData_invalidParamsTimestamp() { 212 RadarSweepData.Builder builder = 213 new RadarSweepData.Builder() 214 .setSequenceNumber(1) 215 .setTimestamp(-10) // Invalid as timestamp must be greater than 0. 216 .setSampleData(new byte[] {0x01}); 217 assertThrows(IllegalArgumentException.class, () -> builder.build()); 218 } 219 220 @Test testRadarSweepData_invalidParamsSampleData()221 public void testRadarSweepData_invalidParamsSampleData() { 222 RadarSweepData.Builder builder = 223 new RadarSweepData.Builder() 224 .setSequenceNumber(1) 225 .setTimestamp(10) 226 .setSampleData(new byte[] {}); // Empty sampleData. 227 assertThrows(IllegalArgumentException.class, () -> builder.build()); 228 } 229 230 @Test testRadarSweepData()231 public void testRadarSweepData() { 232 RadarSweepData data = 233 new RadarSweepData.Builder() 234 .setSequenceNumber(SEQUENCE_NUMBER) 235 .setTimestamp(TIMESTAMP) 236 .setVendorSpecificData(VENDOR_SPECIFIC_DATA) 237 .setSampleData(SAMPLE_DATA) 238 .build(); 239 240 assertEquals(data.getSequenceNumber(), SEQUENCE_NUMBER); 241 assertEquals(data.getTimestamp(), TIMESTAMP); 242 assertArrayEquals(data.getVendorSpecificData(), VENDOR_SPECIFIC_DATA); 243 assertArrayEquals(data.getSampleData(), SAMPLE_DATA); 244 245 RadarSweepData fromBundle = RadarSweepData.fromBundle(data.toBundle()); 246 247 assertEquals(fromBundle.getSequenceNumber(), SEQUENCE_NUMBER); 248 assertEquals(fromBundle.getTimestamp(), TIMESTAMP); 249 assertArrayEquals(fromBundle.getVendorSpecificData(), VENDOR_SPECIFIC_DATA); 250 assertArrayEquals(fromBundle.getSampleData(), SAMPLE_DATA); 251 assertEquals(data, fromBundle); 252 253 data = 254 new RadarSweepData.Builder() 255 .setSequenceNumber(SEQUENCE_NUMBER) 256 .setTimestamp(TIMESTAMP) 257 .setSampleData(SAMPLE_DATA) 258 .build(); 259 260 assertEquals(data.getVendorSpecificData(), null); 261 262 fromBundle = RadarSweepData.fromBundle(data.toBundle()); 263 264 assertEquals(fromBundle.getVendorSpecificData(), null); 265 assertEquals(data, fromBundle); 266 } 267 268 @Test testRadarData_missingRequiredParams()269 public void testRadarData_missingRequiredParams() { 270 assertThrows(IllegalStateException.class, () -> new RadarData.Builder().build()); 271 } 272 273 @Test testRadarData_fromBundleWithInvalidProtocol()274 public void testRadarData_fromBundleWithInvalidProtocol() { 275 assertThrows(IllegalArgumentException.class, () -> RadarData.fromBundle(INVALID_BUNDLE)); 276 } 277 278 @Test testRadarData_invalidParams()279 public void testRadarData_invalidParams() { 280 RadarData.Builder builder = 281 new RadarData.Builder() 282 .setStatusCode(FiraParams.STATUS_CODE_OK) 283 .setRadarDataType(RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES) 284 .setSamplesPerSweep(5) 285 .setBitsPerSample(RadarParams.BITS_PER_SAMPLES_64) 286 .setSweepOffset(-1); // Empty SweepData 287 assertThrows(IllegalArgumentException.class, () -> builder.build()); 288 } 289 290 @Test testRadarData()291 public void testRadarData() { 292 @FiraParams.StatusCode int statusCode = FiraParams.STATUS_CODE_OK; 293 @RadarParams.RadarDataType 294 int radarDataType = RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES; 295 @RadarParams.SamplesPerSweep int samplesPerSweep = 5; 296 @RadarParams.BitsPerSample int bitsPerSample = RadarParams.BITS_PER_SAMPLES_32; 297 @RadarParams.SweepOffset int sweepOffset = -1; 298 299 RadarSweepData sweepData1 = 300 new RadarSweepData.Builder() 301 .setSequenceNumber(SEQUENCE_NUMBER) 302 .setTimestamp(TIMESTAMP) 303 .setVendorSpecificData(VENDOR_SPECIFIC_DATA) 304 .setSampleData(SAMPLE_DATA) 305 .build(); 306 RadarSweepData sweepData2 = 307 new RadarSweepData.Builder() 308 .setSequenceNumber(SEQUENCE_NUMBER) 309 .setTimestamp(TIMESTAMP) 310 .setVendorSpecificData(VENDOR_SPECIFIC_DATA) 311 .setSampleData(SAMPLE_DATA) 312 .build(); 313 314 List<RadarSweepData> sweepDataList = new ArrayList<>(); 315 sweepDataList.add(sweepData1); 316 sweepDataList.add(sweepData2); 317 318 RadarData data = 319 new RadarData.Builder() 320 .setStatusCode(statusCode) 321 .setRadarDataType(radarDataType) 322 .setSamplesPerSweep(5) 323 .setBitsPerSample(RadarParams.BITS_PER_SAMPLES_32) 324 .setSweepOffset(-1) 325 .setSweepData(sweepDataList) 326 .build(); 327 328 assertEquals(data.getStatusCode(), statusCode); 329 assertEquals(data.getRadarDataType(), radarDataType); 330 assertEquals(data.getSamplesPerSweep(), samplesPerSweep); 331 assertEquals(data.getBitsPerSample(), bitsPerSample); 332 assertEquals(data.getSweepOffset(), sweepOffset); 333 assertEquals(data.getSweepData().get(0), sweepData1); 334 assertEquals(data.getSweepData().get(1), sweepData2); 335 336 RadarData fromBundle = RadarData.fromBundle(data.toBundle()); 337 338 assertEquals(fromBundle.getStatusCode(), statusCode); 339 assertEquals(fromBundle.getRadarDataType(), radarDataType); 340 assertEquals(fromBundle.getSamplesPerSweep(), samplesPerSweep); 341 assertEquals(fromBundle.getBitsPerSample(), bitsPerSample); 342 assertEquals(fromBundle.getSweepOffset(), sweepOffset); 343 assertEquals(fromBundle.getSweepData().get(0), sweepData1); 344 assertEquals(fromBundle.getSweepData().get(1), sweepData2); 345 assertEquals(data, fromBundle); 346 } 347 } 348