1 package org.robolectric.shadows; 2 3 import static org.robolectric.util.reflector.Reflector.reflector; 4 5 import android.net.MacAddress; 6 import android.net.wifi.WifiAnnotations.ChannelWidth; 7 import android.net.wifi.aware.PeerHandle; 8 import android.net.wifi.rtt.RangingResult; 9 import android.net.wifi.rtt.ResponderLocation; 10 import android.os.Build; 11 import org.robolectric.RuntimeEnvironment; 12 import org.robolectric.util.ReflectionHelpers; 13 import org.robolectric.util.reflector.Accessor; 14 import org.robolectric.util.reflector.ForType; 15 import org.robolectric.util.reflector.WithType; 16 import org.robolectric.versioning.AndroidVersions.V; 17 18 /** 19 * A builder for creating ShadowRangingResults. Status, macAddress, distance [mm] and timestamp are 20 * all mandatory fields. Additional fields can be specified by setters. Use build() to return the 21 * ShadowRangingResult object. 22 * 23 * <p>TODO:org/robolectric/shadows/ShadowLegacyTypeface Remove after V is generally available. 24 */ 25 public class RangingResultBuilder { 26 27 // Required Values 28 private final int status; 29 private final MacAddress mac; 30 private final int distanceMm; 31 private final long timestampMillis; 32 33 // Optional Values 34 private int distanceStdDevMm = 0; 35 private int rssi = 0; 36 private int numAttemptedMeasurements = 0; 37 private int numSuccessfulMeasurements = 0; 38 private byte[] lci = new byte[0]; 39 private byte[] lcr = new byte[0]; 40 private ResponderLocation unverifiedResponderLocation = null; 41 private boolean is80211mcMeasurement = true; 42 RangingResultBuilder(int status, MacAddress mac, long timestampMillis, int distanceMm)43 public RangingResultBuilder(int status, MacAddress mac, long timestampMillis, int distanceMm) { 44 this.status = status; 45 this.mac = mac; 46 this.timestampMillis = timestampMillis; 47 this.distanceMm = distanceMm; 48 } 49 setDistanceStandardDeviation(int stddev)50 public RangingResultBuilder setDistanceStandardDeviation(int stddev) { 51 this.distanceStdDevMm = stddev; 52 return this; 53 } 54 setRssi(int rssi)55 public RangingResultBuilder setRssi(int rssi) { 56 this.rssi = rssi; 57 return this; 58 } 59 setNumAttemptedMeasurements(int num)60 public RangingResultBuilder setNumAttemptedMeasurements(int num) { 61 this.numAttemptedMeasurements = num; 62 return this; 63 } 64 setNumSuccessfulMeasurements(int num)65 public RangingResultBuilder setNumSuccessfulMeasurements(int num) { 66 this.numSuccessfulMeasurements = num; 67 return this; 68 } 69 setLci(byte[] lci)70 public RangingResultBuilder setLci(byte[] lci) { 71 this.lci = lci; 72 return this; 73 } 74 setLcr(byte[] lcr)75 public RangingResultBuilder setLcr(byte[] lcr) { 76 this.lcr = lcr; 77 return this; 78 } 79 setUnverifiedResponderLocation( ResponderLocation unverifiedResponderLocation)80 public RangingResultBuilder setUnverifiedResponderLocation( 81 ResponderLocation unverifiedResponderLocation) { 82 this.unverifiedResponderLocation = unverifiedResponderLocation; 83 return this; 84 } 85 setIs80211mcMeasurement(boolean is80211mcMeasurement)86 public RangingResultBuilder setIs80211mcMeasurement(boolean is80211mcMeasurement) { 87 this.is80211mcMeasurement = is80211mcMeasurement; 88 return this; 89 } 90 build()91 public RangingResult build() { 92 if (RuntimeEnvironment.getApiLevel() >= V.SDK_INT) { 93 Object builder; 94 try { 95 builder = 96 ReflectionHelpers.newInstance( 97 Class.forName("android.net.wifi.rtt.RangingResult$Builder")); 98 } catch (ClassNotFoundException e) { 99 throw new RuntimeException(e); 100 } 101 102 reflector(RangingResultBuilderReflector.class, builder).setStatus(status); 103 reflector(RangingResultBuilderReflector.class, builder).setMacAddress(mac); 104 reflector(RangingResultBuilderReflector.class, builder).setDistanceMm(distanceMm); 105 reflector(RangingResultBuilderReflector.class, builder).setDistanceStdDevMm(distanceStdDevMm); 106 reflector(RangingResultBuilderReflector.class, builder).setRssi(rssi); 107 reflector(RangingResultBuilderReflector.class, builder) 108 .setNumAttemptedMeasurements(numAttemptedMeasurements); 109 reflector(RangingResultBuilderReflector.class, builder) 110 .setNumSuccessfulMeasurements(numSuccessfulMeasurements); 111 reflector(RangingResultBuilderReflector.class, builder).setLci(lci); 112 reflector(RangingResultBuilderReflector.class, builder).setLcr(lcr); 113 reflector(RangingResultBuilderReflector.class, builder) 114 .setUnverifiedResponderLocation(unverifiedResponderLocation); 115 reflector(RangingResultBuilderReflector.class, builder) 116 .setRangingTimestampMillis(timestampMillis); 117 reflector(RangingResultBuilderReflector.class, builder) 118 .set80211mcMeasurement(is80211mcMeasurement); 119 return reflector(RangingResultBuilderReflector.class, builder).build(); 120 } 121 if (RuntimeEnvironment.getApiLevel() > Build.VERSION_CODES.R) { 122 return asRangingResultS( 123 status, 124 mac, 125 distanceMm, 126 distanceStdDevMm, 127 rssi, 128 numAttemptedMeasurements, 129 numSuccessfulMeasurements, 130 lci, 131 lcr, 132 unverifiedResponderLocation, 133 timestampMillis, 134 is80211mcMeasurement); 135 } 136 137 if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.Q) { 138 return asRangingResultQ( 139 status, 140 mac, 141 distanceMm, 142 distanceStdDevMm, 143 rssi, 144 numAttemptedMeasurements, 145 numSuccessfulMeasurements, 146 lci, 147 lcr, 148 unverifiedResponderLocation, 149 timestampMillis); 150 } 151 152 return asRangingResultP( 153 status, 154 mac, 155 distanceMm, 156 distanceStdDevMm, 157 rssi, 158 numAttemptedMeasurements, 159 numSuccessfulMeasurements, 160 lci, 161 lcr, 162 timestampMillis); 163 } 164 asRangingResultP( int status, MacAddress mac, int distanceMm, int distanceStdDevMm, int rssi, int numAttemptedMeasurements, int numSuccessfulMeasurements, byte[] lci, byte[] lcr, long timestampMillis)165 private static RangingResult asRangingResultP( 166 int status, 167 MacAddress mac, 168 int distanceMm, 169 int distanceStdDevMm, 170 int rssi, 171 int numAttemptedMeasurements, 172 int numSuccessfulMeasurements, 173 byte[] lci, 174 byte[] lcr, 175 long timestampMillis) { 176 return ReflectionHelpers.callConstructor( 177 RangingResult.class, 178 ReflectionHelpers.ClassParameter.from(int.class, status), 179 ReflectionHelpers.ClassParameter.from(MacAddress.class, mac), 180 ReflectionHelpers.ClassParameter.from(int.class, distanceMm), 181 ReflectionHelpers.ClassParameter.from(int.class, distanceStdDevMm), 182 ReflectionHelpers.ClassParameter.from(int.class, rssi), 183 ReflectionHelpers.ClassParameter.from(int.class, numAttemptedMeasurements), 184 ReflectionHelpers.ClassParameter.from(int.class, numSuccessfulMeasurements), 185 ReflectionHelpers.ClassParameter.from(byte[].class, lci), 186 ReflectionHelpers.ClassParameter.from(byte[].class, lcr), 187 ReflectionHelpers.ClassParameter.from(long.class, timestampMillis)); 188 } 189 asRangingResultQ( int status, MacAddress mac, int distanceMm, int distanceStdDevMm, int rssi, int numAttemptedMeasurements, int numSuccessfulMeasurements, byte[] lci, byte[] lcr, ResponderLocation unverifiedResponderLocation, long timestampMillis)190 private static RangingResult asRangingResultQ( 191 int status, 192 MacAddress mac, 193 int distanceMm, 194 int distanceStdDevMm, 195 int rssi, 196 int numAttemptedMeasurements, 197 int numSuccessfulMeasurements, 198 byte[] lci, 199 byte[] lcr, 200 ResponderLocation unverifiedResponderLocation, 201 long timestampMillis) { 202 return ReflectionHelpers.callConstructor( 203 RangingResult.class, 204 ReflectionHelpers.ClassParameter.from(int.class, status), 205 ReflectionHelpers.ClassParameter.from(MacAddress.class, mac), 206 ReflectionHelpers.ClassParameter.from(int.class, distanceMm), 207 ReflectionHelpers.ClassParameter.from(int.class, distanceStdDevMm), 208 ReflectionHelpers.ClassParameter.from(int.class, rssi), 209 ReflectionHelpers.ClassParameter.from(int.class, numAttemptedMeasurements), 210 ReflectionHelpers.ClassParameter.from(int.class, numSuccessfulMeasurements), 211 ReflectionHelpers.ClassParameter.from(byte[].class, lci), 212 ReflectionHelpers.ClassParameter.from(byte[].class, lcr), 213 ReflectionHelpers.ClassParameter.from(ResponderLocation.class, unverifiedResponderLocation), 214 ReflectionHelpers.ClassParameter.from(long.class, timestampMillis)); 215 } 216 asRangingResultS( int status, MacAddress mac, int distanceMm, int distanceStdDevMm, int rssi, int numAttemptedMeasurements, int numSuccessfulMeasurements, byte[] lci, byte[] lcr, ResponderLocation unverifiedResponderLocation, long timestamp, boolean is80211mcMeasurement)217 private static RangingResult asRangingResultS( 218 int status, 219 MacAddress mac, 220 int distanceMm, 221 int distanceStdDevMm, 222 int rssi, 223 int numAttemptedMeasurements, 224 int numSuccessfulMeasurements, 225 byte[] lci, 226 byte[] lcr, 227 ResponderLocation unverifiedResponderLocation, 228 long timestamp, 229 boolean is80211mcMeasurement) { 230 return ReflectionHelpers.callConstructor( 231 RangingResult.class, 232 ReflectionHelpers.ClassParameter.from(int.class, status), 233 ReflectionHelpers.ClassParameter.from(MacAddress.class, mac), 234 ReflectionHelpers.ClassParameter.from(int.class, distanceMm), 235 ReflectionHelpers.ClassParameter.from(int.class, distanceStdDevMm), 236 ReflectionHelpers.ClassParameter.from(int.class, rssi), 237 ReflectionHelpers.ClassParameter.from(int.class, numAttemptedMeasurements), 238 ReflectionHelpers.ClassParameter.from(int.class, numSuccessfulMeasurements), 239 ReflectionHelpers.ClassParameter.from(byte[].class, lci), 240 ReflectionHelpers.ClassParameter.from(byte[].class, lcr), 241 ReflectionHelpers.ClassParameter.from(ResponderLocation.class, unverifiedResponderLocation), 242 ReflectionHelpers.ClassParameter.from(long.class, timestamp), 243 ReflectionHelpers.ClassParameter.from(boolean.class, is80211mcMeasurement)); 244 } 245 246 @ForType(className = "android.net.wifi.rtt.RangingResult$Builder") 247 interface RangingResultBuilderReflector { 248 @Accessor("mStatus") setStatus(int status)249 void setStatus(int status); 250 251 @Accessor("mMac") setMacAddress(MacAddress macAddress)252 void setMacAddress(MacAddress macAddress); 253 254 @Accessor("mPeerHandle") setPeerHandle(PeerHandle peerHandle)255 void setPeerHandle(PeerHandle peerHandle); 256 257 @Accessor("mDistanceMm") setDistanceMm(int distanceMm)258 void setDistanceMm(int distanceMm); 259 260 @Accessor("mDistanceStdDevMm") setDistanceStdDevMm(int distanceStdDevMm)261 void setDistanceStdDevMm(int distanceStdDevMm); 262 263 @Accessor("mRssi") setRssi(int rssi)264 void setRssi(int rssi); 265 266 @Accessor("mNumAttemptedMeasurements") setNumAttemptedMeasurements(int numAttemptedMeasurements)267 void setNumAttemptedMeasurements(int numAttemptedMeasurements); 268 269 @Accessor("mNumSuccessfulMeasurements") setNumSuccessfulMeasurements(int numSuccessfulMeasurements)270 void setNumSuccessfulMeasurements(int numSuccessfulMeasurements); 271 272 @Accessor("mLci") setLci(byte[] lci)273 void setLci(byte[] lci); 274 275 @Accessor("mLcr") setLcr(byte[] lcr)276 void setLcr(byte[] lcr); 277 278 @Accessor("mResponderLocation") setUnverifiedResponderLocation(ResponderLocation responderLocation)279 void setUnverifiedResponderLocation(ResponderLocation responderLocation); 280 281 @Accessor("mTimestamp") setRangingTimestampMillis(long timestamp)282 void setRangingTimestampMillis(long timestamp); 283 284 @Accessor("mIs80211mcMeasurement") set80211mcMeasurement(boolean is80211mcMeasurement)285 void set80211mcMeasurement(boolean is80211mcMeasurement); 286 287 @Accessor("mFrequencyMHz") setMeasurementChannelFrequencyMHz(int frequencyMHz)288 void setMeasurementChannelFrequencyMHz(int frequencyMHz); 289 290 @Accessor("mPacketBw") setMeasurementBandwidth(@hannelWidth int measurementBandwidth)291 void setMeasurementBandwidth(@ChannelWidth int measurementBandwidth); 292 293 @Accessor("mIs80211azNtbMeasurement") set80211azNtbMeasurement(boolean is80211azNtbMeasurement)294 void set80211azNtbMeasurement(boolean is80211azNtbMeasurement); 295 296 @Accessor("mNtbMinMeasurementTime") setMinTimeBetweenNtbMeasurementsMicros(long ntbMinMeasurementTime)297 void setMinTimeBetweenNtbMeasurementsMicros(long ntbMinMeasurementTime); 298 299 @Accessor("mNtbMaxMeasurementTime") setMaxTimeBetweenNtbMeasurementsMicros(long ntbMaxMeasurementTime)300 void setMaxTimeBetweenNtbMeasurementsMicros(long ntbMaxMeasurementTime); 301 302 @Accessor("mI2rTxLtfRepetitions") set80211azInitiatorTxLtfRepetitionsCount(int i2rTxLtfRepetitions)303 void set80211azInitiatorTxLtfRepetitionsCount(int i2rTxLtfRepetitions); 304 305 @Accessor("mR2iTxLtfRepetitions") set80211azResponderTxLtfRepetitionsCount(int r2iTxLtfRepetitions)306 void set80211azResponderTxLtfRepetitionsCount(int r2iTxLtfRepetitions); 307 308 @Accessor("mNumTxSpatialStreams") set80211azNumberOfTxSpatialStreams(int numTxSpatialStreams)309 void set80211azNumberOfTxSpatialStreams(int numTxSpatialStreams); 310 311 @Accessor("mNumRxSpatialStreams") set80211azNumberOfRxSpatialStreams(int numRxSpatialStreams)312 void set80211azNumberOfRxSpatialStreams(int numRxSpatialStreams); 313 314 @Accessor("mVendorData") setVendorData( @ithType"java.util.List<android.net.wifi.OuiKeyedData>") Object vendorData)315 void setVendorData( 316 @WithType("java.util.List<android.net.wifi.OuiKeyedData>") Object vendorData); 317 build()318 RangingResult build(); 319 } 320 } 321