• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 package android.bluetooth;
17 
18 import android.annotation.RequiresPermission;
19 import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
20 import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.os.Build;
23 import android.os.Parcel;
24 import android.os.ParcelUuid;
25 import android.os.Parcelable;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.UUID;
30 
31 /**
32  * Represents a Bluetooth GATT Service
33  *
34  * <p> Gatt Service contains a collection of {@link BluetoothGattCharacteristic},
35  * as well as referenced services.
36  */
37 public class BluetoothGattService implements Parcelable {
38 
39     /**
40      * Primary service
41      */
42     public static final int SERVICE_TYPE_PRIMARY = 0;
43 
44     /**
45      * Secondary service (included by primary services)
46      */
47     public static final int SERVICE_TYPE_SECONDARY = 1;
48 
49 
50     /**
51      * The remote device this service is associated with.
52      * This applies to client applications only.
53      *
54      * @hide
55      */
56     @UnsupportedAppUsage
57     protected BluetoothDevice mDevice;
58 
59     /**
60      * The UUID of this service.
61      *
62      * @hide
63      */
64     protected UUID mUuid;
65 
66     /**
67      * Instance ID for this service.
68      *
69      * @hide
70      */
71     protected int mInstanceId;
72 
73     /**
74      * Handle counter override (for conformance testing).
75      *
76      * @hide
77      */
78     protected int mHandles = 0;
79 
80     /**
81      * Service type (Primary/Secondary).
82      *
83      * @hide
84      */
85     protected int mServiceType;
86 
87     /**
88      * List of characteristics included in this service.
89      */
90     protected List<BluetoothGattCharacteristic> mCharacteristics;
91 
92     /**
93      * List of included services for this service.
94      */
95     protected List<BluetoothGattService> mIncludedServices;
96 
97     /**
98      * Whether the service uuid should be advertised.
99      */
100     private boolean mAdvertisePreferred;
101 
102     /**
103      * Create a new BluetoothGattService.
104      *
105      * @param uuid The UUID for this service
106      * @param serviceType The type of this service,
107      * {@link BluetoothGattService#SERVICE_TYPE_PRIMARY}
108      * or {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
109      */
BluetoothGattService(UUID uuid, int serviceType)110     public BluetoothGattService(UUID uuid, int serviceType) {
111         mDevice = null;
112         mUuid = uuid;
113         mInstanceId = 0;
114         mServiceType = serviceType;
115         mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
116         mIncludedServices = new ArrayList<BluetoothGattService>();
117     }
118 
119     /**
120      * Create a new BluetoothGattService
121      *
122      * @hide
123      */
BluetoothGattService(BluetoothDevice device, UUID uuid, int instanceId, int serviceType)124     /*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
125             int instanceId, int serviceType) {
126         mDevice = device;
127         mUuid = uuid;
128         mInstanceId = instanceId;
129         mServiceType = serviceType;
130         mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
131         mIncludedServices = new ArrayList<BluetoothGattService>();
132     }
133 
134     /**
135      * Create a new BluetoothGattService
136      *
137      * @hide
138      */
BluetoothGattService(UUID uuid, int instanceId, int serviceType)139     public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
140         mDevice = null;
141         mUuid = uuid;
142         mInstanceId = instanceId;
143         mServiceType = serviceType;
144         mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
145         mIncludedServices = new ArrayList<BluetoothGattService>();
146     }
147 
148     /**
149      * @hide
150      */
describeContents()151     public int describeContents() {
152         return 0;
153     }
154 
155     @Override
writeToParcel(Parcel out, int flags)156     public void writeToParcel(Parcel out, int flags) {
157         out.writeParcelable(new ParcelUuid(mUuid), 0);
158         out.writeInt(mInstanceId);
159         out.writeInt(mServiceType);
160         out.writeTypedList(mCharacteristics);
161 
162         ArrayList<BluetoothGattIncludedService> includedServices =
163                 new ArrayList<BluetoothGattIncludedService>(mIncludedServices.size());
164         for (BluetoothGattService s : mIncludedServices) {
165             includedServices.add(new BluetoothGattIncludedService(s.getUuid(),
166                     s.getInstanceId(), s.getType()));
167         }
168         out.writeTypedList(includedServices);
169     }
170 
171     public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattService> CREATOR =
172             new Parcelable.Creator<BluetoothGattService>() {
173         public BluetoothGattService createFromParcel(Parcel in) {
174             return new BluetoothGattService(in);
175         }
176 
177         public BluetoothGattService[] newArray(int size) {
178             return new BluetoothGattService[size];
179         }
180     };
181 
BluetoothGattService(Parcel in)182     private BluetoothGattService(Parcel in) {
183         mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
184         mInstanceId = in.readInt();
185         mServiceType = in.readInt();
186 
187         mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
188 
189         ArrayList<BluetoothGattCharacteristic> chrcs =
190                 in.createTypedArrayList(BluetoothGattCharacteristic.CREATOR);
191         if (chrcs != null) {
192             for (BluetoothGattCharacteristic chrc : chrcs) {
193                 chrc.setService(this);
194                 mCharacteristics.add(chrc);
195             }
196         }
197 
198         mIncludedServices = new ArrayList<BluetoothGattService>();
199 
200         ArrayList<BluetoothGattIncludedService> inclSvcs =
201                 in.createTypedArrayList(BluetoothGattIncludedService.CREATOR);
202         if (chrcs != null) {
203             for (BluetoothGattIncludedService isvc : inclSvcs) {
204                 mIncludedServices.add(new BluetoothGattService(null, isvc.getUuid(),
205                         isvc.getInstanceId(), isvc.getType()));
206             }
207         }
208     }
209 
210     /**
211      * Returns the device associated with this service.
212      *
213      * @hide
214      */
getDevice()215     /*package*/ BluetoothDevice getDevice() {
216         return mDevice;
217     }
218 
219     /**
220      * Returns the device associated with this service.
221      *
222      * @hide
223      */
setDevice(BluetoothDevice device)224     /*package*/ void setDevice(BluetoothDevice device) {
225         mDevice = device;
226     }
227 
228     /**
229      * Add an included service to this service.
230      *
231      * @param service The service to be added
232      * @return true, if the included service was added to the service
233      */
234     @RequiresLegacyBluetoothPermission
addService(BluetoothGattService service)235     public boolean addService(BluetoothGattService service) {
236         mIncludedServices.add(service);
237         return true;
238     }
239 
240     /**
241      * Add a characteristic to this service.
242      *
243      * @param characteristic The characteristics to be added
244      * @return true, if the characteristic was added to the service
245      */
246     @RequiresLegacyBluetoothPermission
addCharacteristic(BluetoothGattCharacteristic characteristic)247     public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) {
248         mCharacteristics.add(characteristic);
249         characteristic.setService(this);
250         return true;
251     }
252 
253     /**
254      * Get characteristic by UUID and instanceId.
255      *
256      * @hide
257      */
getCharacteristic(UUID uuid, int instanceId)258     /*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
259         for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
260             if (uuid.equals(characteristic.getUuid())
261                     && characteristic.getInstanceId() == instanceId) {
262                 return characteristic;
263             }
264         }
265         return null;
266     }
267 
268     /**
269      * Force the instance ID.
270      *
271      * @hide
272      */
273     @UnsupportedAppUsage
setInstanceId(int instanceId)274     public void setInstanceId(int instanceId) {
275         mInstanceId = instanceId;
276     }
277 
278     /**
279      * Get the handle count override (conformance testing.
280      *
281      * @hide
282      */
getHandles()283     /*package*/ int getHandles() {
284         return mHandles;
285     }
286 
287     /**
288      * Force the number of handles to reserve for this service.
289      * This is needed for conformance testing only.
290      *
291      * @hide
292      */
setHandles(int handles)293     public void setHandles(int handles) {
294         mHandles = handles;
295     }
296 
297     /**
298      * Add an included service to the internal map.
299      *
300      * @hide
301      */
addIncludedService(BluetoothGattService includedService)302     public void addIncludedService(BluetoothGattService includedService) {
303         mIncludedServices.add(includedService);
304     }
305 
306     /**
307      * Returns the UUID of this service
308      *
309      * @return UUID of this service
310      */
getUuid()311     public UUID getUuid() {
312         return mUuid;
313     }
314 
315     /**
316      * Returns the instance ID for this service
317      *
318      * <p>If a remote device offers multiple services with the same UUID
319      * (ex. multiple battery services for different batteries), the instance
320      * ID is used to distuinguish services.
321      *
322      * @return Instance ID of this service
323      */
getInstanceId()324     public int getInstanceId() {
325         return mInstanceId;
326     }
327 
328     /**
329      * Get the type of this service (primary/secondary)
330      */
getType()331     public int getType() {
332         return mServiceType;
333     }
334 
335     /**
336      * Get the list of included GATT services for this service.
337      *
338      * @return List of included services or empty list if no included services were discovered.
339      */
getIncludedServices()340     public List<BluetoothGattService> getIncludedServices() {
341         return mIncludedServices;
342     }
343 
344     /**
345      * Returns a list of characteristics included in this service.
346      *
347      * @return Characteristics included in this service
348      */
getCharacteristics()349     public List<BluetoothGattCharacteristic> getCharacteristics() {
350         return mCharacteristics;
351     }
352 
353     /**
354      * Returns a characteristic with a given UUID out of the list of
355      * characteristics offered by this service.
356      *
357      * <p>This is a convenience function to allow access to a given characteristic
358      * without enumerating over the list returned by {@link #getCharacteristics}
359      * manually.
360      *
361      * <p>If a remote service offers multiple characteristics with the same
362      * UUID, the first instance of a characteristic with the given UUID
363      * is returned.
364      *
365      * @return GATT characteristic object or null if no characteristic with the given UUID was
366      * found.
367      */
getCharacteristic(UUID uuid)368     public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
369         for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
370             if (uuid.equals(characteristic.getUuid())) {
371                 return characteristic;
372             }
373         }
374         return null;
375     }
376 
377     /**
378      * Returns whether the uuid of the service should be advertised.
379      *
380      * @hide
381      */
isAdvertisePreferred()382     public boolean isAdvertisePreferred() {
383         return mAdvertisePreferred;
384     }
385 
386     /**
387      * Set whether the service uuid should be advertised.
388      *
389      * @hide
390      */
391     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setAdvertisePreferred(boolean advertisePreferred)392     public void setAdvertisePreferred(boolean advertisePreferred) {
393         mAdvertisePreferred = advertisePreferred;
394     }
395 }
396