[remoteauth] Implement RangingManager
* Add basic functionalities to RangingManager and related data classes. Test: atest RemoteAuthUnitTests Bug: 292549287, 290675814 Change-Id: I2ebd5c7afbfc04499ef8e8f830e4a44b52332d69
This commit is contained in:
parent
bf6f5b576d
commit
be08f54a25
7 changed files with 282 additions and 6 deletions
|
|
@ -47,6 +47,7 @@ java_library {
|
|||
"modules-utils-preconditions",
|
||||
"modules-utils-backgroundthread",
|
||||
"presence-lite-protos",
|
||||
"uwb_androidx_backend",
|
||||
],
|
||||
sdk_version: "system_server_current",
|
||||
// This is included in service-connectivity which is 30+
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package com.android.server.remoteauth.ranging;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
|
@ -43,6 +46,8 @@ public class RangingCapabilities {
|
|||
public static final int RANGING_METHOD_UWB = 0x1;
|
||||
|
||||
private final ImmutableList<Integer> mSupportedRangingMethods;
|
||||
private final androidx.core.uwb.backend.impl.internal.RangingCapabilities
|
||||
mUwbRangingCapabilities;
|
||||
|
||||
/**
|
||||
* Gets the list of supported ranging methods of the device.
|
||||
|
|
@ -53,13 +58,28 @@ public class RangingCapabilities {
|
|||
return mSupportedRangingMethods;
|
||||
}
|
||||
|
||||
private RangingCapabilities(List<Integer> supportedRangingMethods) {
|
||||
/**
|
||||
* Gets the UWB ranging capabilities of the device.
|
||||
*
|
||||
* @return UWB ranging capabilities, null if UWB is not a supported {@link RangingMethod} in
|
||||
* {@link #getSupportedRangingMethods}.
|
||||
*/
|
||||
@Nullable
|
||||
public androidx.core.uwb.backend.impl.internal.RangingCapabilities getUwbRangingCapabilities() {
|
||||
return mUwbRangingCapabilities;
|
||||
}
|
||||
|
||||
private RangingCapabilities(
|
||||
List<Integer> supportedRangingMethods,
|
||||
androidx.core.uwb.backend.impl.internal.RangingCapabilities uwbRangingCapabilities) {
|
||||
mSupportedRangingMethods = ImmutableList.copyOf(supportedRangingMethods);
|
||||
mUwbRangingCapabilities = uwbRangingCapabilities;
|
||||
}
|
||||
|
||||
/** Builder class for {@link RangingCapabilities}. */
|
||||
public static final class Builder {
|
||||
private List<Integer> mSupportedRangingMethods = new ArrayList<>();
|
||||
private androidx.core.uwb.backend.impl.internal.RangingCapabilities mUwbRangingCapabilities;
|
||||
|
||||
/** Adds a supported {@link RangingMethod} */
|
||||
public Builder addSupportedRangingMethods(@RangingMethod int rangingMethod) {
|
||||
|
|
@ -67,9 +87,18 @@ public class RangingCapabilities {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Sets the uwb ranging capabilities. */
|
||||
public Builder setUwbRangingCapabilities(
|
||||
@NonNull
|
||||
androidx.core.uwb.backend.impl.internal.RangingCapabilities
|
||||
uwbRangingCapabilities) {
|
||||
mUwbRangingCapabilities = uwbRangingCapabilities;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds {@link RangingCapabilities}. */
|
||||
public RangingCapabilities build() {
|
||||
return new RangingCapabilities(mSupportedRangingMethods);
|
||||
return new RangingCapabilities(mSupportedRangingMethods, mUwbRangingCapabilities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,18 @@
|
|||
*/
|
||||
package com.android.server.remoteauth.ranging;
|
||||
|
||||
import static android.content.pm.PackageManager.FEATURE_UWB;
|
||||
|
||||
import static com.android.server.remoteauth.ranging.RangingCapabilities.RANGING_METHOD_UWB;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.uwb.backend.impl.internal.UwbFeatureFlags;
|
||||
import androidx.core.uwb.backend.impl.internal.UwbServiceImpl;
|
||||
|
||||
/**
|
||||
* Manages the creation of generic device to device ranging session and obtaining device's ranging
|
||||
|
|
@ -25,16 +36,46 @@ import android.content.Context;
|
|||
* outside of this class.
|
||||
*/
|
||||
public class RangingManager {
|
||||
private static final String TAG = "RangingManager";
|
||||
|
||||
public RangingManager(Context context) {}
|
||||
private Context mContext;
|
||||
@NonNull private RangingCapabilities mCachedRangingCapabilities;
|
||||
@NonNull private UwbServiceImpl mUwbServiceImpl;
|
||||
|
||||
public RangingManager(@NonNull Context context) {
|
||||
mContext = context;
|
||||
if (mContext.getPackageManager().hasSystemFeature(FEATURE_UWB)) {
|
||||
initiateUwb();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown and stop all listeners and tasks. After shutdown, RangingManager shall not be used
|
||||
* anymore.
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (mUwbServiceImpl != null) {
|
||||
mUwbServiceImpl.shutdown();
|
||||
}
|
||||
Log.i(TAG, "shutdown");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link RangingCapabilities} of this device.
|
||||
*
|
||||
* @return RangingCapabilities.
|
||||
*/
|
||||
@NonNull
|
||||
public RangingCapabilities getRangingCapabilities() {
|
||||
return null;
|
||||
if (mCachedRangingCapabilities == null) {
|
||||
RangingCapabilities.Builder builder = new RangingCapabilities.Builder();
|
||||
if (mUwbServiceImpl != null) {
|
||||
builder.addSupportedRangingMethods(RANGING_METHOD_UWB);
|
||||
builder.setUwbRangingCapabilities(mUwbServiceImpl.getRangingCapabilities());
|
||||
}
|
||||
mCachedRangingCapabilities = builder.build();
|
||||
}
|
||||
return mCachedRangingCapabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,9 +83,23 @@ public class RangingManager {
|
|||
* provided based on the rangingCapabilities of the device.
|
||||
*
|
||||
* @param sessionParameters parameters used to setup the session.
|
||||
* @return the created RangingSession.
|
||||
* @return the created RangingSession. Null if session creation failed.
|
||||
*/
|
||||
public RangingSession createSession(SessionParameters sessionParameters) {
|
||||
@Nullable
|
||||
public RangingSession createSession(@NonNull SessionParameters sessionParameters) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Initiation required for ranging with UWB. */
|
||||
private void initiateUwb() {
|
||||
UwbFeatureFlags uwbFeatureFlags =
|
||||
new UwbFeatureFlags.Builder()
|
||||
.setSkipRangingCapabilitiesCheck(
|
||||
Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
|
||||
.setReversedByteOrderFiraParams(
|
||||
Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU)
|
||||
.build();
|
||||
mUwbServiceImpl = new UwbServiceImpl(mContext, uwbFeatureFlags);
|
||||
Log.i(TAG, "RangingManager initiateUwb complete");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,16 @@ public class SessionInfo {
|
|||
mRangingMethod = rangingMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SessionInfo { "
|
||||
+ "DeviceId = "
|
||||
+ mDeviceId
|
||||
+ "RangingMethod = "
|
||||
+ mRangingMethod
|
||||
+ " }";
|
||||
}
|
||||
|
||||
/** Builder class for {@link SessionInfo}. */
|
||||
public static final class Builder {
|
||||
private String mDeviceId = "";
|
||||
|
|
|
|||
|
|
@ -35,13 +35,20 @@ android_test {
|
|||
static_libs: [
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.rules",
|
||||
"com.uwb.support.generic",
|
||||
"framework-remoteauth-static",
|
||||
"junit",
|
||||
"libprotobuf-java-lite",
|
||||
"mockito-target-extended-minus-junit4",
|
||||
"platform-test-annotations",
|
||||
"service-remoteauth-pre-jarjar",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
// these are needed for Extended Mockito
|
||||
jni_libs: [
|
||||
"libdexmakerjvmtiagent",
|
||||
"libstaticjvmtiagent",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"mts-tethering",
|
||||
|
|
|
|||
|
|
@ -28,16 +28,25 @@ import org.junit.runner.RunWith;
|
|||
/** Unit test for {@link RangingCapabilities}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RangingCapabilitiesTest {
|
||||
private static final androidx.core.uwb.backend.impl.internal.RangingCapabilities
|
||||
TEST_UWB_RANGING_CAPABILITIES =
|
||||
new androidx.core.uwb.backend.impl.internal.RangingCapabilities(
|
||||
/* supportsDistance= */ true,
|
||||
/* supportsAzimuthalAngle= */ true,
|
||||
/* supportsElevationAngle= */ true);
|
||||
|
||||
@Test
|
||||
public void testBuildingRangingCapabilities_success() {
|
||||
final RangingCapabilities rangingCapabilities =
|
||||
new RangingCapabilities.Builder()
|
||||
.addSupportedRangingMethods(RANGING_METHOD_UWB)
|
||||
.setUwbRangingCapabilities(TEST_UWB_RANGING_CAPABILITIES)
|
||||
.build();
|
||||
|
||||
assertEquals(rangingCapabilities.getSupportedRangingMethods().size(), 1);
|
||||
assertEquals(
|
||||
(int) rangingCapabilities.getSupportedRangingMethods().get(0), RANGING_METHOD_UWB);
|
||||
assertEquals(
|
||||
rangingCapabilities.getUwbRangingCapabilities(), TEST_UWB_RANGING_CAPABILITIES);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* 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 android.content.pm.PackageManager.FEATURE_UWB;
|
||||
import static android.uwb.UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE;
|
||||
|
||||
import static androidx.core.uwb.backend.impl.internal.RangingCapabilities.FIRA_DEFAULT_SUPPORTED_CONFIG_IDS;
|
||||
import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR;
|
||||
import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_MULTICAST_DS_TWR;
|
||||
import static androidx.core.uwb.backend.impl.internal.Utils.CONFIG_PROVISIONED_UNICAST_DS_TWR;
|
||||
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 org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.uwb.UwbManager;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.google.uwb.support.fira.FiraParams;
|
||||
import com.google.uwb.support.fira.FiraSpecificationParams;
|
||||
import com.google.uwb.support.generic.GenericSpecificationParams;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/** Unit test for {@link RangingManager}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RangingManagerTest {
|
||||
private static final List<Integer> TEST_UWB_SUPPORTED_CHANNELS = List.of(8, 9);
|
||||
private static final FiraSpecificationParams TEST_FIRA_SPEC =
|
||||
new FiraSpecificationParams.Builder()
|
||||
.setSupportedChannels(TEST_UWB_SUPPORTED_CHANNELS)
|
||||
.setStsCapabilities(EnumSet.allOf(FiraParams.StsCapabilityFlag.class))
|
||||
.build();
|
||||
private static final GenericSpecificationParams TEST_GENERIC_SPEC =
|
||||
new GenericSpecificationParams.Builder()
|
||||
.setFiraSpecificationParams(TEST_FIRA_SPEC)
|
||||
.build();
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@Mock private UwbManager mUwbManager;
|
||||
|
||||
private RangingManager mRangingManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mContext.getSystemService(UwbManager.class)).thenReturn(mUwbManager);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(false);
|
||||
when(mUwbManager.getAdapterState()).thenReturn(STATE_ENABLED_INACTIVE);
|
||||
when(mUwbManager.getSpecificationInfo()).thenReturn(TEST_GENERIC_SPEC.toBundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstruction() {
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
verifyZeroInteractions(mUwbManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstruction_withUwbEnabled() {
|
||||
when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(true);
|
||||
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
|
||||
verify(mUwbManager).getAdapterState();
|
||||
verify(mUwbManager).registerAdapterStateCallback(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShutdown_withUwbEnabled() {
|
||||
when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(true);
|
||||
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
mRangingManager.shutdown();
|
||||
|
||||
verify(mUwbManager).registerAdapterStateCallback(any(), any());
|
||||
verify(mUwbManager).unregisterAdapterStateCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRangingCapabilities() {
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
RangingCapabilities capabilities = mRangingManager.getRangingCapabilities();
|
||||
|
||||
assertEquals(capabilities.getSupportedRangingMethods().size(), 0);
|
||||
assertEquals(capabilities.getUwbRangingCapabilities(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRangingCapabilities_withUwbEnabled() {
|
||||
when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(true);
|
||||
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
RangingCapabilities capabilities = mRangingManager.getRangingCapabilities();
|
||||
|
||||
List<Integer> supportedConfigIds = new ArrayList<>(FIRA_DEFAULT_SUPPORTED_CONFIG_IDS);
|
||||
supportedConfigIds.add(CONFIG_PROVISIONED_UNICAST_DS_TWR);
|
||||
supportedConfigIds.add(CONFIG_PROVISIONED_MULTICAST_DS_TWR);
|
||||
supportedConfigIds.add(CONFIG_PROVISIONED_UNICAST_DS_TWR_NO_AOA);
|
||||
supportedConfigIds.add(CONFIG_PROVISIONED_INDIVIDUAL_MULTICAST_DS_TWR);
|
||||
|
||||
verify(mUwbManager, times(1)).getSpecificationInfo();
|
||||
assertEquals(capabilities.getSupportedRangingMethods().size(), 1);
|
||||
assertEquals((int) capabilities.getSupportedRangingMethods().get(0), RANGING_METHOD_UWB);
|
||||
androidx.core.uwb.backend.impl.internal.RangingCapabilities uwbCapabilities =
|
||||
capabilities.getUwbRangingCapabilities();
|
||||
assertNotNull(uwbCapabilities);
|
||||
assertArrayEquals(
|
||||
uwbCapabilities.getSupportedChannels().toArray(),
|
||||
TEST_UWB_SUPPORTED_CHANNELS.toArray());
|
||||
assertArrayEquals(
|
||||
uwbCapabilities.getSupportedConfigIds().toArray(), supportedConfigIds.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRangingCapabilities_multipleCalls() {
|
||||
when(mPackageManager.hasSystemFeature(FEATURE_UWB)).thenReturn(true);
|
||||
|
||||
mRangingManager = new RangingManager(mContext);
|
||||
RangingCapabilities capabilities1 = mRangingManager.getRangingCapabilities();
|
||||
RangingCapabilities capabilities2 = mRangingManager.getRangingCapabilities();
|
||||
RangingCapabilities capabilities3 = mRangingManager.getRangingCapabilities();
|
||||
|
||||
verify(mUwbManager, times(1)).getSpecificationInfo();
|
||||
assertEquals(capabilities1, capabilities2);
|
||||
assertEquals(capabilities2, capabilities3);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue