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.Parcelable; 20 import android.os.ParcelUuid; 21 import java.util.ArrayList; 22 import java.util.List; 23 import 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 */ 31 public 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 */ BluetoothGattService(UUID uuid, int serviceType)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 */ BluetoothGattService(BluetoothDevice device, UUID uuid, int instanceId, int serviceType)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 */ BluetoothGattService(UUID uuid, int instanceId, int serviceType)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 */ describeContents()138 public int describeContents() { 139 return 0; 140 } 141 142 @Override writeToParcel(Parcel out, int flags)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 BluetoothGattService(Parcel in)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 */ getDevice()201 /*package*/ BluetoothDevice getDevice() { 202 return mDevice; 203 } 204 205 /** 206 * Returns the device associated with this service. 207 * @hide 208 */ setDevice(BluetoothDevice device)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 */ addService(BluetoothGattService service)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 */ addCharacteristic(BluetoothGattCharacteristic characteristic)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 */ getCharacteristic(UUID uuid, int instanceId)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 * @hide 254 */ setInstanceId(int instanceId)255 public void setInstanceId(int instanceId) { 256 mInstanceId = instanceId; 257 } 258 259 /** 260 * Get the handle count override (conformance testing. 261 * @hide 262 */ getHandles()263 /*package*/ int getHandles() { 264 return mHandles; 265 } 266 267 /** 268 * Force the number of handles to reserve for this service. 269 * This is needed for conformance testing only. 270 * @hide 271 */ setHandles(int handles)272 public void setHandles(int handles) { 273 mHandles = handles; 274 } 275 276 /** 277 * Add an included service to the internal map. 278 * @hide 279 */ addIncludedService(BluetoothGattService includedService)280 public void addIncludedService(BluetoothGattService includedService) { 281 mIncludedServices.add(includedService); 282 } 283 284 /** 285 * Returns the UUID of this service 286 * 287 * @return UUID of this service 288 */ getUuid()289 public UUID getUuid() { 290 return mUuid; 291 } 292 293 /** 294 * Returns the instance ID for this service 295 * 296 * <p>If a remote device offers multiple services with the same UUID 297 * (ex. multiple battery services for different batteries), the instance 298 * ID is used to distuinguish services. 299 * 300 * @return Instance ID of this service 301 */ getInstanceId()302 public int getInstanceId() { 303 return mInstanceId; 304 } 305 306 /** 307 * Get the type of this service (primary/secondary) 308 */ getType()309 public int getType() { 310 return mServiceType; 311 } 312 313 /** 314 * Get the list of included GATT services for this service. 315 * 316 * @return List of included services or empty list if no included services 317 * were discovered. 318 */ getIncludedServices()319 public List<BluetoothGattService> getIncludedServices() { 320 return mIncludedServices; 321 } 322 323 /** 324 * Returns a list of characteristics included in this service. 325 * 326 * @return Characteristics included in this service 327 */ getCharacteristics()328 public List<BluetoothGattCharacteristic> getCharacteristics() { 329 return mCharacteristics; 330 } 331 332 /** 333 * Returns a characteristic with a given UUID out of the list of 334 * characteristics offered by this service. 335 * 336 * <p>This is a convenience function to allow access to a given characteristic 337 * without enumerating over the list returned by {@link #getCharacteristics} 338 * manually. 339 * 340 * <p>If a remote service offers multiple characteristics with the same 341 * UUID, the first instance of a characteristic with the given UUID 342 * is returned. 343 * 344 * @return GATT characteristic object or null if no characteristic with the 345 * given UUID was found. 346 */ getCharacteristic(UUID uuid)347 public BluetoothGattCharacteristic getCharacteristic(UUID uuid) { 348 for(BluetoothGattCharacteristic characteristic : mCharacteristics) { 349 if (uuid.equals(characteristic.getUuid())) 350 return characteristic; 351 } 352 return null; 353 } 354 355 /** 356 * Returns whether the uuid of the service should be advertised. 357 * @hide 358 */ isAdvertisePreferred()359 public boolean isAdvertisePreferred() { 360 return mAdvertisePreferred; 361 } 362 363 /** 364 * Set whether the service uuid should be advertised. 365 * @hide 366 */ setAdvertisePreferred(boolean advertisePreferred)367 public void setAdvertisePreferred(boolean advertisePreferred) { 368 this.mAdvertisePreferred = advertisePreferred; 369 } 370 } 371