• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.bluetooth.le;
18 
19 import static android.Manifest.permission.BLUETOOTH_CONNECT;
20 import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
21 import static android.bluetooth.BluetoothUtils.executeFromBinder;
22 
23 import static java.util.Objects.requireNonNull;
24 
25 import android.annotation.IntDef;
26 import android.annotation.NonNull;
27 import android.annotation.RequiresPermission;
28 import android.annotation.SystemApi;
29 import android.bluetooth.BluetoothDevice;
30 import android.bluetooth.BluetoothStatusCodes;
31 import android.bluetooth.IDistanceMeasurement;
32 import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
33 import android.content.AttributionSource;
34 import android.os.ParcelUuid;
35 import android.os.RemoteException;
36 import android.util.Log;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.RetentionPolicy;
40 import java.util.concurrent.Executor;
41 
42 /**
43  * This class provides a way to control an active distance measurement session.
44  *
45  * <p>It also defines the required {@link DistanceMeasurementSession.Callback} that must be
46  * implemented in order to be notified of distance measurement results and status events related to
47  * the {@link DistanceMeasurementSession}.
48  *
49  * <p>To get an instance of {@link DistanceMeasurementSession}, first use {@link
50  * DistanceMeasurementManager#startMeasurementSession(DistanceMeasurementParams, Executor,
51  * DistanceMeasurementSession.Callback)} to request to start a session. Once the session is started,
52  * a {@link DistanceMeasurementSession} object is provided through {@link
53  * DistanceMeasurementSession.Callback#onStarted(DistanceMeasurementSession)}. If starting a session
54  * fails, the failure is reported through {@link
55  * DistanceMeasurementSession.Callback#onStartFail(int)} with the failure reason.
56  *
57  * @hide
58  */
59 @SystemApi
60 public final class DistanceMeasurementSession {
61     private static final String TAG = DistanceMeasurementSession.class.getSimpleName();
62 
63     private final IDistanceMeasurement mDistanceMeasurement;
64     private final ParcelUuid mUuid;
65     private final DistanceMeasurementParams mDistanceMeasurementParams;
66     private final Executor mExecutor;
67     private final Callback mCallback;
68     private final AttributionSource mAttributionSource;
69 
70     /** @hide */
71     @Retention(RetentionPolicy.SOURCE)
72     @IntDef(
73             value = {
74                 BluetoothStatusCodes.SUCCESS,
75                 BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
76                 BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL,
77             })
78     public @interface StopSessionReturnValues {}
79 
80     /** @hide */
DistanceMeasurementSession( IDistanceMeasurement distanceMeasurement, ParcelUuid uuid, DistanceMeasurementParams params, Executor executor, AttributionSource attributionSource, Callback callback)81     public DistanceMeasurementSession(
82             IDistanceMeasurement distanceMeasurement,
83             ParcelUuid uuid,
84             DistanceMeasurementParams params,
85             Executor executor,
86             AttributionSource attributionSource,
87             Callback callback) {
88         mDistanceMeasurement = requireNonNull(distanceMeasurement);
89         mDistanceMeasurementParams = requireNonNull(params);
90         mExecutor = requireNonNull(executor);
91         mCallback = requireNonNull(callback);
92         mUuid = uuid;
93         mAttributionSource = attributionSource;
94     }
95 
96     /**
97      * Stops actively ranging, {@link Callback#onStopped} will be invoked if this succeeds.
98      *
99      * @return whether successfully stop or not
100      * @hide
101      */
102     @SystemApi
103     @RequiresBluetoothConnectPermission
104     @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
stopSession()105     public @StopSessionReturnValues int stopSession() {
106         try {
107             return mDistanceMeasurement.stopDistanceMeasurement(
108                     mUuid,
109                     mDistanceMeasurementParams.getDevice(),
110                     mDistanceMeasurementParams.getMethodId(),
111                     mAttributionSource);
112         } catch (RemoteException e) {
113             Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
114             return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
115         }
116     }
117 
118     /** @hide */
onStarted()119     void onStarted() {
120         executeFromBinder(mExecutor, () -> mCallback.onStarted(this));
121     }
122 
123     /** @hide */
onStartFail(int reason)124     void onStartFail(int reason) {
125         executeFromBinder(mExecutor, () -> mCallback.onStartFail(reason));
126     }
127 
128     /** @hide */
onStopped(int reason)129     void onStopped(int reason) {
130         executeFromBinder(mExecutor, () -> mCallback.onStopped(this, reason));
131     }
132 
133     /** @hide */
onResult(@onNull BluetoothDevice device, @NonNull DistanceMeasurementResult result)134     void onResult(@NonNull BluetoothDevice device, @NonNull DistanceMeasurementResult result) {
135         executeFromBinder(mExecutor, () -> mCallback.onResult(device, result));
136     }
137 
138     /**
139      * Interface for receiving {@link DistanceMeasurementSession} events.
140      *
141      * @hide
142      */
143     @SystemApi
144     public interface Callback {
145         /** @hide */
146         @Retention(RetentionPolicy.SOURCE)
147         @IntDef(
148                 value = {
149                     BluetoothStatusCodes.ERROR_UNKNOWN,
150                     BluetoothStatusCodes.FEATURE_NOT_SUPPORTED,
151                     BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED,
152                     BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST,
153                     BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST,
154                     BluetoothStatusCodes.REASON_REMOTE_REQUEST,
155                     BluetoothStatusCodes.ERROR_TIMEOUT,
156                     BluetoothStatusCodes.ERROR_NO_LE_CONNECTION,
157                     BluetoothStatusCodes.ERROR_BAD_PARAMETERS,
158                     BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL,
159                 })
160         @interface Reason {}
161 
162         /**
163          * Invoked when {@link DistanceMeasurementManager#startMeasurementSession(
164          * DistanceMeasurementParams, Executor, DistanceMeasurementSession.Callback)} is successful.
165          *
166          * @param session the started {@link DistanceMeasurementSession}
167          * @hide
168          */
169         @SystemApi
onStarted(@onNull DistanceMeasurementSession session)170         void onStarted(@NonNull DistanceMeasurementSession session);
171 
172         /**
173          * Invoked if {@link DistanceMeasurementManager#startMeasurementSession(
174          * DistanceMeasurementParams, Executor, DistanceMeasurementSession.Callback)} fails.
175          *
176          * @param reason the failure reason
177          * @hide
178          */
179         @SystemApi
onStartFail(@eason int reason)180         void onStartFail(@Reason int reason);
181 
182         /**
183          * Invoked when a distance measurement session stopped.
184          *
185          * @param reason reason for the session stop
186          * @hide
187          */
188         @SystemApi
onStopped(@onNull DistanceMeasurementSession session, @Reason int reason)189         void onStopped(@NonNull DistanceMeasurementSession session, @Reason int reason);
190 
191         /**
192          * Invoked when get distance measurement result.
193          *
194          * @param device remote device
195          * @param result {@link DistanceMeasurementResult} for this device
196          * @hide
197          */
198         @SystemApi
onResult(@onNull BluetoothDevice device, @NonNull DistanceMeasurementResult result)199         void onResult(@NonNull BluetoothDevice device, @NonNull DistanceMeasurementResult result);
200     }
201 }
202