• 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.annotation.NonNull;
20 import android.content.AttributionSource;
21 import android.os.CancellationSignal;
22 import android.os.PersistableBundle;
23 import android.os.RemoteException;
24 import android.util.Log;
25 
26 import java.util.Hashtable;
27 import java.util.concurrent.Executor;
28 
29 /**
30  * @hide
31  */
32 public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
33     private static final String TAG = "Uwb.RangingManager";
34 
35     private final IUwbAdapter mAdapter;
36     private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
37     private int mNextSessionId = 1;
38 
RangingManager(IUwbAdapter adapter)39     public RangingManager(IUwbAdapter adapter) {
40         mAdapter = adapter;
41     }
42 
43     /**
44      * Open a new ranging session
45      *
46      * @param attributionSource Attribution source to use for the enforcement of
47      *                          {@link android.Manifest.permission#ULTRAWIDEBAND_RANGING} runtime
48      *                          permission.
49      * @param params the parameters that define the ranging session
50      * @param executor {@link Executor} to run callbacks
51      * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
52      *                  that is being opened.
53      * @return a {@link CancellationSignal} that may be used to cancel the opening of the
54      *         {@link RangingSession}.
55      */
openSession(@onNull AttributionSource attributionSource, @NonNull PersistableBundle params, @NonNull Executor executor, @NonNull RangingSession.Callback callbacks)56     public CancellationSignal openSession(@NonNull AttributionSource attributionSource,
57             @NonNull PersistableBundle params,
58             @NonNull Executor executor,
59             @NonNull RangingSession.Callback callbacks) {
60         synchronized (this) {
61             SessionHandle sessionHandle = new SessionHandle(mNextSessionId++);
62             RangingSession session =
63                     new RangingSession(executor, callbacks, mAdapter, sessionHandle);
64             mRangingSessionTable.put(sessionHandle, session);
65             try {
66                 mAdapter.openRanging(attributionSource, sessionHandle, this, params);
67             } catch (RemoteException e) {
68                 throw e.rethrowFromSystemServer();
69             }
70 
71             CancellationSignal cancellationSignal = new CancellationSignal();
72             cancellationSignal.setOnCancelListener(() -> session.close());
73             return cancellationSignal;
74         }
75     }
76 
hasSession(SessionHandle sessionHandle)77     private boolean hasSession(SessionHandle sessionHandle) {
78         return mRangingSessionTable.containsKey(sessionHandle);
79     }
80 
81     @Override
onRangingOpened(SessionHandle sessionHandle)82     public void onRangingOpened(SessionHandle sessionHandle) {
83         synchronized (this) {
84             if (!hasSession(sessionHandle)) {
85                 Log.w(TAG,
86                         "onRangingOpened - received unexpected SessionHandle: " + sessionHandle);
87                 return;
88             }
89 
90             RangingSession session = mRangingSessionTable.get(sessionHandle);
91             session.onRangingOpened();
92         }
93     }
94 
95     @Override
onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)96     public void onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
97             PersistableBundle parameters) {
98         synchronized (this) {
99             if (!hasSession(sessionHandle)) {
100                 Log.w(TAG,
101                         "onRangingOpenedFailed - received unexpected SessionHandle: "
102                                 + sessionHandle);
103                 return;
104             }
105 
106             RangingSession session = mRangingSessionTable.get(sessionHandle);
107             session.onRangingOpenFailed(convertToReason(reason), parameters);
108             mRangingSessionTable.remove(sessionHandle);
109         }
110     }
111 
112     @Override
onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters)113     public void onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters) {
114         synchronized (this) {
115             if (!hasSession(sessionHandle)) {
116                 Log.w(TAG,
117                         "onRangingReconfigured - received unexpected SessionHandle: "
118                                 + sessionHandle);
119                 return;
120             }
121 
122             RangingSession session = mRangingSessionTable.get(sessionHandle);
123             session.onRangingReconfigured(parameters);
124         }
125     }
126 
127     @Override
onRangingReconfigureFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)128     public void onRangingReconfigureFailed(SessionHandle sessionHandle,
129             @RangingChangeReason int reason, PersistableBundle params) {
130         synchronized (this) {
131             if (!hasSession(sessionHandle)) {
132                 Log.w(TAG, "onRangingReconfigureFailed - received unexpected SessionHandle: "
133                         + sessionHandle);
134                 return;
135             }
136 
137             RangingSession session = mRangingSessionTable.get(sessionHandle);
138             session.onRangingReconfigureFailed(convertToReason(reason), params);
139         }
140     }
141 
142 
143     @Override
onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters)144     public void onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters) {
145         synchronized (this) {
146             if (!hasSession(sessionHandle)) {
147                 Log.w(TAG,
148                         "onRangingStarted - received unexpected SessionHandle: " + sessionHandle);
149                 return;
150             }
151 
152             RangingSession session = mRangingSessionTable.get(sessionHandle);
153             session.onRangingStarted(parameters);
154         }
155     }
156 
157     @Override
onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)158     public void onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
159             PersistableBundle params) {
160         synchronized (this) {
161             if (!hasSession(sessionHandle)) {
162                 Log.w(TAG, "onRangingStartFailed - received unexpected SessionHandle: "
163                         + sessionHandle);
164                 return;
165             }
166 
167             RangingSession session = mRangingSessionTable.get(sessionHandle);
168             session.onRangingStartFailed(convertToReason(reason), params);
169         }
170     }
171 
172     @Override
onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)173     public void onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason,
174             PersistableBundle params) {
175         synchronized (this) {
176             if (!hasSession(sessionHandle)) {
177                 Log.w(TAG, "onRangingStopped - received unexpected SessionHandle: "
178                         + sessionHandle);
179                 return;
180             }
181 
182             RangingSession session = mRangingSessionTable.get(sessionHandle);
183             session.onRangingStopped(convertToReason(reason), params);
184         }
185     }
186 
187     @Override
onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)188     public void onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
189             PersistableBundle parameters) {
190         synchronized (this) {
191             if (!hasSession(sessionHandle)) {
192                 Log.w(TAG, "onRangingStopFailed - received unexpected SessionHandle: "
193                         + sessionHandle);
194                 return;
195             }
196 
197             RangingSession session = mRangingSessionTable.get(sessionHandle);
198             session.onRangingStopFailed(convertToReason(reason), parameters);
199         }
200     }
201 
202     @Override
onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)203     public void onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason,
204             PersistableBundle params) {
205         synchronized (this) {
206             if (!hasSession(sessionHandle)) {
207                 Log.w(TAG, "onRangingClosed - received unexpected SessionHandle: " + sessionHandle);
208                 return;
209             }
210 
211             RangingSession session = mRangingSessionTable.get(sessionHandle);
212             session.onRangingClosed(convertToReason(reason), params);
213             mRangingSessionTable.remove(sessionHandle);
214         }
215     }
216 
217     @Override
onRangingResult(SessionHandle sessionHandle, RangingReport result)218     public void onRangingResult(SessionHandle sessionHandle, RangingReport result) {
219         synchronized (this) {
220             if (!hasSession(sessionHandle)) {
221                 Log.w(TAG, "onRangingResult - received unexpected SessionHandle: " + sessionHandle);
222                 return;
223             }
224 
225             RangingSession session = mRangingSessionTable.get(sessionHandle);
226             session.onRangingResult(result);
227         }
228     }
229 
230     @RangingSession.Callback.Reason
convertToReason(@angingChangeReason int reason)231     private static int convertToReason(@RangingChangeReason int reason) {
232         switch (reason) {
233             case RangingChangeReason.LOCAL_API:
234                 return RangingSession.Callback.REASON_LOCAL_REQUEST;
235 
236             case RangingChangeReason.MAX_SESSIONS_REACHED:
237                 return RangingSession.Callback.REASON_MAX_SESSIONS_REACHED;
238 
239             case RangingChangeReason.SYSTEM_POLICY:
240                 return RangingSession.Callback.REASON_SYSTEM_POLICY;
241 
242             case RangingChangeReason.REMOTE_REQUEST:
243                 return RangingSession.Callback.REASON_REMOTE_REQUEST;
244 
245             case RangingChangeReason.PROTOCOL_SPECIFIC:
246                 return RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR;
247 
248             case RangingChangeReason.BAD_PARAMETERS:
249                 return RangingSession.Callback.REASON_BAD_PARAMETERS;
250 
251             case RangingChangeReason.UNKNOWN:
252             default:
253                 return RangingSession.Callback.REASON_UNKNOWN;
254         }
255     }
256 }
257