Home | History | Annotate | Download | only in bluetooth
      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.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      */
    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      */
    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      */
    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      */
    148     public int describeContents() {
    149         return 0;
    150     }
    151 
    152     @Override
    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 
    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      */
    212     /*package*/ BluetoothDevice getDevice() {
    213         return mDevice;
    214     }
    215 
    216     /**
    217      * Returns the device associated with this service.
    218      *
    219      * @hide
    220      */
    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      */
    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      */
    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      */
    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
    271     public void setInstanceId(int instanceId) {
    272         mInstanceId = instanceId;
    273     }
    274 
    275     /**
    276      * Get the handle count override (conformance testing.
    277      *
    278      * @hide
    279      */
    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      */
    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      */
    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      */
    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      */
    321     public int getInstanceId() {
    322         return mInstanceId;
    323     }
    324 
    325     /**
    326      * Get the type of this service (primary/secondary)
    327      */
    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      */
    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      */
    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      */
    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      */
    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
    389     public void setAdvertisePreferred(boolean advertisePreferred) {
    390         mAdvertisePreferred = advertisePreferred;
    391     }
    392 }
    393