From 6c580dd473c096b3e70acb61be15dd5833c144fd Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 29 Jul 2021 21:31:23 -0700 Subject: [PATCH] Move existing UWB API classes to UWB apex Following instructions from go/mainline-java-lib to move the existing UWB API classes to the new apex. Bug: 194906542 Test: Compiles Change-Id: I08801b418c7ba42c76952f5a80745cd0057ca329 --- Android.bp | 2 + StubLibraries.bp | 2 + api/Android.bp | 8 + boot/Android.bp | 4 + core/api/system-current.txt | 142 ----- core/java/android/uwb/AdapterState.aidl | 38 -- .../android/uwb/AdapterStateListener.java | 199 ------- core/java/android/uwb/AngleMeasurement.java | 157 ------ .../uwb/AngleOfArrivalMeasurement.java | 169 ------ .../java/android/uwb/DistanceMeasurement.java | 214 -------- core/java/android/uwb/IUwbAdapter.aidl | 191 ------- .../uwb/IUwbAdapterStateCallbacks.aidl | 33 -- .../android/uwb/IUwbRangingCallbacks.aidl | 136 ----- core/java/android/uwb/MeasurementStatus.aidl | 39 -- core/java/android/uwb/OWNERS | 6 - .../java/android/uwb/RangingChangeReason.aidl | 63 --- core/java/android/uwb/RangingManager.java | 256 --------- core/java/android/uwb/RangingMeasurement.java | 308 ----------- core/java/android/uwb/RangingReport.aidl | 19 - core/java/android/uwb/RangingReport.java | 160 ------ core/java/android/uwb/RangingSession.java | 496 ------------------ core/java/android/uwb/SessionHandle.aidl | 19 - core/java/android/uwb/SessionHandle.java | 86 --- core/java/android/uwb/StateChangeReason.aidl | 50 -- core/java/android/uwb/TEST_MAPPING | 10 - core/java/android/uwb/UwbAddress.aidl | 19 - core/java/android/uwb/UwbAddress.java | 131 ----- core/java/android/uwb/UwbManager.java | 308 ----------- core/tests/uwbtests/Android.bp | 38 -- core/tests/uwbtests/AndroidManifest.xml | 31 -- core/tests/uwbtests/AndroidTest.xml | 32 -- core/tests/uwbtests/OWNERS | 1 - .../android/uwb/AdapterStateListenerTest.java | 288 ---------- .../src/android/uwb/RangingManagerTest.java | 267 ---------- .../src/android/uwb/UwbTestUtils.java | 90 ---- 35 files changed, 16 insertions(+), 3996 deletions(-) delete mode 100644 core/java/android/uwb/AdapterState.aidl delete mode 100644 core/java/android/uwb/AdapterStateListener.java delete mode 100644 core/java/android/uwb/AngleMeasurement.java delete mode 100644 core/java/android/uwb/AngleOfArrivalMeasurement.java delete mode 100644 core/java/android/uwb/DistanceMeasurement.java delete mode 100644 core/java/android/uwb/IUwbAdapter.aidl delete mode 100644 core/java/android/uwb/IUwbAdapterStateCallbacks.aidl delete mode 100644 core/java/android/uwb/IUwbRangingCallbacks.aidl delete mode 100644 core/java/android/uwb/MeasurementStatus.aidl delete mode 100644 core/java/android/uwb/OWNERS delete mode 100644 core/java/android/uwb/RangingChangeReason.aidl delete mode 100644 core/java/android/uwb/RangingManager.java delete mode 100644 core/java/android/uwb/RangingMeasurement.java delete mode 100644 core/java/android/uwb/RangingReport.aidl delete mode 100644 core/java/android/uwb/RangingReport.java delete mode 100644 core/java/android/uwb/RangingSession.java delete mode 100644 core/java/android/uwb/SessionHandle.aidl delete mode 100644 core/java/android/uwb/SessionHandle.java delete mode 100644 core/java/android/uwb/StateChangeReason.aidl delete mode 100644 core/java/android/uwb/TEST_MAPPING delete mode 100644 core/java/android/uwb/UwbAddress.aidl delete mode 100644 core/java/android/uwb/UwbAddress.java delete mode 100644 core/java/android/uwb/UwbManager.java delete mode 100644 core/tests/uwbtests/Android.bp delete mode 100644 core/tests/uwbtests/AndroidManifest.xml delete mode 100644 core/tests/uwbtests/AndroidTest.xml delete mode 100644 core/tests/uwbtests/OWNERS delete mode 100644 core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java delete mode 100644 core/tests/uwbtests/src/android/uwb/RangingManagerTest.java delete mode 100644 core/tests/uwbtests/src/android/uwb/UwbTestUtils.java diff --git a/Android.bp b/Android.bp index 3afd6ecd5610e..c156774a1c515 100644 --- a/Android.bp +++ b/Android.bp @@ -156,6 +156,7 @@ java_library { "framework-sdkextensions.stubs.module_lib", "framework-statsd.stubs.module_lib", "framework-tethering.stubs.module_lib", + "framework-uwb.stubs.module_lib", "framework-wifi.stubs.module_lib", ], sdk_version: "module_current", @@ -178,6 +179,7 @@ java_library { "framework-sdkextensions.impl", "framework-statsd.impl", "framework-tethering.impl", + "framework-uwb.impl", "framework-wifi.impl", "updatable-media", ], diff --git a/StubLibraries.bp b/StubLibraries.bp index 44c55c26153d4..1904c1f34da01 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -250,6 +250,7 @@ modules_public_stubs = [ "framework-sdkextensions.stubs", "framework-statsd.stubs", "framework-tethering.stubs", + "framework-uwb.stubs", "framework-wifi.stubs", "i18n.module.public.api.stubs", ] @@ -269,6 +270,7 @@ modules_system_stubs = [ "framework-sdkextensions.stubs.system", "framework-statsd.stubs.system", "framework-tethering.stubs.system", + "framework-uwb.stubs.system", "framework-wifi.stubs.system", "i18n.module.public.api.stubs", // Only has public stubs ] diff --git a/api/Android.bp b/api/Android.bp index 2ea180ebf5982..66b6dbafcc853 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -90,6 +90,7 @@ genrule { ":framework-sdkextensions{.public.api.txt}", ":framework-statsd{.public.api.txt}", ":framework-tethering{.public.api.txt}", + ":framework-uwb{.public.api.txt}", ":framework-wifi{.public.api.txt}", ":i18n.module.public.api{.public.api.txt}", ":non-updatable-current.txt", @@ -149,6 +150,7 @@ genrule { ":framework-sdkextensions{.public.stubs.source}", ":framework-statsd{.public.stubs.source}", ":framework-tethering{.public.stubs.source}", + ":framework-uwb{.public.stubs.source}", ":framework-wifi{.public.stubs.source}", ":i18n.module.public.api{.public.stubs.source}", ], @@ -175,6 +177,7 @@ genrule { ":framework-sdkextensions{.public.removed-api.txt}", ":framework-statsd{.public.removed-api.txt}", ":framework-tethering{.public.removed-api.txt}", + ":framework-uwb{.public.removed-api.txt}", ":framework-wifi{.public.removed-api.txt}", ":i18n.module.public.api{.public.removed-api.txt}", ":non-updatable-removed.txt", @@ -215,6 +218,7 @@ genrule { ":framework-sdkextensions{.system.api.txt}", ":framework-statsd{.system.api.txt}", ":framework-tethering{.system.api.txt}", + ":framework-uwb{.system.api.txt}", ":framework-wifi{.system.api.txt}", ":non-updatable-system-current.txt", ], @@ -273,6 +277,7 @@ genrule { ":framework-sdkextensions{.system.removed-api.txt}", ":framework-statsd{.system.removed-api.txt}", ":framework-tethering{.system.removed-api.txt}", + ":framework-uwb{.system.removed-api.txt}", ":framework-wifi{.system.removed-api.txt}", ":non-updatable-system-removed.txt", ], @@ -313,6 +318,7 @@ genrule { ":framework-sdkextensions{.module-lib.api.txt}", ":framework-statsd{.module-lib.api.txt}", ":framework-tethering{.module-lib.api.txt}", + ":framework-uwb{.module-lib.api.txt}", ":framework-wifi{.module-lib.api.txt}", ":non-updatable-module-lib-current.txt", ], @@ -373,6 +379,7 @@ genrule { ":framework-sdkextensions{.module-lib.removed-api.txt}", ":framework-statsd{.module-lib.removed-api.txt}", ":framework-tethering{.module-lib.removed-api.txt}", + ":framework-uwb{.module-lib.removed-api.txt}", ":framework-wifi{.module-lib.removed-api.txt}", ":non-updatable-module-lib-removed.txt", ], @@ -491,6 +498,7 @@ genrule { ":framework-sdkextensions.stubs{.jar}", ":framework-statsd.stubs{.jar}", ":framework-tethering.stubs{.jar}", + ":framework-uwb.stubs{.jar}", ":framework-wifi.stubs{.jar}", ":i18n.module.public.api.stubs{.jar}", ], diff --git a/boot/Android.bp b/boot/Android.bp index b71f9bf519cbc..049c8026faa96 100644 --- a/boot/Android.bp +++ b/boot/Android.bp @@ -99,6 +99,10 @@ platform_bootclasspath { apex: "com.android.tethering", module: "com.android.tethering-bootclasspath-fragment", }, + { + apex: "com.android.uwb", + module: "com.android.uwb-bootclasspath-fragment", + }, { apex: "com.android.wifi", module: "com.android.wifi-bootclasspath-fragment", diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 2c2e8110f8794..82b032a05c095 100755 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -14267,148 +14267,6 @@ package android.util { } -package android.uwb { - - public final class AngleMeasurement implements android.os.Parcelable { - ctor public AngleMeasurement(@FloatRange(from=-3.141592653589793, to=3.141592653589793) double, @FloatRange(from=0.0, to=3.141592653589793) double, @FloatRange(from=0.0, to=1.0) double); - method public int describeContents(); - method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel(); - method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians(); - method @FloatRange(from=-3.141592653589793, to=3.141592653589793) public double getRadians(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - } - - public final class AngleOfArrivalMeasurement implements android.os.Parcelable { - method public int describeContents(); - method @Nullable public android.uwb.AngleMeasurement getAltitude(); - method @NonNull public android.uwb.AngleMeasurement getAzimuth(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - } - - public static final class AngleOfArrivalMeasurement.Builder { - ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement); - method @NonNull public android.uwb.AngleOfArrivalMeasurement build(); - method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement); - } - - public final class DistanceMeasurement implements android.os.Parcelable { - method public int describeContents(); - method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel(); - method @FloatRange(from=0.0) public double getErrorMeters(); - method public double getMeters(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - } - - public static final class DistanceMeasurement.Builder { - ctor public DistanceMeasurement.Builder(); - method @NonNull public android.uwb.DistanceMeasurement build(); - method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(@FloatRange(from=0.0, to=1.0) double); - method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(@FloatRange(from=0.0) double); - method @NonNull public android.uwb.DistanceMeasurement.Builder setMeters(double); - } - - public final class RangingMeasurement implements android.os.Parcelable { - method public int describeContents(); - method @Nullable public android.uwb.AngleOfArrivalMeasurement getAngleOfArrivalMeasurement(); - method @Nullable public android.uwb.DistanceMeasurement getDistanceMeasurement(); - method public long getElapsedRealtimeNanos(); - method @NonNull public android.uwb.UwbAddress getRemoteDeviceAddress(); - method public int getStatus(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - field public static final int RANGING_STATUS_FAILURE_OUT_OF_RANGE = 1; // 0x1 - field public static final int RANGING_STATUS_FAILURE_UNKNOWN_ERROR = -1; // 0xffffffff - field public static final int RANGING_STATUS_SUCCESS = 0; // 0x0 - } - - public static final class RangingMeasurement.Builder { - ctor public RangingMeasurement.Builder(); - method @NonNull public android.uwb.RangingMeasurement build(); - method @NonNull public android.uwb.RangingMeasurement.Builder setAngleOfArrivalMeasurement(@NonNull android.uwb.AngleOfArrivalMeasurement); - method @NonNull public android.uwb.RangingMeasurement.Builder setDistanceMeasurement(@NonNull android.uwb.DistanceMeasurement); - method @NonNull public android.uwb.RangingMeasurement.Builder setElapsedRealtimeNanos(long); - method @NonNull public android.uwb.RangingMeasurement.Builder setRemoteDeviceAddress(@NonNull android.uwb.UwbAddress); - method @NonNull public android.uwb.RangingMeasurement.Builder setStatus(int); - } - - public final class RangingReport implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public java.util.List getMeasurements(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - } - - public static final class RangingReport.Builder { - ctor public RangingReport.Builder(); - method @NonNull public android.uwb.RangingReport.Builder addMeasurement(@NonNull android.uwb.RangingMeasurement); - method @NonNull public android.uwb.RangingReport.Builder addMeasurements(@NonNull java.util.List); - method @NonNull public android.uwb.RangingReport build(); - } - - public final class RangingSession implements java.lang.AutoCloseable { - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void close(); - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void reconfigure(@NonNull android.os.PersistableBundle); - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void start(@NonNull android.os.PersistableBundle); - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void stop(); - } - - public static interface RangingSession.Callback { - method public void onClosed(int, @NonNull android.os.PersistableBundle); - method public void onOpenFailed(int, @NonNull android.os.PersistableBundle); - method public void onOpened(@NonNull android.uwb.RangingSession); - method public void onReconfigureFailed(int, @NonNull android.os.PersistableBundle); - method public void onReconfigured(@NonNull android.os.PersistableBundle); - method public void onReportReceived(@NonNull android.uwb.RangingReport); - method public void onStartFailed(int, @NonNull android.os.PersistableBundle); - method public void onStarted(@NonNull android.os.PersistableBundle); - method public void onStopFailed(int, @NonNull android.os.PersistableBundle); - method public void onStopped(int, @NonNull android.os.PersistableBundle); - field public static final int REASON_BAD_PARAMETERS = 3; // 0x3 - field public static final int REASON_GENERIC_ERROR = 4; // 0x4 - field public static final int REASON_LOCAL_REQUEST = 1; // 0x1 - field public static final int REASON_MAX_SESSIONS_REACHED = 5; // 0x5 - field public static final int REASON_PROTOCOL_SPECIFIC_ERROR = 7; // 0x7 - field public static final int REASON_REMOTE_REQUEST = 2; // 0x2 - field public static final int REASON_SYSTEM_POLICY = 6; // 0x6 - field public static final int REASON_UNKNOWN = 0; // 0x0 - } - - public final class UwbAddress implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public static android.uwb.UwbAddress fromBytes(@NonNull byte[]); - method public int size(); - method @NonNull public byte[] toBytes(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - field public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8; // 0x8 - field public static final int SHORT_ADDRESS_BYTE_LENGTH = 2; // 0x2 - } - - public final class UwbManager { - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos(); - method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo(); - method @NonNull @RequiresPermission(allOf={android.Manifest.permission.UWB_PRIVILEGED, android.Manifest.permission.UWB_RANGING}) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback); - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback); - method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback); - } - - public static interface UwbManager.AdapterStateCallback { - method public void onStateChanged(int, int); - field public static final int STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED = 1; // 0x1 - field public static final int STATE_CHANGED_REASON_ERROR_UNKNOWN = 4; // 0x4 - field public static final int STATE_CHANGED_REASON_SESSION_STARTED = 0; // 0x0 - field public static final int STATE_CHANGED_REASON_SYSTEM_BOOT = 3; // 0x3 - field public static final int STATE_CHANGED_REASON_SYSTEM_POLICY = 2; // 0x2 - field public static final int STATE_DISABLED = 0; // 0x0 - field public static final int STATE_ENABLED_ACTIVE = 2; // 0x2 - field public static final int STATE_ENABLED_INACTIVE = 1; // 0x1 - } - -} - package android.view { public abstract class Window { diff --git a/core/java/android/uwb/AdapterState.aidl b/core/java/android/uwb/AdapterState.aidl deleted file mode 100644 index 991f64a0c0aea..0000000000000 --- a/core/java/android/uwb/AdapterState.aidl +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2021 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; - -/** - * @hide - */ -@Backing(type="int") -enum AdapterState { - /** - * The state when UWB is disabled. - */ - STATE_DISABLED, - - /** - * The state when UWB is enabled but has no active sessions. - */ - STATE_ENABLED_INACTIVE, - - /** - * The state when UWB is enabled and has active sessions. - */ - STATE_ENABLED_ACTIVE, -} \ No newline at end of file diff --git a/core/java/android/uwb/AdapterStateListener.java b/core/java/android/uwb/AdapterStateListener.java deleted file mode 100644 index 7e82cc6318f7b..0000000000000 --- a/core/java/android/uwb/AdapterStateListener.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.NonNull; -import android.os.Binder; -import android.os.RemoteException; -import android.util.Log; -import android.uwb.UwbManager.AdapterStateCallback; -import android.uwb.UwbManager.AdapterStateCallback.State; -import android.uwb.UwbManager.AdapterStateCallback.StateChangedReason; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executor; - -/** - * @hide - */ -public class AdapterStateListener extends IUwbAdapterStateCallbacks.Stub { - private static final String TAG = "Uwb.StateListener"; - - private final IUwbAdapter mAdapter; - private boolean mIsRegistered = false; - - private final Map mCallbackMap = new HashMap<>(); - - @StateChangedReason - private int mAdapterStateChangeReason = AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN; - @State - private int mAdapterState = AdapterStateCallback.STATE_DISABLED; - - public AdapterStateListener(@NonNull IUwbAdapter adapter) { - mAdapter = adapter; - } - - /** - * Register an {@link AdapterStateCallback} with this {@link AdapterStateListener} - * - * @param executor an {@link Executor} to execute given callback - * @param callback user implementation of the {@link AdapterStateCallback} - */ - public void register(@NonNull Executor executor, @NonNull AdapterStateCallback callback) { - synchronized (this) { - if (mCallbackMap.containsKey(callback)) { - return; - } - - mCallbackMap.put(callback, executor); - - if (!mIsRegistered) { - try { - mAdapter.registerAdapterStateCallbacks(this); - mIsRegistered = true; - } catch (RemoteException e) { - Log.w(TAG, "Failed to register adapter state callback"); - throw e.rethrowFromSystemServer(); - } - } else { - sendCurrentState(callback); - } - } - } - - /** - * Unregister the specified {@link AdapterStateCallback} - * - * @param callback user implementation of the {@link AdapterStateCallback} - */ - public void unregister(@NonNull AdapterStateCallback callback) { - synchronized (this) { - if (!mCallbackMap.containsKey(callback)) { - return; - } - - mCallbackMap.remove(callback); - - if (mCallbackMap.isEmpty() && mIsRegistered) { - try { - mAdapter.unregisterAdapterStateCallbacks(this); - } catch (RemoteException e) { - Log.w(TAG, "Failed to unregister AdapterStateCallback with service"); - throw e.rethrowFromSystemServer(); - } - mIsRegistered = false; - } - } - } - - /** - * Sets the adapter enabled state - * - * @param isEnabled value of new adapter state - */ - public void setEnabled(boolean isEnabled) { - synchronized (this) { - try { - mAdapter.setEnabled(isEnabled); - } catch (RemoteException e) { - Log.w(TAG, "Failed to set adapter state"); - throw e.rethrowFromSystemServer(); - } - - } - } - - /** - * Gets the adapter enabled state - * - * @return integer representing adapter enabled state - */ - public int getAdapterState() { - synchronized (this) { - try { - return mAdapter.getAdapterState(); - } catch (RemoteException e) { - Log.w(TAG, "Failed to get adapter state"); - throw e.rethrowFromSystemServer(); - } - } - } - - private void sendCurrentState(@NonNull AdapterStateCallback callback) { - synchronized (this) { - Executor executor = mCallbackMap.get(callback); - - final long identity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> callback.onStateChanged( - mAdapterState, mAdapterStateChangeReason)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - } - - @Override - public void onAdapterStateChanged(int state, int reason) { - synchronized (this) { - @StateChangedReason int localReason = - convertToStateChangedReason(reason); - @State int localState = convertToState(state); - mAdapterStateChangeReason = localReason; - mAdapterState = localState; - for (AdapterStateCallback cb : mCallbackMap.keySet()) { - sendCurrentState(cb); - } - } - } - - private static @StateChangedReason int convertToStateChangedReason( - @StateChangeReason int reason) { - switch (reason) { - case StateChangeReason.ALL_SESSIONS_CLOSED: - return AdapterStateCallback.STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED; - - case StateChangeReason.SESSION_STARTED: - return AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED; - - case StateChangeReason.SYSTEM_POLICY: - return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY; - - case StateChangeReason.SYSTEM_BOOT: - return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT; - - case StateChangeReason.UNKNOWN: - default: - return AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN; - } - } - - private static @State int convertToState(@AdapterState int state) { - switch (state) { - case AdapterState.STATE_ENABLED_INACTIVE: - return AdapterStateCallback.STATE_ENABLED_INACTIVE; - - case AdapterState.STATE_ENABLED_ACTIVE: - return AdapterStateCallback.STATE_ENABLED_ACTIVE; - - case AdapterState.STATE_DISABLED: - default: - return AdapterStateCallback.STATE_DISABLED; - } - } -} diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java deleted file mode 100644 index 3d603737c48c5..0000000000000 --- a/core/java/android/uwb/AngleMeasurement.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * 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.FloatRange; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Angle measurement - * - *

The actual angle is interpreted as: - * {@link #getRadians()} +/- {@link #getErrorRadians()} ()} at {@link #getConfidenceLevel()} - * - * @hide - */ -@SystemApi -public final class AngleMeasurement implements Parcelable { - private final double mRadians; - private final double mErrorRadians; - private final double mConfidenceLevel; - - /** - * Constructs a new {@link AngleMeasurement} object - * - * @param radians the angle in radians - * @param errorRadians the error of the angle measurement in radians - * @param confidenceLevel confidence level of the angle measurement - * - * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of - * allowed range - */ - public AngleMeasurement( - @FloatRange(from = -Math.PI, to = +Math.PI) double radians, - @FloatRange(from = 0.0, to = +Math.PI) double errorRadians, - @FloatRange(from = 0.0, to = 1.0) double confidenceLevel) { - if (radians < -Math.PI || radians > Math.PI) { - throw new IllegalArgumentException("Invalid radians: " + radians); - } - mRadians = radians; - - if (errorRadians < 0.0 || errorRadians > Math.PI) { - throw new IllegalArgumentException("Invalid error radians: " + errorRadians); - } - mErrorRadians = errorRadians; - - if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { - throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel); - } - mConfidenceLevel = confidenceLevel; - } - - /** - * Angle measurement in radians - * - * @return angle in radians - */ - @FloatRange(from = -Math.PI, to = +Math.PI) - public double getRadians() { - return mRadians; - } - - /** - * Error of angle measurement in radians - * - *

Must be a positive value - * - * @return angle measurement error in radians - */ - @FloatRange(from = 0.0, to = +Math.PI) - public double getErrorRadians() { - return mErrorRadians; - } - - /** - * Angle measurement confidence level expressed as a value between - * 0.0 to 1.0. - * - *

A value of 0.0 indicates there is no confidence in the measurement. A value of 1.0 - * indicates there is maximum confidence in the measurement. - * - * @return the confidence level of the angle measurement - */ - @FloatRange(from = 0.0, to = 1.0) - public double getConfidenceLevel() { - return mConfidenceLevel; - } - - /** - * @hide - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof AngleMeasurement) { - AngleMeasurement other = (AngleMeasurement) obj; - return mRadians == other.getRadians() - && mErrorRadians == other.getErrorRadians() - && mConfidenceLevel == other.getConfidenceLevel(); - } - return false; - } - - /** - * @hide - */ - @Override - public int hashCode() { - return Objects.hash(mRadians, mErrorRadians, mConfidenceLevel); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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) { - return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble()); - } - - @Override - public AngleMeasurement[] newArray(int size) { - return new AngleMeasurement[size]; - } - }; -} diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java deleted file mode 100644 index db04ad16c1918..0000000000000 --- a/core/java/android/uwb/AngleOfArrivalMeasurement.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Represents an angle of arrival measurement between two devices using Ultra Wideband - * - * @hide - */ -@SystemApi -public final class AngleOfArrivalMeasurement implements Parcelable { - private final AngleMeasurement mAzimuthAngleMeasurement; - private final AngleMeasurement mAltitudeAngleMeasurement; - - private AngleOfArrivalMeasurement(@NonNull AngleMeasurement azimuthAngleMeasurement, - @Nullable AngleMeasurement altitudeAngleMeasurement) { - mAzimuthAngleMeasurement = azimuthAngleMeasurement; - mAltitudeAngleMeasurement = altitudeAngleMeasurement; - } - - /** - * Azimuth angle measurement - *

Azimuth {@link AngleMeasurement} of remote device in horizontal coordinate system, this is - * the angle clockwise from the meridian when viewing above the north pole. - * - *

See: https://en.wikipedia.org/wiki/Horizontal_coordinate_system - * - *

On an Android device, azimuth north is defined as the angle perpendicular away from the - * back of the device when holding it in portrait mode upright. - * - *

Azimuth angle must be supported when Angle of Arrival is supported - * - * @return the azimuth {@link AngleMeasurement} - */ - @NonNull - public AngleMeasurement getAzimuth() { - return mAzimuthAngleMeasurement; - } - - /** - * Altitude angle measurement - *

Altitude {@link AngleMeasurement} of remote device in horizontal coordinate system, this - * is the angle above the equator when the north pole is up. - * - *

See: https://en.wikipedia.org/wiki/Horizontal_coordinate_system - * - *

On an Android device, altitude is defined as the angle vertical from ground when holding - * the device in portrait mode upright. - * - * @return altitude {@link AngleMeasurement} or null when this is not available - */ - @Nullable - public AngleMeasurement getAltitude() { - return mAltitudeAngleMeasurement; - } - - /** - * @hide - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof AngleOfArrivalMeasurement) { - AngleOfArrivalMeasurement other = (AngleOfArrivalMeasurement) obj; - return mAzimuthAngleMeasurement.equals(other.getAzimuth()) - && mAltitudeAngleMeasurement.equals(other.getAltitude()); - } - return false; - } - - /** - * @hide - */ - @Override - public int hashCode() { - return Objects.hash(mAzimuthAngleMeasurement, mAltitudeAngleMeasurement); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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(in.readParcelable(AngleMeasurement.class.getClassLoader())); - - builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader())); - - return builder.build(); - } - - @Override - public AngleOfArrivalMeasurement[] newArray(int size) { - return new AngleOfArrivalMeasurement[size]; - } - }; - - /** - * Builder class for {@link AngleOfArrivalMeasurement}. - */ - public static final class Builder { - private final AngleMeasurement mAzimuthAngleMeasurement; - private AngleMeasurement mAltitudeAngleMeasurement = null; - - /** - * Constructs an {@link AngleOfArrivalMeasurement} object - * - * @param azimuthAngle the azimuth angle of the measurement - */ - public Builder(@NonNull AngleMeasurement azimuthAngle) { - mAzimuthAngleMeasurement = azimuthAngle; - } - - /** - * Set the altitude angle - * - * @param altitudeAngle altitude angle - */ - @NonNull - public Builder setAltitude(@NonNull AngleMeasurement altitudeAngle) { - mAltitudeAngleMeasurement = altitudeAngle; - return this; - } - - /** - * Build the {@link AngleOfArrivalMeasurement} object - */ - @NonNull - public AngleOfArrivalMeasurement build() { - return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement, - mAltitudeAngleMeasurement); - } - } -} diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java deleted file mode 100644 index 98565536e64a3..0000000000000 --- a/core/java/android/uwb/DistanceMeasurement.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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.FloatRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * A data point for the distance measurement - * - *

The actual distance is interpreted as: - * {@link #getMeters()} +/- {@link #getErrorMeters()} at {@link #getConfidenceLevel()} - * - * @hide - */ -@SystemApi -public final class DistanceMeasurement implements Parcelable { - 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 - * - * @return distance in meters - */ - public double getMeters() { - return mMeters; - } - - /** - * Error of distance measurement in meters - *

Must be positive - * - * @return error of distance measurement in meters - */ - @FloatRange(from = 0.0) - public double getErrorMeters() { - return mErrorMeters; - } - - /** - * Distance measurement confidence level expressed as a value between 0.0 to 1.0. - * - *

A value of 0.0 indicates no confidence in the measurement. A value of 1.0 represents - * maximum confidence in the measurement - * - * @return confidence level - */ - @FloatRange(from = 0.0, to = 1.0) - public double getConfidenceLevel() { - return mConfidenceLevel; - } - - /** - * @hide - */ - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof DistanceMeasurement) { - DistanceMeasurement other = (DistanceMeasurement) obj; - return mMeters == other.getMeters() - && mErrorMeters == other.getErrorMeters() - && mConfidenceLevel == other.getConfidenceLevel(); - } - return false; - } - - /** - * @hide - */ - @Override - public int hashCode() { - return Objects.hash(mMeters, mErrorMeters, mConfidenceLevel); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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. - */ - 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 - */ - @NonNull - 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 - */ - @NonNull - public Builder setErrorMeters(@FloatRange(from = 0.0) 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] - */ - @NonNull - public Builder setConfidenceLevel( - @FloatRange(from = 0.0, to = 1.0) 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 - */ - @NonNull - 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); - } - } -} diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl deleted file mode 100644 index d87935003e03f..0000000000000 --- a/core/java/android/uwb/IUwbAdapter.aidl +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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.content.AttributionSource; -import android.os.PersistableBundle; -import android.uwb.IUwbAdapterStateCallbacks; -import android.uwb.IUwbRangingCallbacks; -import android.uwb.SessionHandle; - -/** - * @hide - */ -interface IUwbAdapter { - /* - * Register the callbacks used to notify the framework of events and data - * - * The provided callback's IUwbAdapterStateCallbacks#onAdapterStateChanged - * function must be called immediately following registration with the current - * state of the UWB adapter. - * - * @param callbacks callback to provide range and status updates to the framework - */ - void registerAdapterStateCallbacks(in IUwbAdapterStateCallbacks adapterStateCallbacks); - - /* - * Unregister the callbacks used to notify the framework of events and data - * - * Calling this function with an unregistered callback is a no-op - * - * @param callbacks callback to unregister - */ - void unregisterAdapterStateCallbacks(in IUwbAdapterStateCallbacks callbacks); - - /** - * Get the accuracy of the ranging timestamps - * - * @return accuracy of the ranging timestamps in nanoseconds - */ - long getTimestampResolutionNanos(); - - /** - * Provides the capabilities and features of the device - * - * @return specification specific capabilities and features of the device - */ - PersistableBundle getSpecificationInfo(); - - /** - * Request to open a new ranging session - * - * This function does not start the ranging session, but all necessary - * components must be initialized and ready to start a new ranging - * session prior to calling IUwbAdapterCallback#onRangingOpened. - * - * IUwbAdapterCallbacks#onRangingOpened must be called within - * RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being - * called if the ranging session is opened successfully. - * - * IUwbAdapterCallbacks#onRangingOpenFailed must be called within - * RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called - * if the ranging session fails to be opened. - * - * If the provided sessionHandle is already open for the calling client, then - * #onRangingOpenFailed must be called and the new session must not be opened. - * - * @param attributionSource AttributionSource to use for permission enforcement. - * @param sessionHandle the session handle to open ranging for - * @param rangingCallbacks the callbacks used to deliver ranging information - * @param parameters the configuration to use for ranging - */ - void openRanging(in AttributionSource attributionSource, - in SessionHandle sessionHandle, - in IUwbRangingCallbacks rangingCallbacks, - in PersistableBundle parameters); - - /** - * Request to start ranging - * - * IUwbAdapterCallbacks#onRangingStarted must be called within - * RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being - * called if the ranging session starts successfully. - * - * IUwbAdapterCallbacks#onRangingStartFailed must be called within - * RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being - * called if the ranging session fails to be started. - * - * @param sessionHandle the session handle to start ranging for - * @param parameters additional configuration required to start ranging - */ - void startRanging(in SessionHandle sessionHandle, - in PersistableBundle parameters); - - /** - * Request to reconfigure ranging - * - * IUwbAdapterCallbacks#onRangingReconfigured must be called after - * successfully reconfiguring the session. - * - * IUwbAdapterCallbacks#onRangingReconfigureFailed must be called after - * failing to reconfigure the session. - * - * A session must not be modified by a failed call to #reconfigureRanging. - * - * @param sessionHandle the session handle to start ranging for - * @param parameters the parameters to reconfigure and their new values - */ - void reconfigureRanging(in SessionHandle sessionHandle, - in PersistableBundle parameters); - - /** - * Request to stop ranging - * - * IUwbAdapterCallbacks#onRangingStopped must be called after - * successfully stopping the session. - * - * IUwbAdapterCallbacks#onRangingStopFailed must be called after failing - * to stop the session. - * - * @param sessionHandle the session handle to stop ranging for - */ - void stopRanging(in SessionHandle sessionHandle); - - /** - * Close ranging for the session associated with the given handle - * - * Calling with an invalid handle or a handle that has already been closed - * is a no-op. - * - * IUwbAdapterCallbacks#onRangingClosed must be called within - * RANGING_SESSION_CLOSE_THRESHOLD_MS of #closeRanging being called. - * - * @param sessionHandle the session handle to close ranging for - */ - void closeRanging(in SessionHandle sessionHandle); - - /** - * Disables or enables UWB for a user - * - * The provided callback's IUwbAdapterStateCallbacks#onAdapterStateChanged - * function must be called immediately following state change. - * - * @param enabled value representing intent to disable or enable UWB. If - * true, any subsequent calls to #openRanging will be allowed. If false, - * all active ranging sessions will be closed and subsequent calls to - * #openRanging will be disallowed. - */ - void setEnabled(boolean enabled); - - /** - * Returns the current enabled/disabled UWB state. - * - * Possible values are: - * IUwbAdapterState#STATE_DISABLED - * IUwbAdapterState#STATE_ENABLED_ACTIVE - * IUwbAdapterState#STATE_ENABLED_INACTIVE - * - * @return value representing enabled/disabled UWB state. - */ - int getAdapterState(); - - /** - * The maximum allowed time to open a ranging session. - */ - const int RANGING_SESSION_OPEN_THRESHOLD_MS = 3000; // Value TBD - - /** - * The maximum allowed time to start a ranging session. - */ - const int RANGING_SESSION_START_THRESHOLD_MS = 3000; // Value TBD - - /** - * The maximum allowed time to notify the framework that a session has been - * closed. - */ - const int RANGING_SESSION_CLOSE_THRESHOLD_MS = 3000; // Value TBD -} diff --git a/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl b/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl deleted file mode 100644 index d3b34c632bccb..0000000000000 --- a/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.uwb.StateChangeReason; -import android.uwb.AdapterState; - -/** - * @hide - */ -interface IUwbAdapterStateCallbacks { - /** - * Called whenever the adapter state changes - * - * @param state UWB state; enabled_active, enabled_inactive, or disabled. - * @param reason the reason that the state has changed - */ - void onAdapterStateChanged(AdapterState state, StateChangeReason reason); -} \ No newline at end of file diff --git a/core/java/android/uwb/IUwbRangingCallbacks.aidl b/core/java/android/uwb/IUwbRangingCallbacks.aidl deleted file mode 100644 index 555bafee8b1ec..0000000000000 --- a/core/java/android/uwb/IUwbRangingCallbacks.aidl +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.os.PersistableBundle; -import android.uwb.RangingChangeReason; -import android.uwb.RangingReport; -import android.uwb.SessionHandle; - -/** - * @hide - */ -oneway interface IUwbRangingCallbacks { - /** - * Called when the ranging session has been opened - * - * @param sessionHandle the session the callback is being invoked for - */ - void onRangingOpened(in SessionHandle sessionHandle); - - /** - * Called when a ranging session fails to start - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session failed to start - * @param parameters protocol specific parameters - */ - void onRangingOpenFailed(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Called when ranging has started - * - * May output parameters generated by the lower layers that must be sent to the - * remote device(s). The PersistableBundle must be constructed using the UWB - * support library. - * - * @param sessionHandle the session the callback is being invoked for - * @param rangingOutputParameters parameters generated by the lower layer that - * should be sent to the remote device. - */ - void onRangingStarted(in SessionHandle sessionHandle, - in PersistableBundle parameters); - - /** - * Called when a ranging session fails to start - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session failed to start - * @param parameters protocol specific parameters - */ - void onRangingStartFailed(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Called when ranging has been reconfigured - * - * @param sessionHandle the session the callback is being invoked for - * @param parameters the updated ranging configuration - */ - void onRangingReconfigured(in SessionHandle sessionHandle, - in PersistableBundle parameters); - - /** - * Called when a ranging session fails to be reconfigured - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session failed to reconfigure - * @param parameters protocol specific parameters - */ - void onRangingReconfigureFailed(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Called when the ranging session has been stopped - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session was stopped - * @param parameters protocol specific parameters - */ - - void onRangingStopped(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Called when a ranging session fails to stop - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session failed to stop - * @param parameters protocol specific parameters - */ - void onRangingStopFailed(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Called when a ranging session is closed - * - * @param sessionHandle the session the callback is being invoked for - * @param reason the reason the session was closed - * @param parameters protocol specific parameters - */ - void onRangingClosed(in SessionHandle sessionHandle, - RangingChangeReason reason, - in PersistableBundle parameters); - - /** - * Provides a new RangingResult to the framework - * - * The reported timestamp for a ranging measurement must be calculated as the - * time which the ranging round that generated this measurement concluded. - * - * @param sessionHandle an identifier to associate the ranging results with a - * session that is active - * @param result the ranging report - */ - void onRangingResult(in SessionHandle sessionHandle, in RangingReport result); -} diff --git a/core/java/android/uwb/MeasurementStatus.aidl b/core/java/android/uwb/MeasurementStatus.aidl deleted file mode 100644 index 5fa15549e84dd..0000000000000 --- a/core/java/android/uwb/MeasurementStatus.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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; - -/** - * @hide - */ -@Backing(type="int") -enum MeasurementStatus { - /** - * Ranging was successful - */ - SUCCESS, - - /** - * The remote device is out of range - */ - FAILURE_OUT_OF_RANGE, - - /** - * An unknown failure has occurred. - */ - FAILURE_UNKNOWN, -} - diff --git a/core/java/android/uwb/OWNERS b/core/java/android/uwb/OWNERS deleted file mode 100644 index 17936ae7bb73a..0000000000000 --- a/core/java/android/uwb/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -bstack@google.com -eliptus@google.com -jsolnit@google.com -matbev@google.com -siyuanh@google.com -zachoverflow@google.com diff --git a/core/java/android/uwb/RangingChangeReason.aidl b/core/java/android/uwb/RangingChangeReason.aidl deleted file mode 100644 index 19d4b3949d07d..0000000000000 --- a/core/java/android/uwb/RangingChangeReason.aidl +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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; - -/** - * @hide - */ -@Backing(type="int") -enum RangingChangeReason { - /** - * Unknown reason - */ - UNKNOWN, - - /** - * A local API call triggered the change, such as a call to - * IUwbAdapter.closeRanging. - */ - LOCAL_API, - - /** - * The maximum number of sessions has been reached. This may be generated for - * an active session if a higher priority session begins. - */ - MAX_SESSIONS_REACHED, - - /** - * The system state has changed resulting in the session changing (e.g. the - * user disables UWB, or the user's locale changes and an active channel is no - * longer permitted to be used). - */ - SYSTEM_POLICY, - - /** - * The remote device has requested to change the session - */ - REMOTE_REQUEST, - - /** - * The session changed for a protocol specific reason - */ - PROTOCOL_SPECIFIC, - - /** - * The provided parameters were invalid - */ - BAD_PARAMETERS, -} - diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java deleted file mode 100644 index 6bba796005989..0000000000000 --- a/core/java/android/uwb/RangingManager.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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.NonNull; -import android.content.AttributionSource; -import android.os.CancellationSignal; -import android.os.PersistableBundle; -import android.os.RemoteException; -import android.util.Log; - -import java.util.Hashtable; -import java.util.concurrent.Executor; - -/** - * @hide - */ -public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { - private static final String TAG = "Uwb.RangingManager"; - - private final IUwbAdapter mAdapter; - private final Hashtable mRangingSessionTable = new Hashtable<>(); - private int mNextSessionId = 1; - - public RangingManager(IUwbAdapter adapter) { - mAdapter = adapter; - } - - /** - * Open a new ranging session - * - * @param attributionSource Attribution source to use for the enforcement of - * {@link android.Manifest.permission#ULTRAWIDEBAND_RANGING} runtime - * permission. - * @param params the parameters that define the ranging session - * @param executor {@link Executor} to run callbacks - * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession} - * that is being opened. - * @return a {@link CancellationSignal} that may be used to cancel the opening of the - * {@link RangingSession}. - */ - public CancellationSignal openSession(@NonNull AttributionSource attributionSource, - @NonNull PersistableBundle params, - @NonNull Executor executor, - @NonNull RangingSession.Callback callbacks) { - synchronized (this) { - SessionHandle sessionHandle = new SessionHandle(mNextSessionId++); - RangingSession session = - new RangingSession(executor, callbacks, mAdapter, sessionHandle); - mRangingSessionTable.put(sessionHandle, session); - try { - mAdapter.openRanging(attributionSource, sessionHandle, this, params); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - - CancellationSignal cancellationSignal = new CancellationSignal(); - cancellationSignal.setOnCancelListener(() -> session.close()); - return cancellationSignal; - } - } - - private boolean hasSession(SessionHandle sessionHandle) { - return mRangingSessionTable.containsKey(sessionHandle); - } - - @Override - public void onRangingOpened(SessionHandle sessionHandle) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, - "onRangingOpened - received unexpected SessionHandle: " + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingOpened(); - } - } - - @Override - public void onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, - PersistableBundle parameters) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, - "onRangingOpenedFailed - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingOpenFailed(convertToReason(reason), parameters); - mRangingSessionTable.remove(sessionHandle); - } - } - - @Override - public void onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, - "onRangingReconfigured - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingReconfigured(parameters); - } - } - - @Override - public void onRangingReconfigureFailed(SessionHandle sessionHandle, - @RangingChangeReason int reason, PersistableBundle params) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingReconfigureFailed - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingReconfigureFailed(convertToReason(reason), params); - } - } - - - @Override - public void onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, - "onRangingStarted - received unexpected SessionHandle: " + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingStarted(parameters); - } - } - - @Override - public void onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, - PersistableBundle params) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingStartFailed - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingStartFailed(convertToReason(reason), params); - } - } - - @Override - public void onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason, - PersistableBundle params) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingStopped - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingStopped(convertToReason(reason), params); - } - } - - @Override - public void onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, - PersistableBundle parameters) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingStopFailed - received unexpected SessionHandle: " - + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingStopFailed(convertToReason(reason), parameters); - } - } - - @Override - public void onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason, - PersistableBundle params) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingClosed - received unexpected SessionHandle: " + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingClosed(convertToReason(reason), params); - mRangingSessionTable.remove(sessionHandle); - } - } - - @Override - public void onRangingResult(SessionHandle sessionHandle, RangingReport result) { - synchronized (this) { - if (!hasSession(sessionHandle)) { - Log.w(TAG, "onRangingResult - received unexpected SessionHandle: " + sessionHandle); - return; - } - - RangingSession session = mRangingSessionTable.get(sessionHandle); - session.onRangingResult(result); - } - } - - @RangingSession.Callback.Reason - private static int convertToReason(@RangingChangeReason int reason) { - switch (reason) { - case RangingChangeReason.LOCAL_API: - return RangingSession.Callback.REASON_LOCAL_REQUEST; - - case RangingChangeReason.MAX_SESSIONS_REACHED: - return RangingSession.Callback.REASON_MAX_SESSIONS_REACHED; - - case RangingChangeReason.SYSTEM_POLICY: - return RangingSession.Callback.REASON_SYSTEM_POLICY; - - case RangingChangeReason.REMOTE_REQUEST: - return RangingSession.Callback.REASON_REMOTE_REQUEST; - - case RangingChangeReason.PROTOCOL_SPECIFIC: - return RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR; - - case RangingChangeReason.BAD_PARAMETERS: - return RangingSession.Callback.REASON_BAD_PARAMETERS; - - case RangingChangeReason.UNKNOWN: - default: - return RangingSession.Callback.REASON_UNKNOWN; - } - } -} diff --git a/core/java/android/uwb/RangingMeasurement.java b/core/java/android/uwb/RangingMeasurement.java deleted file mode 100644 index 249e2b746d0d0..0000000000000 --- a/core/java/android/uwb/RangingMeasurement.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; - -/** - * Representation of a ranging measurement between the local device and a remote device - * - * @hide - */ -@SystemApi -public final class RangingMeasurement implements Parcelable { - 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} - * - * @return the remote device's {@link UwbAddress} - */ - @NonNull - public UwbAddress getRemoteDeviceAddress() { - return mRemoteDeviceAddress; - } - - /** - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - RANGING_STATUS_SUCCESS, - RANGING_STATUS_FAILURE_OUT_OF_RANGE, - RANGING_STATUS_FAILURE_UNKNOWN_ERROR}) - public @interface Status {} - - /** - * Ranging attempt was successful for this device - */ - public static final int RANGING_STATUS_SUCCESS = 0; - - /** - * Ranging failed for this device because it is out of range - */ - public static final int RANGING_STATUS_FAILURE_OUT_OF_RANGE = 1; - - /** - * Ranging failed for this device because of unknown error - */ - public static final int RANGING_STATUS_FAILURE_UNKNOWN_ERROR = -1; - - /** - * Get the status of this ranging measurement - * - *

Possible values are - * {@link #RANGING_STATUS_SUCCESS}, - * {@link #RANGING_STATUS_FAILURE_OUT_OF_RANGE}, - * {@link #RANGING_STATUS_FAILURE_UNKNOWN_ERROR}. - * - * @return the status of the ranging measurement - */ - @Status - public int getStatus() { - return mStatus; - } - - /** - * Timestamp of this ranging measurement in time since boot nanos in the same namespace as - * {@link SystemClock#elapsedRealtimeNanos()} - * - * @return timestamp of ranging measurement in nanoseconds - */ - @SuppressLint("MethodNameUnits") - public long getElapsedRealtimeNanos() { - return mElapsedRealtimeNanos; - } - - /** - * Get the distance measurement - * - * @return a {@link DistanceMeasurement} or null if {@link #getStatus()} != - * {@link #RANGING_STATUS_SUCCESS} - */ - @Nullable - public DistanceMeasurement getDistanceMeasurement() { - return mDistanceMeasurement; - } - - /** - * Get the angle of arrival measurement - * - * @return an {@link AngleOfArrivalMeasurement} or null if {@link #getStatus()} != - * {@link #RANGING_STATUS_SUCCESS} - */ - @Nullable - public AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() { - return mAngleOfArrivalMeasurement; - } - - /** - * @hide - */ - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof RangingMeasurement) { - RangingMeasurement other = (RangingMeasurement) obj; - return mRemoteDeviceAddress.equals(other.getRemoteDeviceAddress()) - && mStatus == other.getStatus() - && mElapsedRealtimeNanos == other.getElapsedRealtimeNanos() - && mDistanceMeasurement.equals(other.getDistanceMeasurement()) - && mAngleOfArrivalMeasurement.equals(other.getAngleOfArrivalMeasurement()); - } - return false; - } - - /** - * @hide - */ - @Override - public int hashCode() { - return Objects.hash(mRemoteDeviceAddress, mStatus, mElapsedRealtimeNanos, - mDistanceMeasurement, mAngleOfArrivalMeasurement); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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. - */ - 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 - */ - @NonNull - public Builder setRemoteDeviceAddress(@NonNull UwbAddress remoteDeviceAddress) { - mRemoteDeviceAddress = remoteDeviceAddress; - return this; - } - - /** - * Set the status of ranging measurement - * - * @param status the status of the ranging measurement - */ - @NonNull - 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 - */ - @NonNull - 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 - */ - @NonNull - 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 - */ - @NonNull - 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 - */ - @NonNull - 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); - } - } -} diff --git a/core/java/android/uwb/RangingReport.aidl b/core/java/android/uwb/RangingReport.aidl deleted file mode 100644 index c32747ae58da6..0000000000000 --- a/core/java/android/uwb/RangingReport.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -parcelable RangingReport; diff --git a/core/java/android/uwb/RangingReport.java b/core/java/android/uwb/RangingReport.java deleted file mode 100644 index 7a2df86177004..0000000000000 --- a/core/java/android/uwb/RangingReport.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * This class contains the UWB ranging data - * - * @hide - */ -@SystemApi -public final class RangingReport implements Parcelable { - private final List mRangingMeasurements; - - private RangingReport(@NonNull List rangingMeasurements) { - mRangingMeasurements = rangingMeasurements; - } - - /** - * Get a {@link List} of {@link RangingMeasurement} objects in the last measurement interval - *

The underlying UWB adapter may choose to do multiple measurements in each ranging - * interval. - * - *

The entries in the {@link List} are ordered in ascending order based on - * {@link RangingMeasurement#getElapsedRealtimeNanos()} - * - * @return a {@link List} of {@link RangingMeasurement} objects - */ - @NonNull - public List getMeasurements() { - return mRangingMeasurements; - } - - /** - * @hide - */ - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof RangingReport) { - RangingReport other = (RangingReport) obj; - return mRangingMeasurements.equals(other.getMeasurements()); - } - - return false; - } - - /** - * @hide - */ - @Override - public int hashCode() { - return Objects.hash(mRangingMeasurements); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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 - */ - public static final class Builder { - List mMeasurements = new ArrayList<>(); - - /** - * Add a single {@link RangingMeasurement} - * - * @param rangingMeasurement a ranging measurement - */ - @NonNull - 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 - */ - @NonNull - public Builder addMeasurements(@NonNull List rangingMeasurements) { - mMeasurements.addAll(rangingMeasurements); - return this; - } - - /** - * Build the {@link RangingReport} object - * - * @throws IllegalStateException if measurements are not in monotonically increasing order - */ - @NonNull - 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); - } - } -} - diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java deleted file mode 100644 index 345b69df84d50..0000000000000 --- a/core/java/android/uwb/RangingSession.java +++ /dev/null @@ -1,496 +0,0 @@ -/* - * 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.Manifest; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.os.Binder; -import android.os.PersistableBundle; -import android.os.RemoteException; -import android.util.Log; - -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. - *

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}. - * - *

To get an instance of {@link RangingSession}, first use - * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} to request to open a - * session. Once the session is opened, a {@link RangingSession} object is provided through - * {@link RangingSession.Callback#onOpened(RangingSession)}. If opening a session fails, the failure - * is reported through {@link RangingSession.Callback#onOpenFailed(int, PersistableBundle)} with the - * failure reason. - * - * @hide - */ -@SystemApi -public final class RangingSession implements AutoCloseable { - private static final String TAG = "Uwb.RangingSession"; - private final SessionHandle mSessionHandle; - private final IUwbAdapter mAdapter; - private final Executor mExecutor; - private final Callback mCallback; - - private enum State { - /** - * The state of the {@link RangingSession} until - * {@link RangingSession.Callback#onOpened(RangingSession)} is invoked - */ - INIT, - - /** - * The {@link RangingSession} is initialized and ready to begin ranging - */ - IDLE, - - /** - * The {@link RangingSession} is actively ranging - */ - ACTIVE, - - /** - * The {@link RangingSession} is closed and may not be used for ranging. - */ - CLOSED - } - - private State mState = State.INIT; - - /** - * Interface for receiving {@link RangingSession} events - */ - public interface Callback { - /** - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - REASON_UNKNOWN, - REASON_LOCAL_REQUEST, - REASON_REMOTE_REQUEST, - REASON_BAD_PARAMETERS, - REASON_GENERIC_ERROR, - REASON_MAX_SESSIONS_REACHED, - REASON_SYSTEM_POLICY, - REASON_PROTOCOL_SPECIFIC_ERROR}) - @interface Reason {} - - /** - * Indicates that the session was closed or failed to open due to an unknown reason - */ - int REASON_UNKNOWN = 0; - - /** - * Indicates that the session was closed or failed to open because - * {@link AutoCloseable#close()} or {@link RangingSession#close()} was called - */ - int REASON_LOCAL_REQUEST = 1; - - /** - * Indicates that the session was closed or failed to open due to an explicit request from - * the remote device. - */ - int REASON_REMOTE_REQUEST = 2; - - /** - * Indicates that the session was closed or failed to open due to erroneous parameters - */ - int REASON_BAD_PARAMETERS = 3; - - /** - * Indicates an error on this device besides the error code already listed - */ - int REASON_GENERIC_ERROR = 4; - - /** - * Indicates that the number of currently open sessions is equal to - * {@link UwbManager#getMaxSimultaneousSessions()} and additional sessions may not be - * opened. - */ - int REASON_MAX_SESSIONS_REACHED = 5; - - /** - * Indicates that the local system policy caused the change, such - * as privacy policy, power management policy, permissions, and more. - */ - int REASON_SYSTEM_POLICY = 6; - - /** - * Indicates a protocol specific error. The associated {@link PersistableBundle} should be - * consulted for additional information. - */ - int REASON_PROTOCOL_SPECIFIC_ERROR = 7; - - /** - * Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} - * is successful - * - * @param session the newly opened {@link RangingSession} - */ - void onOpened(@NonNull RangingSession session); - - /** - * Invoked if {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}} - * fails - * - * @param reason the failure reason - * @param params protocol specific parameters - */ - void onOpenFailed(@Reason int reason, @NonNull PersistableBundle params); - - /** - * Invoked when {@link RangingSession#start(PersistableBundle)} is successful - * @param sessionInfo session specific parameters from the lower layers - */ - void onStarted(@NonNull PersistableBundle sessionInfo); - - /** - * Invoked when {@link RangingSession#start(PersistableBundle)} fails - * - * @param reason the failure reason - * @param params protocol specific parameters - */ - void onStartFailed(@Reason int reason, @NonNull PersistableBundle params); - - /** - * Invoked when a request to reconfigure the session succeeds - * - * @param params the updated ranging configuration - */ - void onReconfigured(@NonNull PersistableBundle params); - - /** - * Invoked when a request to reconfigure the session fails - * - * @param reason reason the session failed to be reconfigured - * @param params protocol specific failure reasons - */ - void onReconfigureFailed(@Reason int reason, @NonNull PersistableBundle params); - - /** - * Invoked when a request to stop the session succeeds - * - * @param reason reason for the session stop - * @param parameters protocol specific parameters related to the stop reason - */ - void onStopped(@Reason int reason, @NonNull PersistableBundle parameters); - - /** - * Invoked when a request to stop the session fails - * - * @param reason reason the session failed to be stopped - * @param params protocol specific failure reasons - */ - void onStopFailed(@Reason int reason, @NonNull PersistableBundle params); - - /** - * Invoked when session is either closed spontaneously, or per user request via - * {@link RangingSession#close()} or {@link AutoCloseable#close()}. - * - * @param reason reason for the session closure - * @param parameters protocol specific parameters related to the close reason - */ - void onClosed(@Reason int reason, @NonNull PersistableBundle parameters); - - /** - * Called once per ranging interval even when a ranging measurement fails - * - * @param rangingReport ranging report for this interval's measurements - */ - void onReportReceived(@NonNull RangingReport rangingReport); - } - - /** - * @hide - */ - public RangingSession(Executor executor, Callback callback, IUwbAdapter adapter, - SessionHandle sessionHandle) { - mState = State.INIT; - mExecutor = executor; - mCallback = callback; - mAdapter = adapter; - mSessionHandle = sessionHandle; - } - - /** - * @hide - */ - public boolean isOpen() { - return mState == State.IDLE || mState == State.ACTIVE; - } - - /** - * Begins ranging for the session. - * - *

On successfully starting a ranging session, - * {@link RangingSession.Callback#onStarted(PersistableBundle)} is invoked. - * - *

On failure to start the session, - * {@link RangingSession.Callback#onStartFailed(int, PersistableBundle)} is invoked. - * - * @param params configuration parameters for starting the session - */ - @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public void start(@NonNull PersistableBundle params) { - if (mState != State.IDLE) { - throw new IllegalStateException(); - } - - try { - mAdapter.startRanging(mSessionHandle, params); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Attempts to reconfigure the session with the given parameters - *

This call may be made when the session is open. - * - *

On successfully reconfiguring the session - * {@link RangingSession.Callback#onReconfigured(PersistableBundle)} is invoked. - * - *

On failure to reconfigure the session, - * {@link RangingSession.Callback#onReconfigureFailed(int, PersistableBundle)} is invoked. - * - * @param params the parameters to reconfigure and their new values - */ - @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public void reconfigure(@NonNull PersistableBundle params) { - if (mState != State.ACTIVE && mState != State.IDLE) { - throw new IllegalStateException(); - } - - try { - mAdapter.reconfigureRanging(mSessionHandle, params); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Stops actively ranging - * - *

A session that has been stopped may be resumed by calling - * {@link RangingSession#start(PersistableBundle)} without the need to open a new session. - * - *

Stopping a {@link RangingSession} is useful when the lower layers should not discard - * the parameters of the session, or when a session needs to be able to be resumed quickly. - * - *

If the {@link RangingSession} is no longer needed, use {@link RangingSession#close()} to - * completely close the session and allow lower layers of the stack to perform necessarily - * cleanup. - * - *

Stopped sessions may be closed by the system at any time. In such a case, - * {@link RangingSession.Callback#onClosed(int, PersistableBundle)} is invoked. - * - *

On failure to stop the session, - * {@link RangingSession.Callback#onStopFailed(int, PersistableBundle)} is invoked. - */ - @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public void stop() { - if (mState != State.ACTIVE) { - throw new IllegalStateException(); - } - - try { - mAdapter.stopRanging(mSessionHandle); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Close the ranging session - * - *

After calling this function, in order resume ranging, a new {@link RangingSession} must - * be opened by calling - * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}. - * - *

If this session is currently ranging, it will stop and close the session. - *

If the session is in the process of being opened, it will attempt to stop the session from - * being opened. - *

If the session is already closed, the registered - * {@link Callback#onClosed(int, PersistableBundle)} callback will still be invoked. - * - *

{@link Callback#onClosed(int, PersistableBundle)} will be invoked using the same callback - * object given to {@link UwbManager#openRangingSession(PersistableBundle, 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 - @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public void close() { - if (mState == State.CLOSED) { - mExecutor.execute(() -> mCallback.onClosed( - Callback.REASON_LOCAL_REQUEST, new PersistableBundle())); - return; - } - - try { - mAdapter.closeRanging(mSessionHandle); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * @hide - */ - public void onRangingOpened() { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingOpened invoked for a closed session"); - return; - } - - mState = State.IDLE; - executeCallback(() -> mCallback.onOpened(this)); - } - - /** - * @hide - */ - public void onRangingOpenFailed(@Callback.Reason int reason, - @NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingOpenFailed invoked for a closed session"); - return; - } - - mState = State.CLOSED; - executeCallback(() -> mCallback.onOpenFailed(reason, params)); - } - - /** - * @hide - */ - public void onRangingStarted(@NonNull PersistableBundle parameters) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingStarted invoked for a closed session"); - return; - } - - mState = State.ACTIVE; - executeCallback(() -> mCallback.onStarted(parameters)); - } - - /** - * @hide - */ - public void onRangingStartFailed(@Callback.Reason int reason, - @NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingStartFailed invoked for a closed session"); - return; - } - - executeCallback(() -> mCallback.onStartFailed(reason, params)); - } - - /** - * @hide - */ - public void onRangingReconfigured(@NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingReconfigured invoked for a closed session"); - return; - } - - executeCallback(() -> mCallback.onReconfigured(params)); - } - - /** - * @hide - */ - public void onRangingReconfigureFailed(@Callback.Reason int reason, - @NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingReconfigureFailed invoked for a closed session"); - return; - } - - executeCallback(() -> mCallback.onReconfigureFailed(reason, params)); - } - - /** - * @hide - */ - public void onRangingStopped(@Callback.Reason int reason, - @NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingStopped invoked for a closed session"); - return; - } - - mState = State.IDLE; - executeCallback(() -> mCallback.onStopped(reason, params)); - } - - /** - * @hide - */ - public void onRangingStopFailed(@Callback.Reason int reason, - @NonNull PersistableBundle params) { - if (mState == State.CLOSED) { - Log.w(TAG, "onRangingStopFailed invoked for a closed session"); - return; - } - - executeCallback(() -> mCallback.onStopFailed(reason, params)); - } - - /** - * @hide - */ - public void onRangingClosed(@Callback.Reason int reason, - @NonNull PersistableBundle parameters) { - mState = State.CLOSED; - executeCallback(() -> mCallback.onClosed(reason, parameters)); - } - - /** - * @hide - */ - public void onRangingResult(@NonNull RangingReport report) { - if (!isOpen()) { - Log.w(TAG, "onRangingResult invoked for non-open session"); - return; - } - - executeCallback(() -> mCallback.onReportReceived(report)); - } - - /** - * @hide - */ - private void executeCallback(@NonNull Runnable runnable) { - final long identity = Binder.clearCallingIdentity(); - try { - mExecutor.execute(runnable); - } finally { - Binder.restoreCallingIdentity(identity); - } - } -} diff --git a/core/java/android/uwb/SessionHandle.aidl b/core/java/android/uwb/SessionHandle.aidl deleted file mode 100644 index 58a7dbb2ef9f9..0000000000000 --- a/core/java/android/uwb/SessionHandle.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -parcelable SessionHandle; diff --git a/core/java/android/uwb/SessionHandle.java b/core/java/android/uwb/SessionHandle.java deleted file mode 100644 index b23f5ad603ff2..0000000000000 --- a/core/java/android/uwb/SessionHandle.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * @hide - */ -public final class SessionHandle implements Parcelable { - private final int mId; - - public SessionHandle(int id) { - mId = id; - } - - protected SessionHandle(Parcel in) { - mId = in.readInt(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public SessionHandle createFromParcel(Parcel in) { - return new SessionHandle(in); - } - - @Override - public SessionHandle[] newArray(int size) { - return new SessionHandle[size]; - } - }; - - public int getId() { - return mId; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mId); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof SessionHandle) { - SessionHandle other = (SessionHandle) obj; - return mId == other.mId; - } - return false; - } - - @Override - public int hashCode() { - return Objects.hashCode(mId); - } - - @Override - public String toString() { - return "SessionHandle [id=" + mId + "]"; - } -} diff --git a/core/java/android/uwb/StateChangeReason.aidl b/core/java/android/uwb/StateChangeReason.aidl deleted file mode 100644 index 28eaf9f2b24ee..0000000000000 --- a/core/java/android/uwb/StateChangeReason.aidl +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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; - -/** - * @hide - */ -@Backing(type="int") -enum StateChangeReason { - /** - * The state changed for an unknown reason - */ - UNKNOWN, - - /** - * The adapter state changed because a session started. - */ - SESSION_STARTED, - - - /** - * The adapter state changed because all sessions were closed. - */ - ALL_SESSIONS_CLOSED, - - /** - * The adapter state changed because of a device system change. - */ - SYSTEM_POLICY, - - /** - * Used to signal the first adapter state message after boot - */ - SYSTEM_BOOT, -} - diff --git a/core/java/android/uwb/TEST_MAPPING b/core/java/android/uwb/TEST_MAPPING deleted file mode 100644 index 08ed2c7b71d93..0000000000000 --- a/core/java/android/uwb/TEST_MAPPING +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presubmit": [ - { - "name": "UwbManagerTests" - }, - { - "name": "CtsUwbTestCases" - } - ] -} diff --git a/core/java/android/uwb/UwbAddress.aidl b/core/java/android/uwb/UwbAddress.aidl deleted file mode 100644 index a202b1a1f51de..0000000000000 --- a/core/java/android/uwb/UwbAddress.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -parcelable UwbAddress; diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java deleted file mode 100644 index 22883be887608..0000000000000 --- a/core/java/android/uwb/UwbAddress.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Arrays; - -/** - * A class representing a UWB address - * - * @hide - */ -@SystemApi -public final class UwbAddress implements Parcelable { - 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. - * - *

If the provided array is {@link #SHORT_ADDRESS_BYTE_LENGTH} bytes, a short address is - * created. If the provided array is {@link #EXTENDED_ADDRESS_BYTE_LENGTH} bytes, then an - * extended address is created. - * - * @param address a byte array to convert to a {@link UwbAddress} - * @return a {@link UwbAddress} created from the input byte array - * @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(@NonNull byte[] address) { - 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); - } - - /** - * Get the address as a byte array - * - * @return the byte representation of this {@link UwbAddress} - */ - @NonNull - public byte[] toBytes() { - return mAddressBytes; - } - - /** - * The length of the address in bytes - *

Possible values are {@link #SHORT_ADDRESS_BYTE_LENGTH} and - * {@link #EXTENDED_ADDRESS_BYTE_LENGTH}. - */ - public int size() { - return mAddressBytes.length; - } - - @NonNull - @Override - public String toString() { - 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) { - if (obj instanceof UwbAddress) { - return Arrays.equals(mAddressBytes, ((UwbAddress) obj).toBytes()); - } - return false; - } - - @Override - public int hashCode() { - return Arrays.hashCode(mAddressBytes); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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]; - } - }; -} diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java deleted file mode 100644 index f7406ae277de5..0000000000000 --- a/core/java/android/uwb/UwbManager.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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.Manifest.permission; -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.content.Context; -import android.os.CancellationSignal; -import android.os.IBinder; -import android.os.PersistableBundle; -import android.os.RemoteException; -import android.os.ServiceManager; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.Executor; - -/** - * This class provides a way to perform Ultra Wideband (UWB) operations such as querying the - * device's capabilities and determining the distance and angle between the local device and a - * remote device. - * - *

To get a {@link UwbManager}, call the Context.getSystemService(UwbManager.class). - * - * @hide - */ -@SystemApi -@SystemService(Context.UWB_SERVICE) -public final class UwbManager { - private static final String SERVICE_NAME = Context.UWB_SERVICE; - - private final Context mContext; - private final IUwbAdapter mUwbAdapter; - private final AdapterStateListener mAdapterStateListener; - private final RangingManager mRangingManager; - - /** - * Interface for receiving UWB adapter state changes - */ - public interface AdapterStateCallback { - /** - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - STATE_CHANGED_REASON_SESSION_STARTED, - STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED, - STATE_CHANGED_REASON_SYSTEM_POLICY, - STATE_CHANGED_REASON_SYSTEM_BOOT, - STATE_CHANGED_REASON_ERROR_UNKNOWN}) - @interface StateChangedReason {} - - /** - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - STATE_ENABLED_INACTIVE, - STATE_ENABLED_ACTIVE, - STATE_DISABLED}) - @interface State {} - - /** - * Indicates that the state change was due to opening of first UWB session - */ - int STATE_CHANGED_REASON_SESSION_STARTED = 0; - - /** - * Indicates that the state change was due to closure of all UWB sessions - */ - int STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED = 1; - - /** - * Indicates that the state change was due to changes in system policy - */ - int STATE_CHANGED_REASON_SYSTEM_POLICY = 2; - - /** - * Indicates that the current state is due to a system boot - */ - int STATE_CHANGED_REASON_SYSTEM_BOOT = 3; - - /** - * Indicates that the state change was due to some unknown error - */ - int STATE_CHANGED_REASON_ERROR_UNKNOWN = 4; - - /** - * Indicates that UWB is disabled on device - */ - int STATE_DISABLED = 0; - /** - * Indicates that UWB is enabled on device but has no active ranging sessions - */ - int STATE_ENABLED_INACTIVE = 1; - - /** - * Indicates that UWB is enabled and has active ranging session - */ - int STATE_ENABLED_ACTIVE = 2; - - /** - * Invoked when underlying UWB adapter's state is changed - *

Invoked with the adapter's current state after registering an - * {@link AdapterStateCallback} using - * {@link UwbManager#registerAdapterStateCallback(Executor, AdapterStateCallback)}. - * - *

Possible reasons for the state to change are - * {@link #STATE_CHANGED_REASON_SESSION_STARTED}, - * {@link #STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED}, - * {@link #STATE_CHANGED_REASON_SYSTEM_POLICY}, - * {@link #STATE_CHANGED_REASON_SYSTEM_BOOT}, - * {@link #STATE_CHANGED_REASON_ERROR_UNKNOWN}. - * - *

Possible values for the UWB state are - * {@link #STATE_ENABLED_INACTIVE}, - * {@link #STATE_ENABLED_ACTIVE}, - * {@link #STATE_DISABLED}. - * - * @param state the UWB state; inactive, active or disabled - * @param reason the reason for the state change - */ - void onStateChanged(@State int state, @StateChangedReason int reason); - } - - /** - * Use Context.getSystemService(UwbManager.class) to get an instance. - * - * @param ctx Context of the client. - * @param adapter an instance of an {@link android.uwb.IUwbAdapter} - */ - private UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) { - mContext = ctx; - mUwbAdapter = adapter; - mAdapterStateListener = new AdapterStateListener(adapter); - mRangingManager = new RangingManager(adapter); - } - - /** - * @hide - */ - public static UwbManager getInstance(@NonNull Context ctx) { - IBinder b = ServiceManager.getService(SERVICE_NAME); - if (b == null) { - return null; - } - - IUwbAdapter adapter = IUwbAdapter.Stub.asInterface(b); - if (adapter == null) { - return null; - } - - return new UwbManager(ctx, adapter); - } - - /** - * Register an {@link AdapterStateCallback} to listen for UWB adapter state changes - *

The provided callback will be invoked by the given {@link Executor}. - * - *

When first registering a callback, the callbacks's - * {@link AdapterStateCallback#onStateChanged(int, int)} is immediately invoked to indicate - * the current state of the underlying UWB adapter with the most recent - * {@link AdapterStateCallback.StateChangedReason} that caused the change. - * - * @param executor an {@link Executor} to execute given callback - * @param callback user implementation of the {@link AdapterStateCallback} - */ - @RequiresPermission(permission.UWB_PRIVILEGED) - public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor, - @NonNull AdapterStateCallback callback) { - mAdapterStateListener.register(executor, callback); - } - - /** - * Unregister the specified {@link AdapterStateCallback} - *

The same {@link AdapterStateCallback} object used when calling - * {@link #registerAdapterStateCallback(Executor, AdapterStateCallback)} must be used. - * - *

Callbacks are automatically unregistered when application process goes away - * - * @param callback user implementation of the {@link AdapterStateCallback} - */ - @RequiresPermission(permission.UWB_PRIVILEGED) - public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) { - mAdapterStateListener.unregister(callback); - } - - /** - * Get a {@link PersistableBundle} with the supported UWB protocols and parameters. - *

The {@link PersistableBundle} should be parsed using a support library - * - *

Android reserves the '^android.*' namespace

- * - * @return {@link PersistableBundle} of the device's supported UWB protocols and parameters - */ - @NonNull - @RequiresPermission(permission.UWB_PRIVILEGED) - public PersistableBundle getSpecificationInfo() { - try { - return mUwbAdapter.getSpecificationInfo(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get the timestamp resolution for events in nanoseconds - *

This value defines the maximum error of all timestamps for events reported to - * {@link RangingSession.Callback}. - * - * @return the timestamp resolution in nanoseconds - */ - @SuppressLint("MethodNameUnits") - @RequiresPermission(permission.UWB_PRIVILEGED) - public long elapsedRealtimeResolutionNanos() { - try { - return mUwbAdapter.getTimestampResolutionNanos(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Open a {@link RangingSession} with the given parameters - *

The {@link RangingSession.Callback#onOpened(RangingSession)} function is called with a - * {@link RangingSession} object used to control ranging when the session is successfully - * opened. - * - *

If a session cannot be opened, then - * {@link RangingSession.Callback#onClosed(int, PersistableBundle)} will be invoked with the - * appropriate {@link RangingSession.Callback.Reason}. - * - *

An open {@link RangingSession} will be automatically closed if client application process - * dies. - * - *

A UWB support library must be used in order to construct the {@code parameter} - * {@link PersistableBundle}. - * - * @param parameters the parameters that define the ranging session - * @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 CancellationSignal} that is able to be used to 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#onOpened(RangingSession)}. - */ - @NonNull - @RequiresPermission(allOf = { - permission.UWB_PRIVILEGED, - permission.UWB_RANGING - }) - public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters, - @NonNull @CallbackExecutor Executor executor, - @NonNull RangingSession.Callback callbacks) { - return mRangingManager.openSession( - mContext.getAttributionSource(), parameters, executor, callbacks); - } - - /** - * Returns the current enabled/disabled state for UWB. - * - * Possible values are: - * AdapterStateCallback#STATE_DISABLED - * AdapterStateCallback#STATE_ENABLED_INACTIVE - * AdapterStateCallback#STATE_ENABLED_ACTIVE - * - * @return value representing current enabled/disabled state for UWB. - * @hide - */ - public @AdapterStateCallback.State int getAdapterState() { - return mAdapterStateListener.getAdapterState(); - } - - /** - * Disables or enables UWB for a user - * - * @param enabled value representing intent to disable or enable UWB. If true any subsequent - * calls to IUwbAdapter#openRanging will be allowed. If false, all active ranging sessions will - * be closed and subsequent calls to IUwbAdapter#openRanging will be disallowed. - * - * @hide - */ - public void setUwbEnabled(boolean enabled) { - mAdapterStateListener.setEnabled(enabled); - } -} diff --git a/core/tests/uwbtests/Android.bp b/core/tests/uwbtests/Android.bp deleted file mode 100644 index 31f446f7a60d7..0000000000000 --- a/core/tests/uwbtests/Android.bp +++ /dev/null @@ -1,38 +0,0 @@ -// 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "UwbManagerTests", - static_libs: [ - "androidx.test.ext.junit", - "androidx.test.rules", - "mockito-target-minus-junit4", - ], - libs: [ - "android.test.runner", - ], - srcs: ["src/**/*.java"], - platform_apis: true, - certificate: "platform", - test_suites: ["device-tests"], -} diff --git a/core/tests/uwbtests/AndroidManifest.xml b/core/tests/uwbtests/AndroidManifest.xml deleted file mode 100644 index dc991ff636d27..0000000000000 --- a/core/tests/uwbtests/AndroidManifest.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/core/tests/uwbtests/AndroidTest.xml b/core/tests/uwbtests/AndroidTest.xml deleted file mode 100644 index ff4b668cc6256..0000000000000 --- a/core/tests/uwbtests/AndroidTest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - diff --git a/core/tests/uwbtests/OWNERS b/core/tests/uwbtests/OWNERS deleted file mode 100644 index c7b09a21e1d06..0000000000000 --- a/core/tests/uwbtests/OWNERS +++ /dev/null @@ -1 +0,0 @@ -include /core/java/android/uwb/OWNERS diff --git a/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java b/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java deleted file mode 100644 index 4cad535a3a519..0000000000000 --- a/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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 static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - - -import android.os.RemoteException; -import android.uwb.UwbManager.AdapterStateCallback; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * Test of {@link AdapterStateListener}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class AdapterStateListenerTest { - - IUwbAdapter mUwbAdapter = mock(IUwbAdapter.class); - - Answer mRegisterSuccessAnswer = new Answer() { - public Object answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - IUwbAdapterStateCallbacks cb = (IUwbAdapterStateCallbacks) args[0]; - try { - cb.onAdapterStateChanged(AdapterState.STATE_DISABLED, StateChangeReason.UNKNOWN); - } catch (RemoteException e) { - // Nothing to do - } - return new Object(); - } - }; - - Throwable mThrowRemoteException = new RemoteException("RemoteException"); - - private static Executor getExecutor() { - return new Executor() { - @Override - public void execute(Runnable command) { - command.run(); - } - }; - } - - private static void verifyCallbackStateChangedInvoked( - AdapterStateCallback callback, int numTimes) { - verify(callback, times(numTimes)).onStateChanged(anyInt(), anyInt()); - } - - @Test - public void testRegister_RegisterUnregister() throws RemoteException { - doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any()); - - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback1 = mock(AdapterStateCallback.class); - AdapterStateCallback callback2 = mock(AdapterStateCallback.class); - - // Verify that the adapter state listener registered with the UWB Adapter - adapterStateListener.register(getExecutor(), callback1); - verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any()); - verifyCallbackStateChangedInvoked(callback1, 1); - verifyCallbackStateChangedInvoked(callback2, 0); - - // Register a second client and no new call to UWB Adapter - adapterStateListener.register(getExecutor(), callback2); - verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any()); - verifyCallbackStateChangedInvoked(callback1, 1); - verifyCallbackStateChangedInvoked(callback2, 1); - - // Unregister first callback - adapterStateListener.unregister(callback1); - verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any()); - verify(mUwbAdapter, times(0)).unregisterAdapterStateCallbacks(any()); - verifyCallbackStateChangedInvoked(callback1, 1); - verifyCallbackStateChangedInvoked(callback2, 1); - - // Unregister second callback - adapterStateListener.unregister(callback2); - verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any()); - verify(mUwbAdapter, times(1)).unregisterAdapterStateCallbacks(any()); - verifyCallbackStateChangedInvoked(callback1, 1); - verifyCallbackStateChangedInvoked(callback2, 1); - } - - @Test - public void testRegister_RegisterSameCallbackTwice() throws RemoteException { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback = mock(AdapterStateCallback.class); - doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any()); - - adapterStateListener.register(getExecutor(), callback); - verifyCallbackStateChangedInvoked(callback, 1); - - adapterStateListener.register(getExecutor(), callback); - verifyCallbackStateChangedInvoked(callback, 1); - - // Invoke a state change and ensure the callback is only called once - adapterStateListener.onAdapterStateChanged(AdapterState.STATE_DISABLED, - StateChangeReason.UNKNOWN); - verifyCallbackStateChangedInvoked(callback, 2); - } - - @Test - public void testCallback_RunViaExecutor_Success() throws RemoteException { - // Verify that the callbacks are invoked on the executor when successful - doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any()); - runViaExecutor(); - } - - private void runViaExecutor() { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback = mock(AdapterStateCallback.class); - - Executor executor = mock(Executor.class); - - // Do not run commands received and ensure that the callback is not invoked - doAnswer(new ExecutorAnswer(false)).when(executor).execute(any()); - adapterStateListener.register(executor, callback); - verify(executor, times(1)).execute(any()); - verifyCallbackStateChangedInvoked(callback, 0); - - // Manually invoke the callback and ensure callback is not invoked - adapterStateListener.onAdapterStateChanged(AdapterState.STATE_DISABLED, - StateChangeReason.UNKNOWN); - verify(executor, times(2)).execute(any()); - verifyCallbackStateChangedInvoked(callback, 0); - - // Run the command that the executor receives - doAnswer(new ExecutorAnswer(true)).when(executor).execute(any()); - adapterStateListener.onAdapterStateChanged(AdapterState.STATE_DISABLED, - StateChangeReason.UNKNOWN); - verify(executor, times(3)).execute(any()); - verifyCallbackStateChangedInvoked(callback, 1); - } - - class ExecutorAnswer implements Answer { - - final boolean mShouldRun; - ExecutorAnswer(boolean shouldRun) { - mShouldRun = shouldRun; - } - - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - if (mShouldRun) { - ((Runnable) invocation.getArgument(0)).run(); - } - return null; - } - } - - @Test - public void testNotify_AllCallbacksNotified() throws RemoteException { - doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any()); - - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - List callbacks = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - AdapterStateCallback callback = mock(AdapterStateCallback.class); - adapterStateListener.register(getExecutor(), callback); - callbacks.add(callback); - } - - // Ensure every callback got the initial state - for (AdapterStateCallback callback : callbacks) { - verifyCallbackStateChangedInvoked(callback, 1); - } - - // Invoke a state change and ensure all callbacks are invoked - adapterStateListener.onAdapterStateChanged(AdapterState.STATE_DISABLED, - StateChangeReason.ALL_SESSIONS_CLOSED); - for (AdapterStateCallback callback : callbacks) { - verifyCallbackStateChangedInvoked(callback, 2); - } - } - - @Test - public void testStateChange_CorrectValue() { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - - AdapterStateCallback callback = mock(AdapterStateCallback.class); - - adapterStateListener.register(getExecutor(), callback); - - runStateChangeValue(StateChangeReason.ALL_SESSIONS_CLOSED, - AdapterState.STATE_ENABLED_INACTIVE, - AdapterStateCallback.STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED, - AdapterStateCallback.STATE_ENABLED_INACTIVE); - - runStateChangeValue(StateChangeReason.SESSION_STARTED, AdapterState.STATE_ENABLED_ACTIVE, - AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED, - AdapterStateCallback.STATE_ENABLED_ACTIVE); - - runStateChangeValue(StateChangeReason.SYSTEM_BOOT, AdapterState.STATE_DISABLED, - AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT, - AdapterStateCallback.STATE_DISABLED); - - runStateChangeValue(StateChangeReason.SYSTEM_POLICY, AdapterState.STATE_DISABLED, - AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY, - AdapterStateCallback.STATE_DISABLED); - - runStateChangeValue(StateChangeReason.UNKNOWN, AdapterState.STATE_DISABLED, - AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN, - AdapterStateCallback.STATE_DISABLED); - } - - private void runStateChangeValue(@StateChangeReason int reasonIn, @AdapterState int stateIn, - @AdapterStateCallback.StateChangedReason int reasonOut, - @AdapterStateCallback.State int stateOut) { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback = mock(AdapterStateCallback.class); - adapterStateListener.register(getExecutor(), callback); - - adapterStateListener.onAdapterStateChanged(stateIn, reasonIn); - verify(callback, times(1)).onStateChanged(stateOut, reasonOut); - } - - @Test - public void testStateChange_FirstRegisterGetsCorrectState() throws RemoteException { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback = mock(AdapterStateCallback.class); - - Answer registerAnswer = new Answer() { - public Object answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - IUwbAdapterStateCallbacks cb = (IUwbAdapterStateCallbacks) args[0]; - try { - cb.onAdapterStateChanged(AdapterState.STATE_ENABLED_ACTIVE, - StateChangeReason.SESSION_STARTED); - } catch (RemoteException e) { - // Nothing to do - } - return new Object(); - } - }; - - doAnswer(registerAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any()); - - adapterStateListener.register(getExecutor(), callback); - verify(callback).onStateChanged(AdapterStateCallback.STATE_ENABLED_ACTIVE, - AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED); - } - - @Test - public void testStateChange_SecondRegisterGetsCorrectState() { - AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter); - AdapterStateCallback callback1 = mock(AdapterStateCallback.class); - AdapterStateCallback callback2 = mock(AdapterStateCallback.class); - - adapterStateListener.register(getExecutor(), callback1); - adapterStateListener.onAdapterStateChanged(AdapterState.STATE_ENABLED_ACTIVE, - StateChangeReason.SYSTEM_BOOT); - - adapterStateListener.register(getExecutor(), callback2); - verify(callback2).onStateChanged(AdapterStateCallback.STATE_ENABLED_ACTIVE, - AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java deleted file mode 100644 index 24267e46e9e21..0000000000000 --- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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 static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.content.AttributionSource; -import android.os.PersistableBundle; -import android.os.RemoteException; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; - -import java.util.concurrent.Executor; - -/** - * Test of {@link AdapterStateListener}. - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RangingManagerTest { - - private static final Executor EXECUTOR = UwbTestUtils.getExecutor(); - private static final PersistableBundle PARAMS = new PersistableBundle(); - private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN; - private static final int UID = 343453; - private static final String PACKAGE_NAME = "com.uwb.test"; - private static final AttributionSource ATTRIBUTION_SOURCE = - new AttributionSource.Builder(UID).setPackageName(PACKAGE_NAME).build(); - - @Test - public void testOpenSession_OpenRangingInvoked() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingManager rangingManager = new RangingManager(adapter); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), any(), any(), any()); - } - - @Test - public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingManager rangingManager = new RangingManager(adapter); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - - rangingManager.onRangingOpened(new SessionHandle(2)); - verify(callback, times(0)).onOpened(any()); - } - - @Test - public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession.Callback callback1 = mock(RangingSession.Callback.class); - RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - ArgumentCaptor sessionHandleCaptor = - ArgumentCaptor.forClass(SessionHandle.class); - - RangingManager rangingManager = new RangingManager(adapter); - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); - - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2); - verify(adapter, times(2)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); - - rangingManager.onRangingOpened(sessionHandle1); - verify(callback1, times(1)).onOpened(any()); - verify(callback2, times(0)).onOpened(any()); - - rangingManager.onRangingOpened(sessionHandle2); - verify(callback1, times(1)).onOpened(any()); - verify(callback2, times(1)).onOpened(any()); - } - - @Test - public void testCorrectCallbackInvoked() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingManager rangingManager = new RangingManager(adapter); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - - ArgumentCaptor sessionHandleCaptor = - ArgumentCaptor.forClass(SessionHandle.class); - - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle handle = sessionHandleCaptor.getValue(); - - rangingManager.onRangingOpened(handle); - verify(callback, times(1)).onOpened(any()); - - rangingManager.onRangingStarted(handle, PARAMS); - verify(callback, times(1)).onStarted(eq(PARAMS)); - - rangingManager.onRangingStartFailed(handle, REASON, PARAMS); - verify(callback, times(1)).onStartFailed(eq(REASON), eq(PARAMS)); - - RangingReport report = UwbTestUtils.getRangingReports(1); - rangingManager.onRangingResult(handle, report); - verify(callback, times(1)).onReportReceived(eq(report)); - - rangingManager.onRangingReconfigured(handle, PARAMS); - verify(callback, times(1)).onReconfigured(eq(PARAMS)); - - rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS); - verify(callback, times(1)).onReconfigureFailed(eq(REASON), eq(PARAMS)); - - rangingManager.onRangingStopped(handle, REASON, PARAMS); - verify(callback, times(1)).onStopped(eq(REASON), eq(PARAMS)); - - rangingManager.onRangingStopFailed(handle, REASON, PARAMS); - verify(callback, times(1)).onStopFailed(eq(REASON), eq(PARAMS)); - - rangingManager.onRangingClosed(handle, REASON, PARAMS); - verify(callback, times(1)).onClosed(eq(REASON), eq(PARAMS)); - } - - @Test - public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - // Verify that if multiple sessions are registered, only the session that is - // requested to close receives the associated callbacks - RangingSession.Callback callback1 = mock(RangingSession.Callback.class); - RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - - RangingManager rangingManager = new RangingManager(adapter); - ArgumentCaptor sessionHandleCaptor = - ArgumentCaptor.forClass(SessionHandle.class); - - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); - - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2); - verify(adapter, times(2)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); - - rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS); - verify(callback1, times(1)).onClosed(anyInt(), any()); - verify(callback2, times(0)).onClosed(anyInt(), any()); - - rangingManager.onRangingClosed(sessionHandle2, REASON, PARAMS); - verify(callback1, times(1)).onClosed(anyInt(), any()); - verify(callback2, times(1)).onClosed(anyInt(), any()); - } - - @Test - public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingSession.Callback callback1 = mock(RangingSession.Callback.class); - RangingSession.Callback callback2 = mock(RangingSession.Callback.class); - - ArgumentCaptor sessionHandleCaptor = - ArgumentCaptor.forClass(SessionHandle.class); - - RangingManager rangingManager = new RangingManager(adapter); - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback1); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle1 = sessionHandleCaptor.getValue(); - - rangingManager.onRangingStarted(sessionHandle1, PARAMS); - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback2); - verify(adapter, times(2)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle sessionHandle2 = sessionHandleCaptor.getValue(); - rangingManager.onRangingStarted(sessionHandle2, PARAMS); - - rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1)); - verify(callback1, times(1)).onReportReceived(any()); - verify(callback2, times(0)).onReportReceived(any()); - - rangingManager.onRangingResult(sessionHandle2, UwbTestUtils.getRangingReports(1)); - verify(callback1, times(1)).onReportReceived(any()); - verify(callback2, times(1)).onReportReceived(any()); - } - - @Test - public void testReasons() throws RemoteException { - runReason(RangingChangeReason.LOCAL_API, - RangingSession.Callback.REASON_LOCAL_REQUEST); - - runReason(RangingChangeReason.MAX_SESSIONS_REACHED, - RangingSession.Callback.REASON_MAX_SESSIONS_REACHED); - - runReason(RangingChangeReason.PROTOCOL_SPECIFIC, - RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR); - - runReason(RangingChangeReason.REMOTE_REQUEST, - RangingSession.Callback.REASON_REMOTE_REQUEST); - - runReason(RangingChangeReason.SYSTEM_POLICY, - RangingSession.Callback.REASON_SYSTEM_POLICY); - - runReason(RangingChangeReason.BAD_PARAMETERS, - RangingSession.Callback.REASON_BAD_PARAMETERS); - - runReason(RangingChangeReason.UNKNOWN, - RangingSession.Callback.REASON_UNKNOWN); - } - - private void runReason(@RangingChangeReason int reasonIn, - @RangingSession.Callback.Reason int reasonOut) throws RemoteException { - IUwbAdapter adapter = mock(IUwbAdapter.class); - RangingManager rangingManager = new RangingManager(adapter); - RangingSession.Callback callback = mock(RangingSession.Callback.class); - - ArgumentCaptor sessionHandleCaptor = - ArgumentCaptor.forClass(SessionHandle.class); - - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback); - verify(adapter, times(1)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - SessionHandle handle = sessionHandleCaptor.getValue(); - - rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS); - verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS)); - - // Open a new session - rangingManager.openSession(ATTRIBUTION_SOURCE, PARAMS, EXECUTOR, callback); - verify(adapter, times(2)).openRanging( - eq(ATTRIBUTION_SOURCE), sessionHandleCaptor.capture(), any(), any()); - handle = sessionHandleCaptor.getValue(); - rangingManager.onRangingOpened(handle); - - rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS); - verify(callback, times(1)).onStartFailed(eq(reasonOut), eq(PARAMS)); - - rangingManager.onRangingReconfigureFailed(handle, reasonIn, PARAMS); - verify(callback, times(1)).onReconfigureFailed(eq(reasonOut), eq(PARAMS)); - - rangingManager.onRangingStopFailed(handle, reasonIn, PARAMS); - verify(callback, times(1)).onStopFailed(eq(reasonOut), eq(PARAMS)); - - rangingManager.onRangingClosed(handle, reasonIn, PARAMS); - verify(callback, times(1)).onClosed(eq(reasonOut), eq(PARAMS)); - } -} diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java deleted file mode 100644 index 75c6924a19395..0000000000000 --- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.os.SystemClock; - -import java.util.concurrent.Executor; - -public class UwbTestUtils { - private UwbTestUtils() {} - - public static AngleMeasurement getAngleMeasurement() { - return new AngleMeasurement( - getDoubleInRange(-Math.PI, Math.PI), - getDoubleInRange(0, Math.PI), - getDoubleInRange(0, 1)); - } - - public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() { - return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement()) - .setAltitude(getAngleMeasurement()) - .build(); - } - - public static DistanceMeasurement getDistanceMeasurement() { - return new DistanceMeasurement.Builder() - .setMeters(getDoubleInRange(0, 100)) - .setErrorMeters(getDoubleInRange(0, 10)) - .setConfidenceLevel(getDoubleInRange(0, 1)) - .build(); - } - - public static RangingMeasurement getRangingMeasurement() { - return getRangingMeasurement(getUwbAddress(false)); - } - - public static RangingMeasurement getRangingMeasurement(UwbAddress address) { - return new RangingMeasurement.Builder() - .setDistanceMeasurement(getDistanceMeasurement()) - .setAngleOfArrivalMeasurement(getAngleOfArrivalMeasurement()) - .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()) - .setRemoteDeviceAddress(address != null ? address : getUwbAddress(false)) - .setStatus(RangingMeasurement.RANGING_STATUS_SUCCESS) - .build(); - } - - public static RangingReport getRangingReports(int numMeasurements) { - RangingReport.Builder builder = new RangingReport.Builder(); - for (int i = 0; i < numMeasurements; i++) { - builder.addMeasurement(getRangingMeasurement()); - } - return builder.build(); - } - - private static double getDoubleInRange(double min, double max) { - return min + (max - min) * Math.random(); - } - - public static UwbAddress getUwbAddress(boolean isShortAddress) { - byte[] addressBytes = new byte[isShortAddress ? UwbAddress.SHORT_ADDRESS_BYTE_LENGTH : - UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH]; - for (int i = 0; i < addressBytes.length; i++) { - addressBytes[i] = (byte) getDoubleInRange(1, 255); - } - return UwbAddress.fromBytes(addressBytes); - } - - public static Executor getExecutor() { - return new Executor() { - @Override - public void execute(Runnable command) { - command.run(); - } - }; - } -}