[remoteauth] Add UwbRangingSession

Test: atest RemoteAuthUnitTests
Bug: 292549287, 290675814
Change-Id: Ib5f541edc6d1ce373a58e3f602d7fe3aa1c2f3b7
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java
index 5a41aac..cf0db76 100644
--- a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingManager.java
@@ -17,6 +17,7 @@
 
 import static android.content.pm.PackageManager.FEATURE_UWB;
 
+import static com.android.server.remoteauth.ranging.RangingCapabilities.RANGING_METHOD_UNKNOWN;
 import static com.android.server.remoteauth.ranging.RangingCapabilities.RANGING_METHOD_UWB;
 
 import android.annotation.NonNull;
@@ -28,6 +29,8 @@
 import androidx.core.uwb.backend.impl.internal.UwbFeatureFlags;
 import androidx.core.uwb.backend.impl.internal.UwbServiceImpl;
 
+import com.android.internal.util.Preconditions;
+
 /**
  * Manages the creation of generic device to device ranging session and obtaining device's ranging
  * capabilities.
@@ -84,9 +87,21 @@
      *
      * @param sessionParameters parameters used to setup the session.
      * @return the created RangingSession. Null if session creation failed.
+     * @throws IllegalArgumentException if sessionParameters is invalid.
      */
     @Nullable
     public RangingSession createSession(@NonNull SessionParameters sessionParameters) {
+        Preconditions.checkNotNull(sessionParameters, "sessionParameters must not be null");
+        switch (sessionParameters.getRangingMethod()) {
+            case RANGING_METHOD_UWB:
+                if (mUwbServiceImpl == null) {
+                    Log.w(TAG, "createSession with UWB failed - UWB not supported");
+                    break;
+                }
+                return new UwbRangingSession(mContext, sessionParameters, mUwbServiceImpl);
+            case RANGING_METHOD_UNKNOWN:
+                break;
+        }
         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 4db89b3..adb36c5 100644
--- a/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/RangingSession.java
@@ -221,7 +221,7 @@
         Log.i(TAG, "resetSyncData");
     }
 
-    /** Update mDerivedData */
+    /** Recomputes mDerivedData using the latest mBaseKey, mSyncData, and mSyncCounter. */
     protected boolean updateDerivedData() {
         if (!mAutoDeriveParams) {
             Log.w(TAG, "autoDeriveParams is disabled, updateDerivedData is skipped.");
diff --git a/remoteauth/service/java/com/android/server/remoteauth/ranging/UwbRangingSession.java b/remoteauth/service/java/com/android/server/remoteauth/ranging/UwbRangingSession.java
new file mode 100644
index 0000000..2015b66
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/ranging/UwbRangingSession.java
@@ -0,0 +1,44 @@
+/*
+ * 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.annotation.NonNull;
+import android.content.Context;
+
+import androidx.core.uwb.backend.impl.internal.UwbServiceImpl;
+
+import java.util.concurrent.Executor;
+
+/** UWB (ultra wide-band) implementation of {@link RangingSession}. */
+public class UwbRangingSession extends RangingSession {
+    private static final int DERIVED_DATA_LENGTH = 1;
+
+    public UwbRangingSession(
+            @NonNull Context context,
+            @NonNull SessionParameters sessionParameters,
+            @NonNull UwbServiceImpl uwbServiceImpl) {
+        super(context, sessionParameters, DERIVED_DATA_LENGTH);
+    }
+
+    @Override
+    public void start(
+            @NonNull RangingParameters rangingParameters,
+            @NonNull Executor executor,
+            @NonNull RangingCallback rangingCallback) {}
+
+    @Override
+    public void stop() {}
+}
diff --git a/remoteauth/tests/unit/src/com/android/server/remoteauth/ranging/RangingManagerTest.java b/remoteauth/tests/unit/src/com/android/server/remoteauth/ranging/RangingManagerTest.java
index 609809f..6e343bb 100644
--- a/remoteauth/tests/unit/src/com/android/server/remoteauth/ranging/RangingManagerTest.java
+++ b/remoteauth/tests/unit/src/com/android/server/remoteauth/ranging/RangingManagerTest.java
@@ -26,10 +26,13 @@
 import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA;
 
 import static com.android.server.remoteauth.ranging.RangingCapabilities.RANGING_METHOD_UWB;
+import static com.android.server.remoteauth.ranging.SessionParameters.DEVICE_ROLE_INITIATOR;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -42,6 +45,9 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.server.remoteauth.ranging.RangingCapabilities.RangingMethod;
+import com.android.server.remoteauth.ranging.SessionParameters.DeviceRole;
+
 import com.google.uwb.support.fira.FiraParams;
 import com.google.uwb.support.fira.FiraSpecificationParams;
 import com.google.uwb.support.generic.GenericSpecificationParams;
@@ -69,6 +75,33 @@
             new GenericSpecificationParams.Builder()
                     .setFiraSpecificationParams(TEST_FIRA_SPEC)
                     .build();
+    private static final String TEST_DEVICE_ID = "test_device_id";
+    @RangingMethod private static final int TEST_RANGING_METHOD = RANGING_METHOD_UWB;
+    @DeviceRole private static final int TEST_DEVICE_ROLE = DEVICE_ROLE_INITIATOR;
+    private static final float TEST_LOWER_PROXIMITY_BOUNDARY_M = 1.0f;
+    private static final float TEST_UPPER_PROXIMITY_BOUNDARY_M = 2.5f;
+    private static final boolean TEST_AUTO_DERIVE_PARAMS = true;
+    private static final byte[] TEST_BASE_KEY =
+            new byte[] {
+                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+                0x0e, 0x0f
+            };
+    private static final byte[] TEST_SYNC_DATA =
+            new byte[] {
+                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+                0x0f, 0x00
+            };
+    private static final SessionParameters TEST_SESSION_PARAMETER =
+            new SessionParameters.Builder()
+                    .setDeviceId(TEST_DEVICE_ID)
+                    .setRangingMethod(TEST_RANGING_METHOD)
+                    .setDeviceRole(TEST_DEVICE_ROLE)
+                    .setLowerProximityBoundaryM(TEST_LOWER_PROXIMITY_BOUNDARY_M)
+                    .setUpperProximityBoundaryM(TEST_UPPER_PROXIMITY_BOUNDARY_M)
+                    .setAutoDeriveParams(TEST_AUTO_DERIVE_PARAMS)
+                    .setBaseKey(TEST_BASE_KEY)
+                    .setSyncData(TEST_SYNC_DATA)
+                    .build();
 
     @Mock private Context mContext;
     @Mock private PackageManager mPackageManager;
@@ -162,4 +195,26 @@
         assertEquals(capabilities1, capabilities2);
         assertEquals(capabilities2, capabilities3);
     }
+
+    @Test
+    public void testCreateSession_nullSessionParameters() {
+        mRangingManager = new RangingManager(mContext);
+
+        assertThrows(NullPointerException.class, () -> mRangingManager.createSession(null));
+    }
+
+    @Test
+    public void testCreateSession_uwbSessionWithUwbDisabled() {
+        mRangingManager = new RangingManager(mContext);
+
+        assertNull(mRangingManager.createSession(TEST_SESSION_PARAMETER));
+    }
+
+    @Test
+    public void testCreateSession_uwbSession() {
+        when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(true);
+        mRangingManager = new RangingManager(mContext);
+
+        assertNotNull(mRangingManager.createSession(TEST_SESSION_PARAMETER));
+    }
 }