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