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