summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2020-11-19 02:27:02 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2020-11-19 02:27:02 +0000
commitf5ccd5fa5df1ac087d7cd9efb4eac2467c2aa38b (patch)
treeb980fa01c4078ec0e303f80b948ad6e9bb6eb103
parentb9e490b673201b3ba444d57ba3f806477b01b79b (diff)
parent6a13b9492b870797cdf7217833b4cec176272fc1 (diff)
Merge "Add UWB AIDL" am: 6bf6e05d47 am: d6362ce402 am: fd095b500e am: 6a13b9492b
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1486140 Change-Id: I1e68a47302201b44fea20d154bc6cc539b97c47a
-rw-r--r--core/java/android/uwb/AngleOfArrivalSupport.aidl44
-rw-r--r--core/java/android/uwb/CloseReason.aidl58
-rw-r--r--core/java/android/uwb/IUwbAdapter.aidl170
-rw-r--r--core/java/android/uwb/IUwbAdapterStateCallbacks.aidl32
-rw-r--r--core/java/android/uwb/IUwbRangingCallbacks.aidl73
-rw-r--r--core/java/android/uwb/MeasurementStatus.aidl39
-rw-r--r--core/java/android/uwb/RangingReport.aidl19
-rw-r--r--core/java/android/uwb/SessionHandle.aidl19
-rw-r--r--core/java/android/uwb/SessionHandle.java79
-rw-r--r--core/java/android/uwb/StartFailureReason.aidl52
-rw-r--r--core/java/android/uwb/StateChangeReason.aidl45
-rw-r--r--core/java/android/uwb/UwbAddress.aidl19
-rw-r--r--core/tests/uwbtests/src/android/uwb/SessionHandleTest.java52
13 files changed, 701 insertions, 0 deletions
diff --git a/core/java/android/uwb/AngleOfArrivalSupport.aidl b/core/java/android/uwb/AngleOfArrivalSupport.aidl
new file mode 100644
index 000000000000..57666ff8bca9
--- /dev/null
+++ b/core/java/android/uwb/AngleOfArrivalSupport.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 AngleOfArrivalSupport {
+ /**
+ * The device does not support angle of arrival
+ */
+ NONE,
+
+ /**
+ * The device supports planar angle of arrival
+ */
+ TWO_DIMENSIONAL,
+
+ /**
+ * The device does supports three dimensional angle of arrival with hemispherical azimuth angles
+ */
+ THREE_DIMENSIONAL_HEMISPHERICAL,
+
+ /**
+ * The device does supports three dimensional angle of arrival with full azimuth angles
+ */
+ THREE_DIMENSIONAL_SPHERICAL,
+}
+
diff --git a/core/java/android/uwb/CloseReason.aidl b/core/java/android/uwb/CloseReason.aidl
new file mode 100644
index 000000000000..bef129e2c1c7
--- /dev/null
+++ b/core/java/android/uwb/CloseReason.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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 CloseReason {
+ /**
+ * Unknown reason
+ */
+ UNKNOWN,
+
+ /**
+ * A local API call triggered the close, such as a call to
+ * IUwbAdapter.stopRanging.
+ */
+ LOCAL_API,
+
+ /**
+ * The maximum number of sessions has been reached. This error 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 ending (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 terminate the session
+ */
+ REMOTE_REQUEST,
+
+ /**
+ * The session was closed for a protocol specific reason
+ */
+ PROTOCOL_SPECIFIC,
+}
+
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
new file mode 100644
index 000000000000..d29ed34804f1
--- /dev/null
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -0,0 +1,170 @@
+/*
+ * 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.AngleOfArrivalSupport;
+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);
+
+ /**
+ * Returns true if ranging is supported, false otherwise
+ */
+ boolean isRangingSupported();
+
+ /**
+ * Get the angle of arrival supported by this device
+ *
+ * @return the angle of arrival type supported
+ */
+ AngleOfArrivalSupport getAngleOfArrivalSupport();
+
+ /**
+ * Generates a list of the supported 802.15.4z channels
+ *
+ * The list must be prioritized in the order of preferred channel usage.
+ *
+ * The list must only contain channels that are permitted to be used in the
+ * device's current location.
+ *
+ * @return an array of support channels on the device for the current location.
+ */
+ int[] getSupportedChannels();
+
+ /**
+ * Generates a list of the supported 802.15.4z preamble codes
+ *
+ * The list must be prioritized in the order of preferred preamble usage.
+ *
+ * The list must only contain preambles that are permitted to be used in the
+ * device's current location.
+ *
+ * @return an array of supported preambles on the device for the current
+ * location.
+ */
+ int[] getSupportedPreambleCodes();
+
+ /**
+ * Get the accuracy of the ranging timestamps
+ *
+ * @return accuracy of the ranging timestamps in nanoseconds
+ */
+ long getTimestampResolutionNanos();
+
+ /**
+ * Get the supported number of simultaneous ranging sessions
+ *
+ * @return the supported number of simultaneous ranging sessions
+ */
+ int getMaxSimultaneousSessions();
+
+ /**
+ * Get the maximum number of remote devices per session
+ *
+ * @return the maximum number of remote devices supported in a single session
+ */
+ int getMaxRemoteDevicesPerSession();
+
+ /**
+ * Provides the capabilities and features of the device
+ *
+ * @return specification specific capabilities and features of the device
+ */
+ PersistableBundle getSpecificationInfo();
+
+ /**
+ * Request to start a new ranging session
+ *
+ * This function must return before calling IUwbAdapterCallbacks
+ * #onRangingStarted, #onRangingClosed, or #onRangingResult.
+ *
+ * A ranging session does not need to be started before returning.
+ *
+ * IUwbAdapterCallbacks#onRangingStarted must be called within
+ * RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being called
+ * if the ranging session is scheduled to start successfully.
+ *
+ * IUwbAdapterCallbacks#onRangingStartFailed must be called within
+ * RANGING_SESSION_START_THRESHOLD_MS milliseconds of #startRanging being called
+ * if the ranging session fails to be scheduled to start successfully.
+ *
+ * @param rangingCallbacks the callbacks used to deliver ranging information
+ * @param parameters the configuration to use for ranging
+ * @return a SessionHandle used to identify this ranging request
+ */
+ SessionHandle startRanging(in IUwbRangingCallbacks rangingCallbacks,
+ in PersistableBundle parameters);
+
+ /**
+ * Stop and 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 #stopRanging being called.
+ *
+ * @param sessionHandle the session handle to stop ranging for
+ */
+ void closeRanging(in SessionHandle sessionHandle);
+
+ /**
+ * 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
+
+ /**
+ * Ranging scheduling time unit (RSTU) for High Rate Pulse (HRP) PHY
+ */
+ const int HIGH_RATE_PULSE_CHIRPS_PER_RSTU = 416;
+
+ /**
+ * Ranging scheduling time unit (RSTU) for Low Rate Pulse (LRP) PHY
+ */
+ const int LOW_RATE_PULSE_CHIRPS_PER_RSTU = 1;
+}
diff --git a/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl b/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl
new file mode 100644
index 000000000000..d928eabae465
--- /dev/null
+++ b/core/java/android/uwb/IUwbAdapterStateCallbacks.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * @hide
+ */
+interface IUwbAdapterStateCallbacks {
+ /**
+ * Called whenever the adapter state changes
+ *
+ * @param isEnabled true if the adapter is enabled, false otherwise
+ * @param reason the reason that the state has changed
+ */
+ void onAdapterStateChanged(boolean isEnabled, StateChangeReason reason);
+} \ No newline at end of file
diff --git a/core/java/android/uwb/IUwbRangingCallbacks.aidl b/core/java/android/uwb/IUwbRangingCallbacks.aidl
new file mode 100644
index 000000000000..1fc3bfd818c3
--- /dev/null
+++ b/core/java/android/uwb/IUwbRangingCallbacks.aidl
@@ -0,0 +1,73 @@
+/*
+ * 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.CloseReason;
+import android.uwb.RangingReport;
+import android.uwb.SessionHandle;
+import android.uwb.StartFailureReason;
+
+/**
+ * @hide
+ */
+interface IUwbRangingCallbacks {
+ /**
+ * 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, StartFailureReason 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, CloseReason 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
new file mode 100644
index 000000000000..5fa15549e84d
--- /dev/null
+++ b/core/java/android/uwb/MeasurementStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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/RangingReport.aidl b/core/java/android/uwb/RangingReport.aidl
new file mode 100644
index 000000000000..c32747ae58da
--- /dev/null
+++ b/core/java/android/uwb/RangingReport.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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/SessionHandle.aidl b/core/java/android/uwb/SessionHandle.aidl
new file mode 100644
index 000000000000..58a7dbb2ef9f
--- /dev/null
+++ b/core/java/android/uwb/SessionHandle.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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
new file mode 100644
index 000000000000..928fcbdcf1c7
--- /dev/null
+++ b/core/java/android/uwb/SessionHandle.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+/**
+ * @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<SessionHandle> CREATOR = new Creator<SessionHandle>() {
+ @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 String toString() {
+ return "SessionHandle [id=" + mId + "]";
+ }
+}
diff --git a/core/java/android/uwb/StartFailureReason.aidl b/core/java/android/uwb/StartFailureReason.aidl
new file mode 100644
index 000000000000..4d9c962f529b
--- /dev/null
+++ b/core/java/android/uwb/StartFailureReason.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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 StartFailureReason {
+ /**
+ * Unknown start failure reason
+ */
+ UNKNOWN,
+
+ /**
+ * The provided parameters were invalid and ranging could not start
+ */
+ BAD_PARAMETERS,
+
+ /**
+ * The maximum number of sessions has been reached. This error 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 ending (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 session could not start because of a protocol specific reason.
+ */
+ PROTOCOL_SPECIFIC,
+}
+
diff --git a/core/java/android/uwb/StateChangeReason.aidl b/core/java/android/uwb/StateChangeReason.aidl
new file mode 100644
index 000000000000..46a6e2edfa22
--- /dev/null
+++ b/core/java/android/uwb/StateChangeReason.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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,
+}
+
diff --git a/core/java/android/uwb/UwbAddress.aidl b/core/java/android/uwb/UwbAddress.aidl
new file mode 100644
index 000000000000..a202b1a1f51d
--- /dev/null
+++ b/core/java/android/uwb/UwbAddress.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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/tests/uwbtests/src/android/uwb/SessionHandleTest.java b/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java
new file mode 100644
index 000000000000..8b42ff7f62a7
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link SessionHandle}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SessionHandleTest {
+
+ @Test
+ public void testBasic() {
+ int handleId = 12;
+ SessionHandle handle = new SessionHandle(handleId);
+ assertEquals(handle.getId(), handleId);
+ }
+
+ @Test
+ public void testParcel() {
+ Parcel parcel = Parcel.obtain();
+ SessionHandle handle = new SessionHandle(10);
+ handle.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ SessionHandle fromParcel = SessionHandle.CREATOR.createFromParcel(parcel);
+ assertEquals(handle, fromParcel);
+ }
+}