• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.uwb;
18 
19 import android.Manifest.permission;
20 import android.annotation.CallbackExecutor;
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SuppressLint;
25 import android.annotation.SystemApi;
26 import android.annotation.SystemService;
27 import android.content.Context;
28 import android.os.CancellationSignal;
29 import android.os.IBinder;
30 import android.os.PersistableBundle;
31 import android.os.RemoteException;
32 import android.os.ServiceManager;
33 
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.util.concurrent.Executor;
37 
38 /**
39  * This class provides a way to perform Ultra Wideband (UWB) operations such as querying the
40  * device's capabilities and determining the distance and angle between the local device and a
41  * remote device.
42  *
43  * <p>To get a {@link UwbManager}, call the <code>Context.getSystemService(UwbManager.class)</code>.
44  *
45  * @hide
46  */
47 @SystemApi
48 @SystemService(Context.UWB_SERVICE)
49 public final class UwbManager {
50     private static final String SERVICE_NAME = Context.UWB_SERVICE;
51 
52     private final Context mContext;
53     private final IUwbAdapter mUwbAdapter;
54     private final AdapterStateListener mAdapterStateListener;
55     private final RangingManager mRangingManager;
56 
57     /**
58      * Interface for receiving UWB adapter state changes
59      */
60     public interface AdapterStateCallback {
61         /**
62          * @hide
63          */
64         @Retention(RetentionPolicy.SOURCE)
65         @IntDef(value = {
66                 STATE_CHANGED_REASON_SESSION_STARTED,
67                 STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED,
68                 STATE_CHANGED_REASON_SYSTEM_POLICY,
69                 STATE_CHANGED_REASON_SYSTEM_BOOT,
70                 STATE_CHANGED_REASON_ERROR_UNKNOWN})
71         @interface StateChangedReason {}
72 
73         /**
74          * @hide
75          */
76         @Retention(RetentionPolicy.SOURCE)
77         @IntDef(value = {
78                 STATE_ENABLED_INACTIVE,
79                 STATE_ENABLED_ACTIVE,
80                 STATE_DISABLED})
81         @interface State {}
82 
83         /**
84          * Indicates that the state change was due to opening of first UWB session
85          */
86         int STATE_CHANGED_REASON_SESSION_STARTED = 0;
87 
88         /**
89          * Indicates that the state change was due to closure of all UWB sessions
90          */
91         int STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED = 1;
92 
93         /**
94          * Indicates that the state change was due to changes in system policy
95          */
96         int STATE_CHANGED_REASON_SYSTEM_POLICY = 2;
97 
98         /**
99          * Indicates that the current state is due to a system boot
100          */
101         int STATE_CHANGED_REASON_SYSTEM_BOOT = 3;
102 
103         /**
104          * Indicates that the state change was due to some unknown error
105          */
106         int STATE_CHANGED_REASON_ERROR_UNKNOWN = 4;
107 
108         /**
109          * Indicates that UWB is disabled on device
110          */
111         int STATE_DISABLED = 0;
112         /**
113          * Indicates that UWB is enabled on device but has no active ranging sessions
114          */
115         int STATE_ENABLED_INACTIVE = 1;
116 
117         /**
118          * Indicates that UWB is enabled and has active ranging session
119          */
120         int STATE_ENABLED_ACTIVE = 2;
121 
122         /**
123          * Invoked when underlying UWB adapter's state is changed
124          * <p>Invoked with the adapter's current state after registering an
125          * {@link AdapterStateCallback} using
126          * {@link UwbManager#registerAdapterStateCallback(Executor, AdapterStateCallback)}.
127          *
128          * <p>Possible reasons for the state to change are
129          * {@link #STATE_CHANGED_REASON_SESSION_STARTED},
130          * {@link #STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED},
131          * {@link #STATE_CHANGED_REASON_SYSTEM_POLICY},
132          * {@link #STATE_CHANGED_REASON_SYSTEM_BOOT},
133          * {@link #STATE_CHANGED_REASON_ERROR_UNKNOWN}.
134          *
135          * <p>Possible values for the UWB state are
136          * {@link #STATE_ENABLED_INACTIVE},
137          * {@link #STATE_ENABLED_ACTIVE},
138          * {@link #STATE_DISABLED}.
139          *
140          * @param state the UWB state; inactive, active or disabled
141          * @param reason the reason for the state change
142          */
onStateChanged(@tate int state, @StateChangedReason int reason)143         void onStateChanged(@State int state, @StateChangedReason int reason);
144     }
145 
146     /**
147      * Use <code>Context.getSystemService(UwbManager.class)</code> to get an instance.
148      *
149      * @param ctx Context of the client.
150      * @param adapter an instance of an {@link android.uwb.IUwbAdapter}
151      */
UwbManager(@onNull Context ctx, @NonNull IUwbAdapter adapter)152     private UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) {
153         mContext = ctx;
154         mUwbAdapter = adapter;
155         mAdapterStateListener = new AdapterStateListener(adapter);
156         mRangingManager = new RangingManager(adapter);
157     }
158 
159     /**
160      * @hide
161      */
getInstance(@onNull Context ctx)162     public static UwbManager getInstance(@NonNull Context ctx) {
163         IBinder b = ServiceManager.getService(SERVICE_NAME);
164         if (b == null) {
165             return null;
166         }
167 
168         IUwbAdapter adapter = IUwbAdapter.Stub.asInterface(b);
169         if (adapter == null) {
170             return null;
171         }
172 
173         return new UwbManager(ctx, adapter);
174     }
175 
176     /**
177      * Register an {@link AdapterStateCallback} to listen for UWB adapter state changes
178      * <p>The provided callback will be invoked by the given {@link Executor}.
179      *
180      * <p>When first registering a callback, the callbacks's
181      * {@link AdapterStateCallback#onStateChanged(int, int)} is immediately invoked to indicate
182      * the current state of the underlying UWB adapter with the most recent
183      * {@link AdapterStateCallback.StateChangedReason} that caused the change.
184      *
185      * @param executor an {@link Executor} to execute given callback
186      * @param callback user implementation of the {@link AdapterStateCallback}
187      */
188     @RequiresPermission(permission.UWB_PRIVILEGED)
registerAdapterStateCallback(@onNull @allbackExecutor Executor executor, @NonNull AdapterStateCallback callback)189     public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
190             @NonNull AdapterStateCallback callback) {
191         mAdapterStateListener.register(executor, callback);
192     }
193 
194     /**
195      * Unregister the specified {@link AdapterStateCallback}
196      * <p>The same {@link AdapterStateCallback} object used when calling
197      * {@link #registerAdapterStateCallback(Executor, AdapterStateCallback)} must be used.
198      *
199      * <p>Callbacks are automatically unregistered when application process goes away
200      *
201      * @param callback user implementation of the {@link AdapterStateCallback}
202      */
203     @RequiresPermission(permission.UWB_PRIVILEGED)
unregisterAdapterStateCallback(@onNull AdapterStateCallback callback)204     public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
205         mAdapterStateListener.unregister(callback);
206     }
207 
208     /**
209      * Get a {@link PersistableBundle} with the supported UWB protocols and parameters.
210      * <p>The {@link PersistableBundle} should be parsed using a support library
211      *
212      * <p>Android reserves the '^android.*' namespace</p>
213      *
214      * @return {@link PersistableBundle} of the device's supported UWB protocols and parameters
215      */
216     @NonNull
217     @RequiresPermission(permission.UWB_PRIVILEGED)
getSpecificationInfo()218     public PersistableBundle getSpecificationInfo() {
219         try {
220             return mUwbAdapter.getSpecificationInfo();
221         } catch (RemoteException e) {
222             throw e.rethrowFromSystemServer();
223         }
224     }
225 
226     /**
227      * Get the timestamp resolution for events in nanoseconds
228      * <p>This value defines the maximum error of all timestamps for events reported to
229      * {@link RangingSession.Callback}.
230      *
231      * @return the timestamp resolution in nanoseconds
232      */
233     @SuppressLint("MethodNameUnits")
234     @RequiresPermission(permission.UWB_PRIVILEGED)
elapsedRealtimeResolutionNanos()235     public long elapsedRealtimeResolutionNanos() {
236         try {
237             return mUwbAdapter.getTimestampResolutionNanos();
238         } catch (RemoteException e) {
239             throw e.rethrowFromSystemServer();
240         }
241     }
242 
243     /**
244      * Open a {@link RangingSession} with the given parameters
245      * <p>The {@link RangingSession.Callback#onOpened(RangingSession)} function is called with a
246      * {@link RangingSession} object used to control ranging when the session is successfully
247      * opened.
248      *
249      * <p>If a session cannot be opened, then
250      * {@link RangingSession.Callback#onClosed(int, PersistableBundle)} will be invoked with the
251      * appropriate {@link RangingSession.Callback.Reason}.
252      *
253      * <p>An open {@link RangingSession} will be automatically closed if client application process
254      * dies.
255      *
256      * <p>A UWB support library must be used in order to construct the {@code parameter}
257      * {@link PersistableBundle}.
258      *
259      * @param parameters the parameters that define the ranging session
260      * @param executor {@link Executor} to run callbacks
261      * @param callbacks {@link RangingSession.Callback} to associate with the
262      *                  {@link RangingSession} that is being opened.
263      *
264      * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a
265      *         {@link RangingSession} that has been requested through {@link #openRangingSession}
266      *         but has not yet been made available by
267      *         {@link RangingSession.Callback#onOpened(RangingSession)}.
268      */
269     @NonNull
270     @RequiresPermission(allOf = {
271             permission.UWB_PRIVILEGED,
272             permission.UWB_RANGING
273     })
openRangingSession(@onNull PersistableBundle parameters, @NonNull @CallbackExecutor Executor executor, @NonNull RangingSession.Callback callbacks)274     public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
275             @NonNull @CallbackExecutor Executor executor,
276             @NonNull RangingSession.Callback callbacks) {
277         return mRangingManager.openSession(
278                 mContext.getAttributionSource(), parameters, executor, callbacks);
279     }
280 
281     /**
282      * Returns the current enabled/disabled state for UWB.
283      *
284      * Possible values are:
285      * AdapterStateCallback#STATE_DISABLED
286      * AdapterStateCallback#STATE_ENABLED_INACTIVE
287      * AdapterStateCallback#STATE_ENABLED_ACTIVE
288      *
289      * @return value representing current enabled/disabled state for UWB.
290      * @hide
291      */
getAdapterState()292     public @AdapterStateCallback.State int getAdapterState() {
293         return mAdapterStateListener.getAdapterState();
294     }
295 
296     /**
297      * Disables or enables UWB for a user
298      *
299      * @param enabled value representing intent to disable or enable UWB. If true any subsequent
300      * calls to IUwbAdapter#openRanging will be allowed. If false, all active ranging sessions will
301      * be closed and subsequent calls to IUwbAdapter#openRanging will be disallowed.
302      *
303      * @hide
304      */
setUwbEnabled(boolean enabled)305     public void setUwbEnabled(boolean enabled) {
306         mAdapterStateListener.setEnabled(enabled);
307     }
308 }
309