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