Merge changes I732f0e78,I7a8f668c,I1f439621,I55122a7b,I83c43497, ... am: d318d93dd5 am: bad1cba5f0 am: 0e38639186
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1457564 Change-Id: I36756ceda42bf38df9ccd30e76ea7aa6f4d5266e
This commit is contained in:
@@ -27,6 +27,16 @@ import android.annotation.FloatRange;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class AngleMeasurement {
|
public final class AngleMeasurement {
|
||||||
|
private final double mRadians;
|
||||||
|
private final double mErrorRadians;
|
||||||
|
private final double mConfidenceLevel;
|
||||||
|
|
||||||
|
private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
|
||||||
|
mRadians = radians;
|
||||||
|
mErrorRadians = errorRadians;
|
||||||
|
mConfidenceLevel = confidenceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Angle measurement in radians
|
* Angle measurement in radians
|
||||||
*
|
*
|
||||||
@@ -34,7 +44,7 @@ public final class AngleMeasurement {
|
|||||||
*/
|
*/
|
||||||
@FloatRange(from = -Math.PI, to = +Math.PI)
|
@FloatRange(from = -Math.PI, to = +Math.PI)
|
||||||
public double getRadians() {
|
public double getRadians() {
|
||||||
throw new UnsupportedOperationException();
|
return mRadians;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +56,7 @@ public final class AngleMeasurement {
|
|||||||
*/
|
*/
|
||||||
@FloatRange(from = 0.0, to = +Math.PI)
|
@FloatRange(from = 0.0, to = +Math.PI)
|
||||||
public double getErrorRadians() {
|
public double getErrorRadians() {
|
||||||
throw new UnsupportedOperationException();
|
return mErrorRadians;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +70,80 @@ public final class AngleMeasurement {
|
|||||||
*/
|
*/
|
||||||
@FloatRange(from = 0.0, to = 1.0)
|
@FloatRange(from = 0.0, to = 1.0)
|
||||||
public double getConfidenceLevel() {
|
public double getConfidenceLevel() {
|
||||||
throw new UnsupportedOperationException();
|
return mConfidenceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for {@link AngleMeasurement}.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private double mRadians = Double.NaN;
|
||||||
|
private double mErrorRadians = Double.NaN;
|
||||||
|
private double mConfidenceLevel = Double.NaN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the angle in radians
|
||||||
|
*
|
||||||
|
* @param radians angle in radians
|
||||||
|
* @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI]
|
||||||
|
*/
|
||||||
|
public Builder setRadians(double radians) {
|
||||||
|
if (radians < -Math.PI || radians > Math.PI) {
|
||||||
|
throw new IllegalArgumentException("Invalid radians: " + radians);
|
||||||
|
}
|
||||||
|
mRadians = radians;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the angle error in radians
|
||||||
|
*
|
||||||
|
* @param errorRadians error of the angle in radians
|
||||||
|
* @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI]
|
||||||
|
*/
|
||||||
|
public Builder setErrorRadians(double errorRadians) {
|
||||||
|
if (errorRadians < 0.0 || errorRadians > Math.PI) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid error radians: " + errorRadians);
|
||||||
|
}
|
||||||
|
mErrorRadians = errorRadians;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the angle confidence level
|
||||||
|
*
|
||||||
|
* @param confidenceLevel level of confidence of the angle measurement
|
||||||
|
* @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0]
|
||||||
|
*/
|
||||||
|
public Builder setConfidenceLevel(double confidenceLevel) {
|
||||||
|
if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid confidence level: " + confidenceLevel);
|
||||||
|
}
|
||||||
|
mConfidenceLevel = confidenceLevel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link AngleMeasurement} object
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if angle, error, or confidence values are missing
|
||||||
|
*/
|
||||||
|
public AngleMeasurement build() {
|
||||||
|
if (Double.isNaN(mRadians)) {
|
||||||
|
throw new IllegalStateException("Angle is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Double.isNaN(mErrorRadians)) {
|
||||||
|
throw new IllegalStateException("Angle error is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Double.isNaN(mConfidenceLevel)) {
|
||||||
|
throw new IllegalStateException("Angle confidence level is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,15 @@ import android.annotation.Nullable;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class AngleOfArrivalMeasurement {
|
public final class AngleOfArrivalMeasurement {
|
||||||
|
private final AngleMeasurement mAzimuthAngleMeasurement;
|
||||||
|
private final AngleMeasurement mAltitudeAngleMeasurement;
|
||||||
|
|
||||||
|
private AngleOfArrivalMeasurement(@NonNull AngleMeasurement azimuthAngleMeasurement,
|
||||||
|
@Nullable AngleMeasurement altitudeAngleMeasurement) {
|
||||||
|
mAzimuthAngleMeasurement = azimuthAngleMeasurement;
|
||||||
|
mAltitudeAngleMeasurement = altitudeAngleMeasurement;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Azimuth angle measurement
|
* Azimuth angle measurement
|
||||||
* <p>Azimuth {@link AngleMeasurement} of remote device in horizontal coordinate system, this is
|
* <p>Azimuth {@link AngleMeasurement} of remote device in horizontal coordinate system, this is
|
||||||
@@ -41,7 +50,7 @@ public final class AngleOfArrivalMeasurement {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public AngleMeasurement getAzimuth() {
|
public AngleMeasurement getAzimuth() {
|
||||||
throw new UnsupportedOperationException();
|
return mAzimuthAngleMeasurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,6 +67,48 @@ public final class AngleOfArrivalMeasurement {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public AngleMeasurement getAltitude() {
|
public AngleMeasurement getAltitude() {
|
||||||
throw new UnsupportedOperationException();
|
return mAltitudeAngleMeasurement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for {@link AngleOfArrivalMeasurement}.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private AngleMeasurement mAzimuthAngleMeasurement = null;
|
||||||
|
private AngleMeasurement mAltitudeAngleMeasurement = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the azimuth angle
|
||||||
|
*
|
||||||
|
* @param azimuthAngle azimuth angle
|
||||||
|
*/
|
||||||
|
public Builder setAzimuthAngleMeasurement(@NonNull AngleMeasurement azimuthAngle) {
|
||||||
|
mAzimuthAngleMeasurement = azimuthAngle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the altitude angle
|
||||||
|
*
|
||||||
|
* @param altitudeAngle altitude angle
|
||||||
|
*/
|
||||||
|
public Builder setAltitudeAngleMeasurement(@NonNull AngleMeasurement altitudeAngle) {
|
||||||
|
mAltitudeAngleMeasurement = altitudeAngle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link AngleOfArrivalMeasurement} object
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if the required azimuth angle is not provided
|
||||||
|
*/
|
||||||
|
public AngleOfArrivalMeasurement build() {
|
||||||
|
if (mAzimuthAngleMeasurement == null) {
|
||||||
|
throw new IllegalStateException("Azimuth angle measurement is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement,
|
||||||
|
mAltitudeAngleMeasurement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,23 @@ import android.annotation.FloatRange;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class DistanceMeasurement {
|
public final class DistanceMeasurement {
|
||||||
|
private final double mMeters;
|
||||||
|
private final double mErrorMeters;
|
||||||
|
private final double mConfidenceLevel;
|
||||||
|
|
||||||
|
private DistanceMeasurement(double meters, double errorMeters, double confidenceLevel) {
|
||||||
|
mMeters = meters;
|
||||||
|
mErrorMeters = errorMeters;
|
||||||
|
mConfidenceLevel = confidenceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Distance measurement in meters
|
* Distance measurement in meters
|
||||||
*
|
*
|
||||||
* @return distance in meters
|
* @return distance in meters
|
||||||
*/
|
*/
|
||||||
public double getMeters() {
|
public double getMeters() {
|
||||||
throw new UnsupportedOperationException();
|
return mMeters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +53,7 @@ public final class DistanceMeasurement {
|
|||||||
* @return error of distance measurement in meters
|
* @return error of distance measurement in meters
|
||||||
*/
|
*/
|
||||||
public double getErrorMeters() {
|
public double getErrorMeters() {
|
||||||
throw new UnsupportedOperationException();
|
return mErrorMeters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +66,80 @@ public final class DistanceMeasurement {
|
|||||||
*/
|
*/
|
||||||
@FloatRange(from = 0.0, to = 1.0)
|
@FloatRange(from = 0.0, to = 1.0)
|
||||||
public double getConfidenceLevel() {
|
public double getConfidenceLevel() {
|
||||||
throw new UnsupportedOperationException();
|
return mConfidenceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder to get a {@link DistanceMeasurement} object.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private double mMeters = Double.NaN;
|
||||||
|
private double mErrorMeters = Double.NaN;
|
||||||
|
private double mConfidenceLevel = Double.NaN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the distance measurement in meters
|
||||||
|
*
|
||||||
|
* @param meters distance in meters
|
||||||
|
* @throws IllegalArgumentException if meters is NaN
|
||||||
|
*/
|
||||||
|
public Builder setMeters(double meters) {
|
||||||
|
if (Double.isNaN(meters)) {
|
||||||
|
throw new IllegalArgumentException("meters cannot be NaN");
|
||||||
|
}
|
||||||
|
mMeters = meters;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the distance error in meters
|
||||||
|
*
|
||||||
|
* @param errorMeters distance error in meters
|
||||||
|
* @throws IllegalArgumentException if error is negative or NaN
|
||||||
|
*/
|
||||||
|
public Builder setErrorMeters(double errorMeters) {
|
||||||
|
if (Double.isNaN(errorMeters) || errorMeters < 0.0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"errorMeters must be >= 0.0 and not NaN: " + errorMeters);
|
||||||
|
}
|
||||||
|
mErrorMeters = errorMeters;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the confidence level
|
||||||
|
*
|
||||||
|
* @param confidenceLevel the confidence level in the distance measurement
|
||||||
|
* @throws IllegalArgumentException if confidence level is not in the range of [0.0, 1.0]
|
||||||
|
*/
|
||||||
|
public Builder setConfidenceLevel(double confidenceLevel) {
|
||||||
|
if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"confidenceLevel must be in the range [0.0, 1.0]: " + confidenceLevel);
|
||||||
|
}
|
||||||
|
mConfidenceLevel = confidenceLevel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the {@link DistanceMeasurement} object
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if meters, error, or confidence are not set
|
||||||
|
*/
|
||||||
|
public DistanceMeasurement build() {
|
||||||
|
if (Double.isNaN(mMeters)) {
|
||||||
|
throw new IllegalStateException("Meters cannot be NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Double.isNaN(mErrorMeters)) {
|
||||||
|
throw new IllegalStateException("Error meters cannot be NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Double.isNaN(mConfidenceLevel)) {
|
||||||
|
throw new IllegalStateException("Confidence level cannot be NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DistanceMeasurement(mMeters, mErrorMeters, mConfidenceLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,22 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class RangingMeasurement {
|
public final class RangingMeasurement {
|
||||||
|
private final UwbAddress mRemoteDeviceAddress;
|
||||||
|
private final @Status int mStatus;
|
||||||
|
private final long mElapsedRealtimeNanos;
|
||||||
|
private final DistanceMeasurement mDistanceMeasurement;
|
||||||
|
private final AngleOfArrivalMeasurement mAngleOfArrivalMeasurement;
|
||||||
|
|
||||||
|
private RangingMeasurement(@NonNull UwbAddress remoteDeviceAddress, @Status int status,
|
||||||
|
long elapsedRealtimeNanos, @Nullable DistanceMeasurement distanceMeasurement,
|
||||||
|
@Nullable AngleOfArrivalMeasurement angleOfArrivalMeasurement) {
|
||||||
|
mRemoteDeviceAddress = remoteDeviceAddress;
|
||||||
|
mStatus = status;
|
||||||
|
mElapsedRealtimeNanos = elapsedRealtimeNanos;
|
||||||
|
mDistanceMeasurement = distanceMeasurement;
|
||||||
|
mAngleOfArrivalMeasurement = angleOfArrivalMeasurement;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the remote device's {@link UwbAddress}
|
* Get the remote device's {@link UwbAddress}
|
||||||
*
|
*
|
||||||
@@ -38,7 +54,7 @@ public final class RangingMeasurement {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public UwbAddress getRemoteDeviceAddress() {
|
public UwbAddress getRemoteDeviceAddress() {
|
||||||
throw new UnsupportedOperationException();
|
return mRemoteDeviceAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@@ -75,7 +91,7 @@ public final class RangingMeasurement {
|
|||||||
*/
|
*/
|
||||||
@Status
|
@Status
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
throw new UnsupportedOperationException();
|
return mStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +102,7 @@ public final class RangingMeasurement {
|
|||||||
*/
|
*/
|
||||||
@SuppressLint("MethodNameUnits")
|
@SuppressLint("MethodNameUnits")
|
||||||
public long getElapsedRealtimeNanos() {
|
public long getElapsedRealtimeNanos() {
|
||||||
throw new UnsupportedOperationException();
|
return mElapsedRealtimeNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +113,7 @@ public final class RangingMeasurement {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public DistanceMeasurement getDistance() {
|
public DistanceMeasurement getDistance() {
|
||||||
throw new UnsupportedOperationException();
|
return mDistanceMeasurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,6 +124,106 @@ public final class RangingMeasurement {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public AngleOfArrivalMeasurement getAngleOfArrival() {
|
public AngleOfArrivalMeasurement getAngleOfArrival() {
|
||||||
throw new UnsupportedOperationException();
|
return mAngleOfArrivalMeasurement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for a {@link RangingMeasurement} object.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private UwbAddress mRemoteDeviceAddress = null;
|
||||||
|
private @Status int mStatus = RANGING_STATUS_FAILURE_UNKNOWN_ERROR;
|
||||||
|
private long mElapsedRealtimeNanos = -1L;
|
||||||
|
private DistanceMeasurement mDistanceMeasurement = null;
|
||||||
|
private AngleOfArrivalMeasurement mAngleOfArrivalMeasurement = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the remote device address that this measurement is for
|
||||||
|
*
|
||||||
|
* @param remoteDeviceAddress remote device's address
|
||||||
|
*/
|
||||||
|
public Builder setRemoteDeviceAddress(@NonNull UwbAddress remoteDeviceAddress) {
|
||||||
|
mRemoteDeviceAddress = remoteDeviceAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the status of ranging measurement
|
||||||
|
*
|
||||||
|
* @param status the status of the ranging measurement
|
||||||
|
*/
|
||||||
|
public Builder setStatus(@Status int status) {
|
||||||
|
mStatus = status;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the elapsed realtime in nanoseconds when the ranging measurement occurred
|
||||||
|
*
|
||||||
|
* @param elapsedRealtimeNanos time the ranging measurement occurred
|
||||||
|
*/
|
||||||
|
public Builder setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
|
||||||
|
if (elapsedRealtimeNanos < 0) {
|
||||||
|
throw new IllegalArgumentException("elapsedRealtimeNanos must be >= 0");
|
||||||
|
}
|
||||||
|
mElapsedRealtimeNanos = elapsedRealtimeNanos;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link DistanceMeasurement}
|
||||||
|
*
|
||||||
|
* @param distanceMeasurement the distance measurement for this ranging measurement
|
||||||
|
*/
|
||||||
|
public Builder setDistanceMeasurement(@NonNull DistanceMeasurement distanceMeasurement) {
|
||||||
|
mDistanceMeasurement = distanceMeasurement;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link AngleOfArrivalMeasurement}
|
||||||
|
*
|
||||||
|
* @param angleOfArrivalMeasurement the angle of arrival measurement for this ranging
|
||||||
|
* measurement
|
||||||
|
*/
|
||||||
|
public Builder setAngleOfArrivalMeasurement(
|
||||||
|
@NonNull AngleOfArrivalMeasurement angleOfArrivalMeasurement) {
|
||||||
|
mAngleOfArrivalMeasurement = angleOfArrivalMeasurement;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link RangingMeasurement} object
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if a distance or angle of arrival measurement is provided
|
||||||
|
* but the measurement was not successful, if the
|
||||||
|
* elapsedRealtimeNanos of the measurement is invalid, or
|
||||||
|
* if no remote device address is set
|
||||||
|
*/
|
||||||
|
public RangingMeasurement build() {
|
||||||
|
if (mStatus != RANGING_STATUS_SUCCESS) {
|
||||||
|
if (mDistanceMeasurement != null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Distance Measurement must be null if ranging is not successful");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAngleOfArrivalMeasurement != null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Angle of Arrival must be null if ranging is not successful");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRemoteDeviceAddress == null) {
|
||||||
|
throw new IllegalStateException("No remote device address was set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mElapsedRealtimeNanos < 0) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"elapsedRealtimeNanos must be >=0: " + mElapsedRealtimeNanos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RangingMeasurement(mRemoteDeviceAddress, mStatus, mElapsedRealtimeNanos,
|
||||||
|
mDistanceMeasurement, mAngleOfArrivalMeasurement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ import android.util.Duration;
|
|||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object used when requesting to open a new {@link RangingSession}.
|
* An object used when requesting to open a new {@link RangingSession}.
|
||||||
@@ -33,11 +37,33 @@ import java.util.List;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class RangingParams {
|
public final class RangingParams {
|
||||||
/**
|
private final boolean mIsInitiator;
|
||||||
* Standard builder interface as the class is not modifiable
|
private final boolean mIsController;
|
||||||
*/
|
private final Duration mSamplePeriod;
|
||||||
public static class Builder {
|
private final UwbAddress mLocalDeviceAddress;
|
||||||
// TODO implement
|
private final List<UwbAddress> mRemoteDeviceAddresses;
|
||||||
|
private final int mChannelNumber;
|
||||||
|
private final int mTransmitPreambleCodeIndex;
|
||||||
|
private final int mReceivePreambleCodeIndex;
|
||||||
|
private final int mStsPhyPacketType;
|
||||||
|
private final PersistableBundle mSpecificationParameters;
|
||||||
|
|
||||||
|
private RangingParams(boolean isInitiator, boolean isController,
|
||||||
|
@NonNull Duration samplingPeriod, @NonNull UwbAddress localDeviceAddress,
|
||||||
|
@NonNull List<UwbAddress> remoteDeviceAddresses, int channelNumber,
|
||||||
|
int transmitPreambleCodeIndex, int receivePreambleCodeIndex,
|
||||||
|
@StsPhyPacketType int stsPhyPacketType,
|
||||||
|
@NonNull PersistableBundle specificationParameters) {
|
||||||
|
mIsInitiator = isInitiator;
|
||||||
|
mIsController = isController;
|
||||||
|
mSamplePeriod = samplingPeriod;
|
||||||
|
mLocalDeviceAddress = localDeviceAddress;
|
||||||
|
mRemoteDeviceAddresses = remoteDeviceAddresses;
|
||||||
|
mChannelNumber = channelNumber;
|
||||||
|
mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
|
||||||
|
mReceivePreambleCodeIndex = receivePreambleCodeIndex;
|
||||||
|
mStsPhyPacketType = stsPhyPacketType;
|
||||||
|
mSpecificationParameters = specificationParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +72,7 @@ public final class RangingParams {
|
|||||||
* @return true if the device is the initiator
|
* @return true if the device is the initiator
|
||||||
*/
|
*/
|
||||||
public boolean isInitiator() {
|
public boolean isInitiator() {
|
||||||
throw new UnsupportedOperationException();
|
return mIsInitiator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +81,7 @@ public final class RangingParams {
|
|||||||
* @return true if the device is the controller
|
* @return true if the device is the controller
|
||||||
*/
|
*/
|
||||||
public boolean isController() {
|
public boolean isController() {
|
||||||
throw new UnsupportedOperationException();
|
return mIsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +91,7 @@ public final class RangingParams {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public Duration getSamplingPeriod() {
|
public Duration getSamplingPeriod() {
|
||||||
throw new UnsupportedOperationException();
|
return mSamplePeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,7 +104,7 @@ public final class RangingParams {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public UwbAddress getLocalDeviceAddress() {
|
public UwbAddress getLocalDeviceAddress() {
|
||||||
throw new UnsupportedOperationException();
|
return mLocalDeviceAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,7 +114,7 @@ public final class RangingParams {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<UwbAddress> getRemoteDeviceAddresses() {
|
public List<UwbAddress> getRemoteDeviceAddresses() {
|
||||||
throw new UnsupportedOperationException();
|
return mRemoteDeviceAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +125,7 @@ public final class RangingParams {
|
|||||||
* @return the channel to use
|
* @return the channel to use
|
||||||
*/
|
*/
|
||||||
public int getChannelNumber() {
|
public int getChannelNumber() {
|
||||||
throw new UnsupportedOperationException();
|
return mChannelNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,7 +136,7 @@ public final class RangingParams {
|
|||||||
* @return the preamble index to use for transmitting
|
* @return the preamble index to use for transmitting
|
||||||
*/
|
*/
|
||||||
public int getTxPreambleIndex() {
|
public int getTxPreambleIndex() {
|
||||||
throw new UnsupportedOperationException();
|
return mTransmitPreambleCodeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,7 +147,7 @@ public final class RangingParams {
|
|||||||
* @return the preamble index to use for receiving
|
* @return the preamble index to use for receiving
|
||||||
*/
|
*/
|
||||||
public int getRxPreambleIndex() {
|
public int getRxPreambleIndex() {
|
||||||
throw new UnsupportedOperationException();
|
return mReceivePreambleCodeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@@ -159,7 +185,7 @@ public final class RangingParams {
|
|||||||
*/
|
*/
|
||||||
@StsPhyPacketType
|
@StsPhyPacketType
|
||||||
public int getStsPhyPacketType() {
|
public int getStsPhyPacketType() {
|
||||||
throw new UnsupportedOperationException();
|
return mStsPhyPacketType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,9 +193,189 @@ public final class RangingParams {
|
|||||||
*
|
*
|
||||||
* <p>Android reserves the '^android.*' namespace
|
* <p>Android reserves the '^android.*' namespace
|
||||||
*
|
*
|
||||||
* @return a {@link PersistableBundle} of protocol specific parameters
|
* @return a {@link PersistableBundle} copy of protocol specific parameters
|
||||||
*/
|
*/
|
||||||
public @Nullable PersistableBundle getSpecificationParameters() {
|
public @Nullable PersistableBundle getSpecificationParameters() {
|
||||||
throw new UnsupportedOperationException();
|
return new PersistableBundle(mSpecificationParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for {@link RangingParams}.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private boolean mIsInitiator = false;
|
||||||
|
private boolean mIsController = false;
|
||||||
|
private Duration mSamplePeriod = null;
|
||||||
|
private UwbAddress mLocalDeviceAddress = null;
|
||||||
|
private List<UwbAddress> mRemoteDeviceAddresses = new ArrayList<>();
|
||||||
|
private int mChannelNumber = 0;
|
||||||
|
private int mTransmitPreambleCodeIndex = 0;
|
||||||
|
private int mReceivePreambleCodeIndex = 0;
|
||||||
|
private int mStsPhyPacketType = STS_PHY_PACKET_TYPE_SP0;
|
||||||
|
private PersistableBundle mSpecificationParameters = new PersistableBundle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the device is the initiator or responder as defined by IEEE 802.15.4z
|
||||||
|
*
|
||||||
|
* @param isInitiator whether the device is the initiator (true) or responder (false)
|
||||||
|
*/
|
||||||
|
public Builder setIsInitiator(boolean isInitiator) {
|
||||||
|
mIsInitiator = isInitiator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the local device is the controller or controlee as defined by IEEE 802.15.4z
|
||||||
|
*
|
||||||
|
* @param isController whether the device is the controller (true) or controlee (false)
|
||||||
|
*/
|
||||||
|
public Builder setIsController(boolean isController) {
|
||||||
|
mIsController = isController;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the time between ranging samples
|
||||||
|
*
|
||||||
|
* @param samplePeriod the time between ranging samples
|
||||||
|
*/
|
||||||
|
public Builder setSamplePeriod(@NonNull Duration samplePeriod) {
|
||||||
|
mSamplePeriod = samplePeriod;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the local device address
|
||||||
|
*
|
||||||
|
* @param localDeviceAddress the local device's address for the {@link RangingSession}
|
||||||
|
*/
|
||||||
|
public Builder setLocalDeviceAddress(@NonNull UwbAddress localDeviceAddress) {
|
||||||
|
mLocalDeviceAddress = localDeviceAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a remote device's address to the ranging session
|
||||||
|
*
|
||||||
|
* @param remoteDeviceAddress a remote device's address for the {@link RangingSession}
|
||||||
|
* @throws IllegalArgumentException if {@code remoteDeviceAddress} is already present.
|
||||||
|
*/
|
||||||
|
public Builder addRemoteDeviceAddress(@NonNull UwbAddress remoteDeviceAddress) {
|
||||||
|
if (mRemoteDeviceAddresses.contains(remoteDeviceAddress)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Remote device address already added: " + remoteDeviceAddress.toString());
|
||||||
|
}
|
||||||
|
mRemoteDeviceAddresses.add(remoteDeviceAddress);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the IEEE 802.15.4z channel to use for the {@link RangingSession}
|
||||||
|
* <p>Valid values are in the range [-1, 15]
|
||||||
|
*
|
||||||
|
* @param channelNumber the channel to use for the {@link RangingSession}
|
||||||
|
* @throws IllegalArgumentException if {@code channelNumber} is invalid.
|
||||||
|
*/
|
||||||
|
public Builder setChannelNumber(int channelNumber) {
|
||||||
|
if (channelNumber < -1 || channelNumber > 15) {
|
||||||
|
throw new IllegalArgumentException("Invalid channel number");
|
||||||
|
}
|
||||||
|
mChannelNumber = channelNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<Integer> VALID_TX_PREAMBLE_CODES = new HashSet<Integer>(
|
||||||
|
Arrays.asList(0, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the IEEE 802.15.4z preamble code index to use when transmitting
|
||||||
|
*
|
||||||
|
* <p>Valid values are in the ranges: [0], [13-16], [21-32]
|
||||||
|
*
|
||||||
|
* @param transmitPreambleCodeIndex preamble code index to use for transmitting
|
||||||
|
* @throws IllegalArgumentException if {@code transmitPreambleCodeIndex} is invalid.
|
||||||
|
*/
|
||||||
|
public Builder setTransmitPreambleCodeIndex(int transmitPreambleCodeIndex) {
|
||||||
|
if (!VALID_TX_PREAMBLE_CODES.contains(transmitPreambleCodeIndex)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid transmit preamble: " + transmitPreambleCodeIndex);
|
||||||
|
}
|
||||||
|
mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<Integer> VALID_RX_PREAMBLE_CODES = new HashSet<Integer>(
|
||||||
|
Arrays.asList(0, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the IEEE 802.15.4z preamble code index to use when receiving
|
||||||
|
*
|
||||||
|
* Valid values are in the ranges: [0], [16-32]
|
||||||
|
*
|
||||||
|
* @param receivePreambleCodeIndex preamble code index to use for receiving
|
||||||
|
* @throws IllegalArgumentException if {@code receivePreambleCodeIndex} is invalid.
|
||||||
|
*/
|
||||||
|
public Builder setReceivePreambleCodeIndex(int receivePreambleCodeIndex) {
|
||||||
|
if (!VALID_RX_PREAMBLE_CODES.contains(receivePreambleCodeIndex)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid receive preamble: " + receivePreambleCodeIndex);
|
||||||
|
}
|
||||||
|
mReceivePreambleCodeIndex = receivePreambleCodeIndex;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the IEEE 802.15.4z PHY packet type when STS is used
|
||||||
|
*
|
||||||
|
* @param stsPhyPacketType PHY packet type when STS is used
|
||||||
|
* @throws IllegalArgumentException if {@code stsPhyPacketType} is invalid.
|
||||||
|
*/
|
||||||
|
public Builder setStsPhPacketType(@StsPhyPacketType int stsPhyPacketType) {
|
||||||
|
if (stsPhyPacketType != STS_PHY_PACKET_TYPE_SP0
|
||||||
|
&& stsPhyPacketType != STS_PHY_PACKET_TYPE_SP1
|
||||||
|
&& stsPhyPacketType != STS_PHY_PACKET_TYPE_SP2
|
||||||
|
&& stsPhyPacketType != STS_PHY_PACKET_TYPE_SP3) {
|
||||||
|
throw new IllegalArgumentException("unknown StsPhyPacketType: " + stsPhyPacketType);
|
||||||
|
}
|
||||||
|
|
||||||
|
mStsPhyPacketType = stsPhyPacketType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the specification parameters
|
||||||
|
*
|
||||||
|
* <p>Creates a copy of the parameters
|
||||||
|
*
|
||||||
|
* @param parameters specification parameters built from support library
|
||||||
|
*/
|
||||||
|
public Builder setSpecificationParameters(@NonNull PersistableBundle parameters) {
|
||||||
|
mSpecificationParameters = new PersistableBundle(parameters);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link RangingParams} object.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if required parameters are missing
|
||||||
|
*/
|
||||||
|
public RangingParams build() {
|
||||||
|
if (mSamplePeriod == null) {
|
||||||
|
throw new IllegalStateException("No sample period provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLocalDeviceAddress == null) {
|
||||||
|
throw new IllegalStateException("Local device address not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRemoteDeviceAddresses.size() == 0) {
|
||||||
|
throw new IllegalStateException("No remote device address(es) provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RangingParams(mIsInitiator, mIsController, mSamplePeriod,
|
||||||
|
mLocalDeviceAddress, mRemoteDeviceAddresses, mChannelNumber,
|
||||||
|
mTransmitPreambleCodeIndex, mReceivePreambleCodeIndex, mStsPhyPacketType,
|
||||||
|
mSpecificationParameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package android.uwb;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,6 +27,12 @@ import java.util.List;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class RangingReport {
|
public final class RangingReport {
|
||||||
|
private final List<RangingMeasurement> mRangingMeasurements;
|
||||||
|
|
||||||
|
private RangingReport(@NonNull List<RangingMeasurement> rangingMeasurements) {
|
||||||
|
mRangingMeasurements = rangingMeasurements;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a {@link List} of {@link RangingMeasurement} objects in the last measurement interval
|
* Get a {@link List} of {@link RangingMeasurement} objects in the last measurement interval
|
||||||
* <p>The underlying UWB adapter may choose to do multiple measurements in each ranging
|
* <p>The underlying UWB adapter may choose to do multiple measurements in each ranging
|
||||||
@@ -38,7 +45,57 @@ public final class RangingReport {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<RangingMeasurement> getMeasurements() {
|
public List<RangingMeasurement> getMeasurements() {
|
||||||
throw new UnsupportedOperationException();
|
return mRangingMeasurements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for {@link RangingReport} object
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
List<RangingMeasurement> mMeasurements = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single {@link RangingMeasurement}
|
||||||
|
*
|
||||||
|
* @param rangingMeasurement a ranging measurement
|
||||||
|
*/
|
||||||
|
public Builder addMeasurement(@NonNull RangingMeasurement rangingMeasurement) {
|
||||||
|
mMeasurements.add(rangingMeasurement);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link List} of {@link RangingMeasurement}s
|
||||||
|
*
|
||||||
|
* @param rangingMeasurements {@link List} of {@link RangingMeasurement}s to add
|
||||||
|
*/
|
||||||
|
public Builder addMeasurements(@NonNull List<RangingMeasurement> rangingMeasurements) {
|
||||||
|
mMeasurements.addAll(rangingMeasurements);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the {@link RangingReport} object
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if measurements are not in monotonically increasing order
|
||||||
|
*/
|
||||||
|
public RangingReport build() {
|
||||||
|
// Verify that all measurement timestamps are monotonically increasing
|
||||||
|
RangingMeasurement prevMeasurement = null;
|
||||||
|
for (int curIndex = 0; curIndex < mMeasurements.size(); curIndex++) {
|
||||||
|
RangingMeasurement curMeasurement = mMeasurements.get(curIndex);
|
||||||
|
if (prevMeasurement != null
|
||||||
|
&& (prevMeasurement.getElapsedRealtimeNanos()
|
||||||
|
> curMeasurement.getElapsedRealtimeNanos())) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Timestamp (" + curMeasurement.getElapsedRealtimeNanos()
|
||||||
|
+ ") at index " + curIndex + " is less than previous timestamp ("
|
||||||
|
+ prevMeasurement.getElapsedRealtimeNanos() + ")");
|
||||||
|
}
|
||||||
|
prevMeasurement = curMeasurement;
|
||||||
|
}
|
||||||
|
return new RangingReport(mMeasurements);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
148
core/java/android/uwb/RangingSession.java
Normal file
148
core/java/android/uwb/RangingSession.java
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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 android.uwb;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides a way to control an active UWB ranging session.
|
||||||
|
* <p>It also defines the required {@link RangingSession.Callback} that must be implemented
|
||||||
|
* in order to be notified of UWB ranging results and status events related to the
|
||||||
|
* {@link RangingSession}.
|
||||||
|
*
|
||||||
|
* <p>To get an instance of {@link RangingSession}, first use
|
||||||
|
* {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} to request to open a
|
||||||
|
* session. Once the session is opened, a {@link RangingSession} object is provided through
|
||||||
|
* {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)}. If opening a
|
||||||
|
* session fails, the failure is reported through {@link RangingSession.Callback#onClosed(int)} with
|
||||||
|
* the failure reason.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class RangingSession implements AutoCloseable {
|
||||||
|
/**
|
||||||
|
* Interface for receiving {@link RangingSession} events
|
||||||
|
*/
|
||||||
|
public interface Callback {
|
||||||
|
/**
|
||||||
|
* Invoked when {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
|
||||||
|
* is successful
|
||||||
|
*
|
||||||
|
* @param session the newly opened {@link RangingSession}
|
||||||
|
* @param sessionInfo session specific parameters from lower layers
|
||||||
|
*/
|
||||||
|
void onOpenSuccess(RangingSession session, PersistableBundle sessionInfo);
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef(value = {
|
||||||
|
CLOSE_REASON_UNKNOWN,
|
||||||
|
CLOSE_REASON_LOCAL_CLOSE_API,
|
||||||
|
CLOSE_REASON_LOCAL_BAD_PARAMETERS,
|
||||||
|
CLOSE_REASON_LOCAL_GENERIC_ERROR,
|
||||||
|
CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED,
|
||||||
|
CLOSE_REASON_LOCAL_SYSTEM_POLICY,
|
||||||
|
CLOSE_REASON_REMOTE_GENERIC_ERROR,
|
||||||
|
CLOSE_REASON_REMOTE_REQUEST})
|
||||||
|
@interface CloseReason {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed or failed to open due to an unknown reason
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_UNKNOWN = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed or failed to open because
|
||||||
|
* {@link AutoCloseable#close()} or {@link RangingSession#close()} was called
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_LOCAL_CLOSE_API = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session failed to open due to erroneous parameters passed
|
||||||
|
* to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_LOCAL_BAD_PARAMETERS = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed due to some local error on this device besides the
|
||||||
|
* error code already listed
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_LOCAL_GENERIC_ERROR = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session failed to open because the number of currently open sessions
|
||||||
|
* is equal to {@link UwbManager#getMaxSimultaneousSessions()}
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_LOCAL_MAX_SESSIONS_REACHED = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed or failed to open due to local system policy, such
|
||||||
|
* as privacy policy, power management policy, permissions, and more.
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_LOCAL_SYSTEM_POLICY = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed or failed to open due to an error with the remote
|
||||||
|
* device besides error codes already listed.
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_REMOTE_GENERIC_ERROR = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the session was closed or failed to open due to an explicit request from
|
||||||
|
* the remote device.
|
||||||
|
*/
|
||||||
|
int CLOSE_REASON_REMOTE_REQUEST = 7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when session is either closed spontaneously, or per user request via
|
||||||
|
* {@link RangingSession#close()} or {@link AutoCloseable#close()}, or when session failed
|
||||||
|
* to open.
|
||||||
|
*
|
||||||
|
* @param reason reason for the session closure
|
||||||
|
*/
|
||||||
|
void onClosed(@CloseReason int reason);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once per ranging interval even when a ranging measurement fails
|
||||||
|
*
|
||||||
|
* @param rangingReport ranging report for this interval's measurements
|
||||||
|
*/
|
||||||
|
void onReportReceived(RangingReport rangingReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the ranging session
|
||||||
|
* <p>If this session is currently open, it will close and stop the session.
|
||||||
|
* <p>If the session is in the process of being opened, it will attempt to stop the session from
|
||||||
|
* being opened.
|
||||||
|
* <p>If the session is already closed, the registered {@link Callback#onClosed(int)} callback
|
||||||
|
* will still be invoked.
|
||||||
|
*
|
||||||
|
* <p>{@link Callback#onClosed(int)} will be invoked using the same callback
|
||||||
|
* object given to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} when
|
||||||
|
* the {@link RangingSession} was opened. The callback will be invoked after each call to
|
||||||
|
* {@link #close()}, even if the {@link RangingSession} is already closed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -266,4 +266,33 @@ public final class UwbManager {
|
|||||||
public int getMaxRemoteDevicesPerResponderSession() {
|
public int getMaxRemoteDevicesPerResponderSession() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a {@link RangingSession} with the given parameters
|
||||||
|
* <p>This function is asynchronous and will return before ranging begins. The
|
||||||
|
* {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)} function is
|
||||||
|
* called with a {@link RangingSession} object used to control ranging when the session is
|
||||||
|
* successfully opened.
|
||||||
|
*
|
||||||
|
* <p>If a session cannot be opened, then {@link RangingSession.Callback#onClosed(int)} will be
|
||||||
|
* invoked with the appropriate {@link RangingSession.Callback.CloseReason}.
|
||||||
|
*
|
||||||
|
* <p>An open {@link RangingSession} will be automatically closed if client application process
|
||||||
|
* dies.
|
||||||
|
*
|
||||||
|
* @param params {@link RangingParams} used to initialize this {@link RangingSession}
|
||||||
|
* @param executor {@link Executor} to run callbacks
|
||||||
|
* @param callbacks {@link RangingSession.Callback} to associate with the
|
||||||
|
* {@link RangingSession} that is being opened.
|
||||||
|
*
|
||||||
|
* @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
|
||||||
|
* {@link RangingSession} that has been requested through {@link #openRangingSession}
|
||||||
|
* but has not yet been made available by
|
||||||
|
* {@link RangingSession.Callback#onOpenSuccess}.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public AutoCloseable openRangingSession(@NonNull RangingParams params,
|
||||||
|
@NonNull Executor executor, @NonNull RangingSession.Callback callbacks) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user