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