[remoteauth] Add RangingManager interfaces
* Initial commit to define interfaces and data structures for the
ranging manager.
Test: atest RemoteAuthUnitTests
Bug: 290675597, 292549287
Change-Id: Ic9fbf2f909249586f13f8d7be3069ba8ad3bd779
diff --git a/remoteauth/service/Android.bp b/remoteauth/service/Android.bp
index 737fa32..3486d8c 100644
--- a/remoteauth/service/Android.bp
+++ b/remoteauth/service/Android.bp
@@ -39,6 +39,7 @@
"framework-statsd",
],
static_libs: [
+ "guava",
"libprotobuf-java-lite",
"fast-pair-lite-protos",
"modules-utils-build",
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingCapabilities.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingCapabilities.java
index d61ca37..2b5efff 100644
--- a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingCapabilities.java
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingCapabilities.java
@@ -17,10 +17,18 @@
import androidx.annotation.IntDef;
+import com.google.common.collect.ImmutableList;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
/** The ranging capabilities of the device. */
public class RangingCapabilities {
/** Possible ranging methods */
+ @Retention(RetentionPolicy.SOURCE)
@IntDef(
value = {
RANGING_METHOD_UNKNOWN,
@@ -33,4 +41,35 @@
/** Ultra-wideband ranging. */
public static final int RANGING_METHOD_UWB = 0x1;
+
+ private final ImmutableList<Integer> mSupportedRangingMethods;
+
+ /**
+ * Gets the list of supported ranging methods of the device.
+ *
+ * @return list of {@link RangingMethod}
+ */
+ public ImmutableList<Integer> getSupportedRangingMethods() {
+ return mSupportedRangingMethods;
+ }
+
+ private RangingCapabilities(List<Integer> supportedRangingMethods) {
+ mSupportedRangingMethods = ImmutableList.copyOf(supportedRangingMethods);
+ }
+
+ /** Builder class for {@link RangingCapabilities}. */
+ public static final class Builder {
+ private List<Integer> mSupportedRangingMethods = new ArrayList<>();
+
+ /** Adds a supported {@link RangingMethod} */
+ public Builder addSupportedRangingMethods(@RangingMethod int rangingMethod) {
+ mSupportedRangingMethods.add(rangingMethod);
+ return this;
+ }
+
+ /** Builds {@link RangingCapabilities}. */
+ public RangingCapabilities build() {
+ return new RangingCapabilities(mSupportedRangingMethods);
+ }
+ }
}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java
new file mode 100644
index 0000000..989b5ed
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.ranging;
+
+import android.content.Context;
+
+/**
+ * Manages the creation of generic device to device ranging session and obtaining device's ranging
+ * capabilities.
+ *
+ * <p>Out-of-band channel for ranging capabilities/parameters exchange is assumed being handled
+ * outside of this class.
+ */
+public class RangingManager {
+
+ public RangingManager(Context context) {}
+
+ /**
+ * Gets the {@link RangingCapabilities} of this device.
+ *
+ * @return RangingCapabilities.
+ */
+ public RangingCapabilities getRangingCapabilities() {
+ return null;
+ }
+
+ /**
+ * Creates a {@link RangingSession} based on the given {@link SessionParameters}, which shall be
+ * provided based on the rangingCapabilities of the device.
+ *
+ * @param sessionParameters parameters used to setup the session.
+ * @return the created RangingSession.
+ */
+ public RangingSession createSession(SessionParameters sessionParameters) {
+ return null;
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java
index d42ef51..9ef6bda 100644
--- a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java
@@ -19,6 +19,8 @@
import androidx.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
/**
@@ -35,6 +37,7 @@
public abstract class RangingSession {
/** Types of ranging error. */
+ @Retention(RetentionPolicy.SOURCE)
@IntDef(
value = {
RANGING_ERROR_UNKNOWN,
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/SessionParameters.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/SessionParameters.java
new file mode 100644
index 0000000..33c3203
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/SessionParameters.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.ranging;
+
+import static com.android.server.remoteauth.ranging.RangingCapabilities.RANGING_METHOD_UNKNOWN;
+
+import android.annotation.NonNull;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.remoteauth.ranging.RangingCapabilities.RangingMethod;
+
+/**
+ * The set of parameters to create a ranging session.
+ *
+ * <p>Required parameters must be provided, else {@link Builder} will throw an exception. The
+ * optional parameters only need to be provided if the functionality is necessary to the session,
+ * see the setter functions of the {@link Builder} for detailed info of each parameter.
+ */
+public class SessionParameters {
+
+ /* Required parameters */
+ private final String mDeviceId;
+ @RangingMethod private final int mRangingMethod;
+
+ /* Optional parameters */
+ private final float mLowerProximityBoundaryM;
+ private final float mUpperProximityBoundaryM;
+ private final boolean mAutoDeriveParams;
+ private final byte[] mBaseKey;
+ private final byte[] mSyncData;
+
+ public String getDeviceId() {
+ return mDeviceId;
+ }
+
+ @RangingMethod
+ public int getRangingMethod() {
+ return mRangingMethod;
+ }
+
+ public float getLowerProximityBoundaryM() {
+ return mLowerProximityBoundaryM;
+ }
+
+ public float getUpperProximityBoundaryM() {
+ return mUpperProximityBoundaryM;
+ }
+
+ public boolean getAutoDeriveParams() {
+ return mAutoDeriveParams;
+ }
+
+ public byte[] getBaseKey() {
+ return mBaseKey;
+ }
+
+ public byte[] getSyncData() {
+ return mSyncData;
+ }
+
+ private SessionParameters(
+ String deviceId,
+ @RangingMethod int rangingMethod,
+ float lowerProximityBoundaryM,
+ float upperProximityBoundaryM,
+ boolean autoDeriveParams,
+ byte[] baseKey,
+ byte[] syncData) {
+ mDeviceId = deviceId;
+ mRangingMethod = rangingMethod;
+ mLowerProximityBoundaryM = lowerProximityBoundaryM;
+ mUpperProximityBoundaryM = upperProximityBoundaryM;
+ mAutoDeriveParams = autoDeriveParams;
+ mBaseKey = baseKey;
+ mSyncData = syncData;
+ }
+
+ /** Builder class for {@link SessionParameters}. */
+ public static final class Builder {
+ private String mDeviceId = new String("");
+ @RangingMethod private int mRangingMethod = RANGING_METHOD_UNKNOWN;
+ private float mLowerProximityBoundaryM;
+ private float mUpperProximityBoundaryM;
+ private boolean mAutoDeriveParams = false;
+ private byte[] mBaseKey = new byte[] {};
+ private byte[] mSyncData = new byte[] {};
+
+ /**
+ * Sets the device id.
+ *
+ * <p>This is used as the identity included in the {@link SessionInfo} for all {@link
+ * RangingCallback}s.
+ */
+ public Builder setDeviceId(@NonNull String deviceId) {
+ mDeviceId = deviceId;
+ return this;
+ }
+
+ /**
+ * Sets the {@link RangingMethod} to be used for the {@link RangingSession}.
+ *
+ * <p>Note: The ranging method should be ones in the list return by {@link
+ * RangingCapabilities#getSupportedRangingMethods};
+ */
+ public Builder setRangingMethod(@RangingMethod int rangingMethod) {
+ mRangingMethod = rangingMethod;
+ return this;
+ }
+
+ /**
+ * Sets the lower proximity boundary in meters, must be greater than or equals to zero.
+ *
+ * <p>This value is used to compute the {@link ProximityState} = {@link
+ * PROXIMITY_STATE_INSIDE} if lowerProximityBoundaryM <= proximity <=
+ * upperProximityBoundaryM, else {@link PROXIMITY_STATE_OUTSIDE}.
+ */
+ public Builder setLowerProximityBoundaryM(float lowerProximityBoundaryM) {
+ mLowerProximityBoundaryM = lowerProximityBoundaryM;
+ return this;
+ }
+
+ /**
+ * Sets the upper proximity boundary in meters, must be greater than or equals to
+ * lowerProximityBoundaryM.
+ *
+ * <p>This value is used to compute the {@link ProximityState} = {@link
+ * PROXIMITY_STATE_INSIDE} if lowerProximityBoundaryM <= proximity <=
+ * upperProximityBoundaryM, else {@link PROXIMITY_STATE_OUTSIDE}.
+ */
+ public Builder setUpperProximityBoundaryM(float upperProximityBoundaryM) {
+ mUpperProximityBoundaryM = upperProximityBoundaryM;
+ return this;
+ }
+
+ /**
+ * Sets the auto derive ranging parameters flag. Defaults to false.
+ *
+ * <p>This enables the {@link RangingSession} to automatically derive all possible {@link
+ * RangingParameters} at each {@link RangingSession#start} using the provided {@link
+ * #setBaseKey} and {@link #setSyncData}, which shall be securely shared between the ranging
+ * devices out of band.
+ */
+ public Builder setAutoDeriveParams(boolean autoDeriveParams) {
+ mAutoDeriveParams = autoDeriveParams;
+ return this;
+ }
+
+ /**
+ * Sets the base key. Only required if {@link #setAutoDeriveParams} is set to true.
+ *
+ * @param baseKey baseKey must be 16 or 32 bytes.
+ * @throws NullPointerException if baseKey is null
+ */
+ public Builder setBaseKey(@NonNull byte[] baseKey) {
+ Preconditions.checkNotNull(baseKey);
+ mBaseKey = baseKey;
+ return this;
+ }
+
+ /**
+ * Sets the sync data. Only required if {@link #setAutoDeriveParams} is set to true.
+ *
+ * @param syncData syncData must be 16 bytes.
+ * @throws NullPointerException if syncData is null
+ */
+ public Builder setSyncData(@NonNull byte[] syncData) {
+ Preconditions.checkNotNull(syncData);
+ mSyncData = syncData;
+ return this;
+ }
+
+ /**
+ * Builds {@link SessionParameters}.
+ *
+ * @throws IllegalArgumentException if any parameter is invalid.
+ */
+ public SessionParameters build() {
+ Preconditions.checkArgument(!mDeviceId.isEmpty(), "deviceId must not be empty.");
+ Preconditions.checkArgument(
+ mRangingMethod != RANGING_METHOD_UNKNOWN, "Unknown rangingMethod");
+ Preconditions.checkArgument(
+ mLowerProximityBoundaryM >= 0,
+ "Negative lowerProximityBoundaryM: " + mLowerProximityBoundaryM);
+ Preconditions.checkArgument(
+ mLowerProximityBoundaryM <= mUpperProximityBoundaryM,
+ "lowerProximityBoundaryM is greater than upperProximityBoundaryM: "
+ + mLowerProximityBoundaryM
+ + " > "
+ + mUpperProximityBoundaryM);
+ // If mAutoDeriveParams is false, mBaseKey and mSyncData will not be used.
+ if (mAutoDeriveParams) {
+ Preconditions.checkArgument(
+ mBaseKey.length == 16 || mBaseKey.length == 32,
+ "Invalid baseKey length: " + mBaseKey.length);
+ Preconditions.checkArgument(
+ mSyncData.length == 16, "Invalid syncData length: " + mSyncData.length);
+ }
+
+ return new SessionParameters(
+ mDeviceId,
+ mRangingMethod,
+ mLowerProximityBoundaryM,
+ mUpperProximityBoundaryM,
+ mAutoDeriveParams,
+ mBaseKey,
+ mSyncData);
+ }
+ }
+}