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