From 9ae9b395e00432a6c8d69bc9c838b788e51ae6c1 Mon Sep 17 00:00:00 2001 From: Brian Stack Date: Wed, 21 Oct 2020 13:24:00 -0700 Subject: [PATCH 1/2] Implement UWB Address Bug: 170323306 Test: Builds Change-Id: I36a6c9f1dd995e3a1d50f5eea3c4ef14d15a123e --- core/java/android/uwb/UwbAddress.java | 35 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java index 48fcb10e1a1a6..335e4fdf8c623 100644 --- a/core/java/android/uwb/UwbAddress.java +++ b/core/java/android/uwb/UwbAddress.java @@ -19,6 +19,8 @@ package android.uwb; import android.annotation.NonNull; import android.annotation.Nullable; +import java.util.Arrays; + /** * A class representing a UWB address * @@ -28,6 +30,12 @@ public final class UwbAddress { public static final int SHORT_ADDRESS_BYTE_LENGTH = 2; public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8; + private final byte[] mAddressBytes; + + private UwbAddress(byte[] address) { + mAddressBytes = address; + } + /** * Create a {@link UwbAddress} from a byte array. * @@ -37,12 +45,16 @@ public final class UwbAddress { * * @param address a byte array to convert to a {@link UwbAddress} * @return a {@link UwbAddress} created from the input byte array - * @throw IllegableArumentException when the length is not one of + * @throws IllegalArgumentException when the length is not one of * {@link #SHORT_ADDRESS_BYTE_LENGTH} or {@link #EXTENDED_ADDRESS_BYTE_LENGTH} bytes */ @NonNull - public static UwbAddress fromBytes(byte[] address) throws IllegalArgumentException { - throw new UnsupportedOperationException(); + public static UwbAddress fromBytes(@NonNull byte[] address) throws IllegalArgumentException { + if (address.length != SHORT_ADDRESS_BYTE_LENGTH + && address.length != EXTENDED_ADDRESS_BYTE_LENGTH) { + throw new IllegalArgumentException("Invalid UwbAddress length " + address.length); + } + return new UwbAddress(address); } /** @@ -52,7 +64,7 @@ public final class UwbAddress { */ @NonNull public byte[] toBytes() { - throw new UnsupportedOperationException(); + return mAddressBytes; } /** @@ -61,22 +73,29 @@ public final class UwbAddress { * {@link #EXTENDED_ADDRESS_BYTE_LENGTH}. */ public int size() { - throw new UnsupportedOperationException(); + return mAddressBytes.length; } @NonNull @Override public String toString() { - throw new UnsupportedOperationException(); + StringBuilder builder = new StringBuilder("0x"); + for (byte addressByte : mAddressBytes) { + builder.append(String.format("%02X", addressByte)); + } + return builder.toString(); } @Override public boolean equals(@Nullable Object obj) { - throw new UnsupportedOperationException(); + if (obj instanceof UwbAddress) { + return Arrays.equals(mAddressBytes, ((UwbAddress) obj).toBytes()); + } + return false; } @Override public int hashCode() { - throw new UnsupportedOperationException(); + return Arrays.hashCode(mAddressBytes); } } From 3c99301acbd2be543cf32e1bbf29d8a00dd0fdc8 Mon Sep 17 00:00:00 2001 From: Brian Stack Date: Tue, 13 Oct 2020 13:29:56 -0700 Subject: [PATCH 2/2] Implement parcelable for UWB types Make the UWB objects parcelable so that they may be re-used in AIDL interfaces. Bug: 170323306 Test: Builds Change-Id: I8d3b81a581e66f2c777bedfd42a877548a51e875 --- core/java/android/uwb/AngleMeasurement.java | 35 ++++++++++- .../uwb/AngleOfArrivalMeasurement.java | 36 ++++++++++- .../java/android/uwb/DistanceMeasurement.java | 33 +++++++++- core/java/android/uwb/RangingMeasurement.java | 40 +++++++++++- core/java/android/uwb/RangingParams.java | 62 ++++++++++++++++++- core/java/android/uwb/RangingReport.java | 29 ++++++++- core/java/android/uwb/UwbAddress.java | 30 ++++++++- 7 files changed, 256 insertions(+), 9 deletions(-) diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java index c3e2ecc9e0f31..cf32b922078e6 100644 --- a/core/java/android/uwb/AngleMeasurement.java +++ b/core/java/android/uwb/AngleMeasurement.java @@ -17,6 +17,8 @@ package android.uwb; import android.annotation.FloatRange; +import android.os.Parcel; +import android.os.Parcelable; /** * Angle measurement @@ -26,7 +28,7 @@ import android.annotation.FloatRange; * * @hide */ -public final class AngleMeasurement { +public final class AngleMeasurement implements Parcelable { private final double mRadians; private final double mErrorRadians; private final double mConfidenceLevel; @@ -39,7 +41,7 @@ public final class AngleMeasurement { /** * Angle measurement in radians - * + * * @return angle in radians */ @FloatRange(from = -Math.PI, to = +Math.PI) @@ -73,6 +75,35 @@ public final class AngleMeasurement { return mConfidenceLevel; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeDouble(mRadians); + dest.writeDouble(mErrorRadians); + dest.writeDouble(mConfidenceLevel); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public AngleMeasurement createFromParcel(Parcel in) { + Builder builder = new Builder(); + builder.setRadians(in.readDouble()); + builder.setErrorRadians(in.readDouble()); + builder.setConfidenceLevel(in.readDouble()); + return builder.build(); + } + + @Override + public AngleMeasurement[] newArray(int size) { + return new AngleMeasurement[size]; + } + }; + /** * Builder class for {@link AngleMeasurement}. */ diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java index a7b5eae728cbf..646bd42cef2a7 100644 --- a/core/java/android/uwb/AngleOfArrivalMeasurement.java +++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java @@ -18,13 +18,15 @@ package android.uwb; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; /** * Represents an angle of arrival measurement between two devices using Ultra Wideband * * @hide */ -public final class AngleOfArrivalMeasurement { +public final class AngleOfArrivalMeasurement implements Parcelable { private final AngleMeasurement mAzimuthAngleMeasurement; private final AngleMeasurement mAltitudeAngleMeasurement; @@ -70,6 +72,38 @@ public final class AngleOfArrivalMeasurement { return mAltitudeAngleMeasurement; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mAzimuthAngleMeasurement, flags); + dest.writeParcelable(mAltitudeAngleMeasurement, flags); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public AngleOfArrivalMeasurement createFromParcel(Parcel in) { + Builder builder = new Builder(); + + builder.setAzimuthAngleMeasurement( + in.readParcelable(AngleMeasurement.class.getClassLoader())); + + builder.setAltitudeAngleMeasurement( + in.readParcelable(AngleMeasurement.class.getClassLoader())); + + return builder.build(); + } + + @Override + public AngleOfArrivalMeasurement[] newArray(int size) { + return new AngleOfArrivalMeasurement[size]; + } + }; + /** * Builder class for {@link AngleOfArrivalMeasurement}. */ diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java index 4cd5d83f4efc7..9561be449a199 100644 --- a/core/java/android/uwb/DistanceMeasurement.java +++ b/core/java/android/uwb/DistanceMeasurement.java @@ -17,6 +17,8 @@ package android.uwb; import android.annotation.FloatRange; +import android.os.Parcel; +import android.os.Parcelable; /** * A data point for the distance measurement @@ -26,7 +28,7 @@ import android.annotation.FloatRange; * * @hide */ -public final class DistanceMeasurement { +public final class DistanceMeasurement implements Parcelable { private final double mMeters; private final double mErrorMeters; private final double mConfidenceLevel; @@ -69,6 +71,35 @@ public final class DistanceMeasurement { return mConfidenceLevel; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeDouble(mMeters); + dest.writeDouble(mErrorMeters); + dest.writeDouble(mConfidenceLevel); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public DistanceMeasurement createFromParcel(Parcel in) { + Builder builder = new Builder(); + builder.setMeters(in.readDouble()); + builder.setErrorMeters(in.readDouble()); + builder.setConfidenceLevel(in.readDouble()); + return builder.build(); + } + + @Override + public DistanceMeasurement[] newArray(int size) { + return new DistanceMeasurement[size]; + } + }; + /** * Builder to get a {@link DistanceMeasurement} object. */ diff --git a/core/java/android/uwb/RangingMeasurement.java b/core/java/android/uwb/RangingMeasurement.java index 33a34e3954c2a..d4d7fb23959a3 100644 --- a/core/java/android/uwb/RangingMeasurement.java +++ b/core/java/android/uwb/RangingMeasurement.java @@ -20,6 +20,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; +import android.os.Parcel; +import android.os.Parcelable; import android.os.SystemClock; import java.lang.annotation.Retention; @@ -30,7 +32,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ -public final class RangingMeasurement { +public final class RangingMeasurement implements Parcelable { private final UwbAddress mRemoteDeviceAddress; private final @Status int mStatus; private final long mElapsedRealtimeNanos; @@ -127,6 +129,42 @@ public final class RangingMeasurement { return mAngleOfArrivalMeasurement; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mRemoteDeviceAddress, flags); + dest.writeInt(mStatus); + dest.writeLong(mElapsedRealtimeNanos); + dest.writeParcelable(mDistanceMeasurement, flags); + dest.writeParcelable(mAngleOfArrivalMeasurement, flags); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public RangingMeasurement createFromParcel(Parcel in) { + Builder builder = new Builder(); + builder.setRemoteDeviceAddress( + in.readParcelable(UwbAddress.class.getClassLoader())); + builder.setStatus(in.readInt()); + builder.setElapsedRealtimeNanos(in.readLong()); + builder.setDistanceMeasurement( + in.readParcelable(DistanceMeasurement.class.getClassLoader())); + builder.setAngleOfArrivalMeasurement( + in.readParcelable(AngleOfArrivalMeasurement.class.getClassLoader())); + return builder.build(); + } + + @Override + public RangingMeasurement[] newArray(int size) { + return new RangingMeasurement[size]; + } + }; + /** * Builder for a {@link RangingMeasurement} object. */ diff --git a/core/java/android/uwb/RangingParams.java b/core/java/android/uwb/RangingParams.java index a50de3e614256..c5d4807859b56 100644 --- a/core/java/android/uwb/RangingParams.java +++ b/core/java/android/uwb/RangingParams.java @@ -19,11 +19,13 @@ package android.uwb; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; import android.os.PersistableBundle; -import android.util.Duration; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -36,7 +38,7 @@ import java.util.Set; * * @hide */ -public final class RangingParams { +public final class RangingParams implements Parcelable { private final boolean mIsInitiator; private final boolean mIsController; private final Duration mSamplePeriod; @@ -199,6 +201,62 @@ public final class RangingParams { return new PersistableBundle(mSpecificationParameters); } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeBoolean(mIsInitiator); + dest.writeBoolean(mIsController); + dest.writeLong(mSamplePeriod.getSeconds()); + dest.writeInt(mSamplePeriod.getNano()); + dest.writeParcelable(mLocalDeviceAddress, flags); + + UwbAddress[] remoteAddresses = new UwbAddress[mRemoteDeviceAddresses.size()]; + mRemoteDeviceAddresses.toArray(remoteAddresses); + dest.writeParcelableArray(remoteAddresses, flags); + + dest.writeInt(mChannelNumber); + dest.writeInt(mTransmitPreambleCodeIndex); + dest.writeInt(mReceivePreambleCodeIndex); + dest.writeInt(mStsPhyPacketType); + dest.writePersistableBundle(mSpecificationParameters); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public RangingParams createFromParcel(Parcel in) { + Builder builder = new Builder(); + builder.setIsInitiator(in.readBoolean()); + builder.setIsController(in.readBoolean()); + builder.setSamplePeriod(Duration.ofSeconds(in.readLong(), in.readInt())); + builder.setLocalDeviceAddress( + in.readParcelable(UwbAddress.class.getClassLoader())); + + UwbAddress[] remoteAddresses = + in.readParcelableArray(null, UwbAddress.class); + for (UwbAddress remoteAddress : remoteAddresses) { + builder.addRemoteDeviceAddress(remoteAddress); + } + + builder.setChannelNumber(in.readInt()); + builder.setTransmitPreambleCodeIndex(in.readInt()); + builder.setReceivePreambleCodeIndex(in.readInt()); + builder.setStsPhPacketType(in.readInt()); + builder.setSpecificationParameters(in.readPersistableBundle()); + + return builder.build(); + } + + @Override + public RangingParams[] newArray(int size) { + return new RangingParams[size]; + } + }; + /** * Builder class for {@link RangingParams}. */ diff --git a/core/java/android/uwb/RangingReport.java b/core/java/android/uwb/RangingReport.java index 5aca12aaf2cf0..1d340b4b03584 100644 --- a/core/java/android/uwb/RangingReport.java +++ b/core/java/android/uwb/RangingReport.java @@ -17,6 +17,8 @@ package android.uwb; import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; import java.util.ArrayList; import java.util.List; @@ -26,7 +28,7 @@ import java.util.List; * * @hide */ -public final class RangingReport { +public final class RangingReport implements Parcelable { private final List mRangingMeasurements; private RangingReport(@NonNull List rangingMeasurements) { @@ -48,6 +50,31 @@ public final class RangingReport { return mRangingMeasurements; } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeTypedList(mRangingMeasurements); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public RangingReport createFromParcel(Parcel in) { + Builder builder = new Builder(); + builder.addMeasurements(in.createTypedArrayList(RangingMeasurement.CREATOR)); + return builder.build(); + } + + @Override + public RangingReport[] newArray(int size) { + return new RangingReport[size]; + } + }; + /** * Builder for {@link RangingReport} object */ diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java index 335e4fdf8c623..828324c54c5a9 100644 --- a/core/java/android/uwb/UwbAddress.java +++ b/core/java/android/uwb/UwbAddress.java @@ -18,6 +18,8 @@ package android.uwb; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; import java.util.Arrays; @@ -26,7 +28,7 @@ import java.util.Arrays; * * @hide */ -public final class UwbAddress { +public final class UwbAddress implements Parcelable { public static final int SHORT_ADDRESS_BYTE_LENGTH = 2; public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8; @@ -98,4 +100,30 @@ public final class UwbAddress { public int hashCode() { return Arrays.hashCode(mAddressBytes); } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mAddressBytes.length); + dest.writeByteArray(mAddressBytes); + } + + public static final @android.annotation.NonNull Creator CREATOR = + new Creator() { + @Override + public UwbAddress createFromParcel(Parcel in) { + byte[] address = new byte[in.readInt()]; + in.readByteArray(address); + return UwbAddress.fromBytes(address); + } + + @Override + public UwbAddress[] newArray(int size) { + return new UwbAddress[size]; + } + }; }