diff options
author | Matthew Xie <mattx@google.com> | 2013-03-01 18:41:02 -0800 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2013-03-28 15:36:10 -0700 |
commit | ddf7e4756c31d0ed90802f98abeaa79df6d16b2a (patch) | |
tree | d50a602db913c46bd83905631cb1d36d3cb9ecec /core/java/android/bluetooth | |
parent | dc1975ea717cdafb914fd00ea781fd314e1ac478 (diff) | |
download | frameworks_base-ddf7e4756c31d0ed90802f98abeaa79df6d16b2a.zip frameworks_base-ddf7e4756c31d0ed90802f98abeaa79df6d16b2a.tar.gz frameworks_base-ddf7e4756c31d0ed90802f98abeaa79df6d16b2a.tar.bz2 |
Unhide Bluetooth Low Energy public APIs
Updated API headers. Add BluetoothManager to be retrieved by
context.getSystemService(Context.BLUETOOTH_SERVICE).
LE scan functions are placed in BluetoothAdapter
The GATT API are device driven instead of a profile-driver.
bug 8450158
Change-Id: I424a4cedaac3ef8120a05996500008dd210d2553
Diffstat (limited to 'core/java/android/bluetooth')
16 files changed, 947 insertions, 993 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index b00bf09..2e9c9e3 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -22,7 +22,6 @@ import android.content.Context; import android.os.Binder; import android.os.Handler; import android.os.IBinder; -import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.RemoteException; @@ -359,6 +358,8 @@ public final class BluetoothAdapter { private IBluetooth mService; private Handler mServiceRecordHandler; + private BluetoothAdapterCallback mCallback; + private int mClientIf; /** * Get a handle to the default local Bluetooth adapter. @@ -1137,7 +1138,8 @@ public final class BluetoothAdapter { * Get the profile proxy object associated with the profile. * * <p>Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET}, - * or {@link BluetoothProfile#A2DP}. Clients must implement + * {@link BluetoothProfile#A2DP}, {@link BluetoothProfile#GATT}, or + * {@link BluetoothProfile#GATT_SERVER}. Clients must implement * {@link BluetoothProfile.ServiceListener} to get notified of * the connection status and to get the proxy object. * @@ -1166,12 +1168,6 @@ public final class BluetoothAdapter { } else if (profile == BluetoothProfile.HEALTH) { BluetoothHealth health = new BluetoothHealth(context, listener); return true; - } else if (profile == BluetoothProfile.GATT) { - BluetoothGatt gatt = new BluetoothGatt(context, listener); - return true; - } else if (profile == BluetoothProfile.GATT_SERVER) { - BluetoothGattServer gattServer = new BluetoothGattServer(context, listener); - return true; } else { return false; } @@ -1411,4 +1407,230 @@ public final class BluetoothAdapter { mProxyServiceStateCallbacks.remove(cb); } } + + /** + * Register an callback to receive async results, such as LE scan result. + * + * <p>This is an asynchronous call. The callback + * {@link BluetoothAdapterCallback#onCallbackRegistration} + * is used to notify success or failure if the function returns true. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param callback BluetootAdapter callback handler that will receive asynchronous callbacks. + * @return If true, the callback will be called to notify success or failure, + * false on immediate error + */ + public boolean registerCallback(BluetoothAdapterCallback callback) { + try { + IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); + mCallback = callback; + UUID uuid = UUID.randomUUID(); + if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid); + + iGatt.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); + return true; + } catch (RemoteException e) { + Log.e(TAG,"",e); + return false; + } + } + + /** + * Unregister the registered callback. + */ + public boolean unRegisterCallback(BluetoothAdapterCallback callback) { + if (callback != mCallback) return false; + try { + IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); + + iGatt.unregisterClient(mClientIf); + return true; + } catch (RemoteException e) { + Log.e(TAG,"",e); + return false; + } + } + + /** + * Starts a scan for Bluetooth LE devices. + * + * <p>Results of the scan are reported using the + * {@link BluetoothAdapterCallback#onLeScan} callback. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @return true, if the scan was started successfully + */ + public boolean startLeScan() { + if (DBG) Log.d(TAG, "startLeScan()"); + if (mClientIf == 0) return false; + + try { + IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); + iGatt.startScan(mClientIf, false); + } catch (RemoteException e) { + Log.e(TAG,"",e); + return false; + } + + return true; + } + + /** + * Starts a scan for Bluetooth LE devices, looking for devices that + * advertise given services. + * + * <p>Devices which advertise all specified services are reported using the + * {@link BluetoothAdapterCallback#onLeScan} callback. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param serviceUuids Array of services to look for + * @return true, if the scan was started successfully + */ + public boolean startLeScan(UUID[] serviceUuids) { + if (DBG) Log.d(TAG, "startLeScan() - with UUIDs"); + if (mClientIf == 0) return false; + + try { + IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); + ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length]; + for(int i = 0; i != uuids.length; ++i) { + uuids[i] = new ParcelUuid(serviceUuids[i]); + } + iGatt.startScanWithUuids(mClientIf, false, uuids); + } catch (RemoteException e) { + Log.e(TAG,"",e); + return false; + } + + return true; + } + + /** + * Stops an ongoing Bluetooth LE device scan. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + */ + public void stopLeScan() { + if (DBG) Log.d(TAG, "stopScan()"); + if (mClientIf == 0) return; + + try { + IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); + iGatt.stopScan(mClientIf, false); + } catch (RemoteException e) { + Log.e(TAG,"",e); + } + } + + /** + * Bluetooth GATT interface callbacks + */ + private final IBluetoothGattCallback mBluetoothGattCallback = + new IBluetoothGattCallback.Stub() { + /** + * Application interface registered - app is ready to go + */ + public void onClientRegistered(int status, int clientIf) { + if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status + + " clientIf=" + clientIf); + mClientIf = clientIf; + mCallback.onCallbackRegistration(status == BluetoothGatt.GATT_SUCCESS ? + BluetoothAdapterCallback.CALLBACK_REGISTERED : + BluetoothAdapterCallback.CALLBACK_REGISTRATION_FAILURE); + } + + public void onClientConnectionState(int status, int clientIf, + boolean connected, String address) { + // no op + } + + /** + * Callback reporting an LE scan result. + * @hide + */ + public void onScanResult(String address, int rssi, byte[] advData) { + if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); + + try { + mCallback.onLeScan(getRemoteDevice(address), rssi, advData); + } catch (Exception ex) { + Log.w(TAG, "Unhandled exception: " + ex); + } + } + + public void onGetService(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid) { + // no op + } + + public void onGetIncludedService(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int inclSrvcType, int inclSrvcInstId, + ParcelUuid inclSrvcUuid) { + // no op + } + + public void onGetCharacteristic(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + int charProps) { + // no op + } + + public void onGetDescriptor(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descUuid) { + // no op + } + + public void onSearchComplete(String address, int status) { + // no op + } + + public void onCharacteristicRead(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, byte[] value) { + // no op + } + + public void onCharacteristicWrite(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid) { + // no op + } + + public void onNotify(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + byte[] value) { + // no op + } + + public void onDescriptorRead(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descrUuid, byte[] value) { + // no op + } + + public void onDescriptorWrite(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descrUuid) { + // no op + } + + public void onExecuteWrite(String address, int status) { + // no op + } + + public void onReadRemoteRssi(String address, int rssi, int status) { + // no op + } + }; + } diff --git a/core/java/android/bluetooth/BluetoothAdapterCallback.java b/core/java/android/bluetooth/BluetoothAdapterCallback.java new file mode 100644 index 0000000..a726bc9 --- /dev/null +++ b/core/java/android/bluetooth/BluetoothAdapterCallback.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth; + +import android.bluetooth.BluetoothDevice; + +/** + * This abstract class is used to implement {@link BluetoothAdapter} callbacks. + */ +public abstract class BluetoothAdapterCallback { + + /** + * Indicates the callback has been registered successfully + */ + public static final int CALLBACK_REGISTERED = 0; + + /** + * Indicates the callback registration has failed + */ + public static final int CALLBACK_REGISTRATION_FAILURE = 1; + + /** + * Callback to inform change in registration state of the application. + * + * @param status Returns {@link #CALLBACK_REGISTERED} if the application + * was successfully registered. + */ + public void onCallbackRegistration(int status) { + } + + /** + * Callback reporting an LE device found during a device scan initiated + * by the {@link BluetoothAdapter#startLeScan} function. + * + * @param device Identifies the remote device + * @param rssi The RSSI value for the remote device as reported by the + * Bluetooth hardware. 0 if no RSSI value is available. + * @param scanRecord The content of the advertisement record offered by + * the remote device. + */ + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + } +} diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 4cc22b4..83e95ca 100755 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -18,6 +18,7 @@ package android.bluetooth; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.content.Context; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -1126,4 +1127,30 @@ public final class BluetoothDevice implements Parcelable { return pinBytes; } + /** + * Connect to GATT Server hosted by this device. Caller acts as GATT client. + * The callback is used to deliver results to Caller, such as connection status as well + * as any further GATT client operations. + * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct + * GATT client operations. + * @param callback GATT callback handler that will receive asynchronous callbacks. + * @param autoConnect Whether to directly connect to the remote device (false) + * or to automatically connect as soon as the remote + * device becomes available (true). + * @throws IllegalArgumentException if callback is null + */ + public BluetoothGatt connectGattServer(Context context, boolean autoConnect, + BluetoothGattCallback callback) { + // TODO(Bluetooth) check whether platform support BLE + // Do the check here or in GattServer? + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + IBluetoothManager managerService = adapter.getBluetoothManager(); + try { + IBluetoothGatt iGatt = managerService.getBluetoothGatt(); + BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this); + gatt.connect(autoConnect, callback); + return gatt; + } catch (RemoteException e) {Log.e(TAG, "", e);} + return null; + } } diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index 1e12025..f9ce6ea 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -16,8 +16,6 @@ package android.bluetooth; - -import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile.ServiceListener; @@ -39,42 +37,48 @@ import java.util.List; import java.util.UUID; /** - * Public API for the Bluetooth Gatt Profile. + * Public API for the Bluetooth GATT Profile. * - * <p>This class provides Bluetooth Gatt functionality to enable communication + * <p>This class provides Bluetooth GATT functionality to enable communication * with Bluetooth Smart or Smart Ready devices. * - * <p>BluetoothGatt is a proxy object for controlling the Bluetooth Service - * via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the - * BluetoothGatt proxy object. - * * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback} - * and call {@link #registerApp} to register your application. Gatt capable - * devices can be discovered using the {@link #startScan} function or the - * regular Bluetooth device discovery process. - * @hide + * and call {@link BluetoothDevice#connectGattServer} to get a instance of this class. + * GATT capable devices can be discovered using the Bluetooth device discovery or BLE + * scan process. */ public final class BluetoothGatt implements BluetoothProfile { private static final String TAG = "BluetoothGatt"; private static final boolean DBG = true; + private static final boolean VDBG = true; - private Context mContext; - private ServiceListener mServiceListener; - private BluetoothAdapter mAdapter; + private final Context mContext; private IBluetoothGatt mService; private BluetoothGattCallback mCallback; private int mClientIf; private boolean mAuthRetry = false; + private BluetoothDevice mDevice; + private boolean mAutoConnect; + private int mConnState; + private final Object mStateLock = new Object(); + + private static final int CONN_STATE_IDLE = 0; + private static final int CONN_STATE_CONNECTING = 1; + private static final int CONN_STATE_CONNECTED = 2; + private static final int CONN_STATE_DISCONNECTING = 3; private List<BluetoothGattService> mServices; - /** A Gatt operation completed successfully */ + /** A GATT operation failed */ + public static final int GATT_FAILURE = 0; + + /** A GATT operation completed successfully */ public static final int GATT_SUCCESS = 0; - /** Gatt read operation is not permitted */ + /** GATT read operation is not permitted */ public static final int GATT_READ_NOT_PERMITTED = 0x2; - /** Gatt write operation is not permitted */ + /** GATT write operation is not permitted */ public static final int GATT_WRITE_NOT_PERMITTED = 0x3; /** Insufficient authentication for a given operation */ @@ -111,55 +115,6 @@ public final class BluetoothGatt implements BluetoothProfile { /*package*/ static final int AUTHENTICATION_MITM = 2; /** - * Bluetooth state change handlers - */ - private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = - new IBluetoothStateChangeCallback.Stub() { - public void onBluetoothStateChange(boolean up) { - if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); - if (!up) { - if (DBG) Log.d(TAG,"Unbinding service..."); - synchronized (mConnection) { - mService = null; - mContext.unbindService(mConnection); - } - } else { - synchronized (mConnection) { - if (mService == null) { - if (DBG) Log.d(TAG,"Binding service..."); - if (!mContext.bindService(new Intent(IBluetoothGatt.class.getName()), - mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth GATT Service"); - } - } - } - } - } - }; - - /** - * Service binder handling - */ - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - if (DBG) Log.d(TAG, "Proxy object connected"); - mService = IBluetoothGatt.Stub.asInterface(service); - ServiceListener serviceListener = mServiceListener; - if (serviceListener != null) { - serviceListener.onServiceConnected(BluetoothProfile.GATT, BluetoothGatt.this); - } - } - public void onServiceDisconnected(ComponentName className) { - if (DBG) Log.d(TAG, "Proxy object disconnected"); - mService = null; - ServiceListener serviceListener = mServiceListener; - if (serviceListener != null) { - serviceListener.onServiceDisconnected(BluetoothProfile.GATT); - } - } - }; - - /** * Bluetooth GATT interface callbacks */ private final IBluetoothGattCallback mBluetoothGattCallback = @@ -171,11 +126,27 @@ public final class BluetoothGatt implements BluetoothProfile { public void onClientRegistered(int status, int clientIf) { if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf); + if (VDBG) { + synchronized(mStateLock) { + if (mConnState != CONN_STATE_CONNECTING) { + Log.e(TAG, "Bad connection state: " + mConnState); + } + } + } mClientIf = clientIf; + if (status != GATT_SUCCESS) { + mCallback.onConnectionStateChange(mDevice, GATT_FAILURE, + BluetoothProfile.STATE_DISCONNECTED); + synchronized(mStateLock) { + mConnState = CONN_STATE_IDLE; + } + return; + } try { - mCallback.onAppRegistered(status); - } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + mService.clientConnect(mClientIf, mDevice.getAddress(), + !mAutoConnect); // autoConnect is inverse of "isDirect" + } catch (RemoteException e) { + Log.e(TAG,"",e); } } @@ -187,13 +158,24 @@ public final class BluetoothGatt implements BluetoothProfile { boolean connected, String address) { if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status + " clientIf=" + clientIf + " device=" + address); + if (!address.equals(mDevice.getAddress())) { + return; + } + int profileState = connected ? BluetoothProfile.STATE_CONNECTED : + BluetoothProfile.STATE_DISCONNECTED; try { - mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status, - connected ? BluetoothProfile.STATE_CONNECTED - : BluetoothProfile.STATE_DISCONNECTED); + mCallback.onConnectionStateChange(mDevice, status, profileState); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } + + synchronized(mStateLock) { + if (connected) { + mConnState = CONN_STATE_CONNECTED; + } else { + mConnState = CONN_STATE_IDLE; + } + } } /** @@ -201,13 +183,7 @@ public final class BluetoothGatt implements BluetoothProfile { * @hide */ public void onScanResult(String address, int rssi, byte[] advData) { - if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); - - try { - mCallback.onScanResult(mAdapter.getRemoteDevice(address), rssi, advData); - } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); - } + // no op } /** @@ -219,8 +195,10 @@ public final class BluetoothGatt implements BluetoothProfile { public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid) { if (DBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - mServices.add(new BluetoothGattService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + mServices.add(new BluetoothGattService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType)); } @@ -236,10 +214,12 @@ public final class BluetoothGatt implements BluetoothProfile { if (DBG) Log.d(TAG, "onGetIncludedService() - Device=" + address + " UUID=" + srvcUuid + " Included=" + inclSrvcUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); - BluetoothGattService includedService = getService(device, + BluetoothGattService includedService = getService(mDevice, inclSrvcUuid.getUuid(), inclSrvcInstId, inclSrvcType); if (service != null && includedService != null) { @@ -260,8 +240,10 @@ public final class BluetoothGatt implements BluetoothProfile { if (DBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" + charUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service != null) { service.addCharacteristic(new BluetoothGattCharacteristic( @@ -281,8 +263,10 @@ public final class BluetoothGatt implements BluetoothProfile { ParcelUuid descUuid) { if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -303,9 +287,11 @@ public final class BluetoothGatt implements BluetoothProfile { */ public void onSearchComplete(String address, int status) { if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status); - BluetoothDevice device = mAdapter.getRemoteDevice(address); + if (!address.equals(mDevice.getAddress())) { + return; + } try { - mCallback.onServicesDiscovered(device, status); + mCallback.onServicesDiscovered(mDevice, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } @@ -322,6 +308,9 @@ public final class BluetoothGatt implements BluetoothProfile { if (DBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address + " UUID=" + charUuid + " Status=" + status); + if (!address.equals(mDevice.getAddress())) { + return; + } if ((status == GATT_INSUFFICIENT_AUTHENTICATION || status == GATT_INSUFFICIENT_ENCRYPTION) && mAuthRetry == false) { @@ -338,8 +327,7 @@ public final class BluetoothGatt implements BluetoothProfile { mAuthRetry = false; - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -367,8 +355,10 @@ public final class BluetoothGatt implements BluetoothProfile { if (DBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address + " UUID=" + charUuid + " Status=" + status); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -411,8 +401,10 @@ public final class BluetoothGatt implements BluetoothProfile { byte[] value) { if (DBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -439,8 +431,10 @@ public final class BluetoothGatt implements BluetoothProfile { ParcelUuid descrUuid, byte[] value) { if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -486,8 +480,10 @@ public final class BluetoothGatt implements BluetoothProfile { ParcelUuid descrUuid) { if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid); - BluetoothDevice device = mAdapter.getRemoteDevice(address); - BluetoothGattService service = getService(device, srvcUuid.getUuid(), + if (!address.equals(mDevice.getAddress())) { + return; + } + BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(), srvcInstId, srvcType); if (service == null) return; @@ -529,9 +525,11 @@ public final class BluetoothGatt implements BluetoothProfile { public void onExecuteWrite(String address, int status) { if (DBG) Log.d(TAG, "onExecuteWrite() - Device=" + address + " status=" + status); - BluetoothDevice device = mAdapter.getRemoteDevice(address); + if (!address.equals(mDevice.getAddress())) { + return; + } try { - mCallback.onReliableWriteCompleted(device, status); + mCallback.onReliableWriteCompleted(mDevice, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } @@ -544,43 +542,24 @@ public final class BluetoothGatt implements BluetoothProfile { public void onReadRemoteRssi(String address, int rssi, int status) { if (DBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address + " rssi=" + rssi + " status=" + status); - BluetoothDevice device = mAdapter.getRemoteDevice(address); + if (!address.equals(mDevice.getAddress())) { + return; + } try { - mCallback.onReadRemoteRssi(device, rssi, status); + mCallback.onReadRemoteRssi(mDevice, rssi, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } } }; - /** - * Create a BluetoothGatt proxy object. - */ - /*package*/ BluetoothGatt(Context context, ServiceListener l) { + /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) { mContext = context; - mServiceListener = l; - mAdapter = BluetoothAdapter.getDefaultAdapter(); + mService = iGatt; + mDevice = device; mServices = new ArrayList<BluetoothGattService>(); - IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE); - if (b != null) { - IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b); - try { - mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Unable to register BluetoothStateChangeCallback", re); - } - } else { - Log.e(TAG, "Unable to get BluetoothManager interface."); - throw new RuntimeException("BluetoothManager inactive"); - } - - //Bind to the service only if the Bluetooth is ON - if(mAdapter.isEnabled()){ - if (!context.bindService(new Intent(IBluetoothGatt.class.getName()), mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth Gatt Service"); - } - } + mConnState = CONN_STATE_IDLE; } /** @@ -590,24 +569,6 @@ public final class BluetoothGatt implements BluetoothProfile { if (DBG) Log.d(TAG, "close()"); unregisterApp(); - mServiceListener = null; - - IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE); - if (b != null) { - IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b); - try { - mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Unable to unregister BluetoothStateChangeCallback", re); - } - } - - synchronized (mConnection) { - if (mService != null) { - mService = null; - mContext.unbindService(mConnection); - } - } } /** @@ -629,18 +590,18 @@ public final class BluetoothGatt implements BluetoothProfile { /** - * Register an application callback to start using Gatt. + * Register an application callback to start using GATT. * - * <p>This is an asynchronous call. The callback is used to notify - * success or failure if the function returns true. + * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} + * is used to notify success or failure if the function returns true. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param callback Gatt callback handler that will receive asynchronous - * callbacks. - * @return true, if application was successfully registered. + * @param callback GATT callback handler that will receive asynchronous callbacks. + * @return If true, the callback will be called to notify success or failure, + * false on immediate error */ - public boolean registerApp(BluetoothGattCallback callback) { + private boolean registerApp(BluetoothGattCallback callback) { if (DBG) Log.d(TAG, "registerApp()"); if (mService == null) return false; @@ -661,7 +622,7 @@ public final class BluetoothGatt implements BluetoothProfile { /** * Unregister the current application and callbacks. */ - public void unregisterApp() { + private void unregisterApp() { if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf); if (mService == null || mClientIf == 0) return; @@ -675,77 +636,7 @@ public final class BluetoothGatt implements BluetoothProfile { } /** - * Starts a scan for Bluetooth LE devices. - * - * <p>Results of the scan are reported using the - * {@link BluetoothGattCallback#onScanResult} callback. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @return true, if the scan was started successfully - */ - public boolean startScan() { - if (DBG) Log.d(TAG, "startScan()"); - if (mService == null || mClientIf == 0) return false; - - try { - mService.startScan(mClientIf, false); - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - - return true; - } - - /** - * Starts a scan for Bluetooth LE devices, looking for devices that - * advertise given services. - * - * <p>Devices which advertise all specified services are reported using the - * {@link BluetoothGattCallback#onScanResult} callback. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param serviceUuids Array of services to look for - * @return true, if the scan was started successfully - */ - public boolean startScan(UUID[] serviceUuids) { - if (DBG) Log.d(TAG, "startScan() - with UUIDs"); - if (mService == null || mClientIf == 0) return false; - - try { - ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length]; - for(int i = 0; i != uuids.length; ++i) { - uuids[i] = new ParcelUuid(serviceUuids[i]); - } - mService.startScanWithUuids(mClientIf, false, uuids); - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - - return true; - } - - /** - * Stops an ongoing Bluetooth LE device scan. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - */ - public void stopScan() { - if (DBG) Log.d(TAG, "stopScan()"); - if (mService == null || mClientIf == 0) return; - - try { - mService.stopScan(mClientIf, false); - } catch (RemoteException e) { - Log.e(TAG,"",e); - } - } - - /** - * Initiate a connection to a Bluetooth Gatt capable device. + * Initiate a connection to a Bluetooth GATT capable device. * * <p>The connection may not be established right away, but will be * completed when the remote device is available. A @@ -757,7 +648,7 @@ public final class BluetoothGatt implements BluetoothProfile { * when the remote device is in range/available. Generally, the first ever * connection to a device should be direct (autoConnect set to false) and * subsequent connections to known devices should be invoked with the - * autoConnect parameter set to false. + * autoConnect parameter set to true. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * @@ -767,18 +658,24 @@ public final class BluetoothGatt implements BluetoothProfile { * device becomes available (true). * @return true, if the connection attempt was initiated successfully */ - public boolean connect(BluetoothDevice device, boolean autoConnect) { - if (DBG) Log.d(TAG, "connect() - device: " + device.getAddress() + ", auto: " + autoConnect); - if (mService == null || mClientIf == 0) return false; - - try { - mService.clientConnect(mClientIf, device.getAddress(), - autoConnect ? false : true); // autoConnect is inverse of "isDirect" - } catch (RemoteException e) { - Log.e(TAG,"",e); + /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) { + if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect); + synchronized(mStateLock) { + if (mConnState != CONN_STATE_IDLE) { + throw new IllegalStateException("Not idle"); + } + mConnState = CONN_STATE_CONNECTING; + } + if (!registerApp(callback)) { + synchronized(mStateLock) { + mConnState = CONN_STATE_IDLE; + } + Log.e(TAG, "Failed to register callback"); return false; } + // the connection will continue after successful callback registration + mAutoConnect = autoConnect; return true; } @@ -787,18 +684,17 @@ public final class BluetoothGatt implements BluetoothProfile { * currently in progress. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param device Remote device */ - public void cancelConnection(BluetoothDevice device) { - if (DBG) Log.d(TAG, "cancelOpen() - device: " + device.getAddress()); + public void disconnect() { + if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return; try { - mService.clientDisconnect(mClientIf, device.getAddress()); + mService.clientDisconnect(mClientIf, mDevice.getAddress()); } catch (RemoteException e) { Log.e(TAG,"",e); } + // TBD deregister after conneciton is torn down } /** @@ -812,17 +708,16 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device to explore * @return true, if the remote service discovery has been started */ - public boolean discoverServices(BluetoothDevice device) { - if (DBG) Log.d(TAG, "discoverServices() - device: " + device.getAddress()); + public boolean discoverServices() { + if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return false; mServices.clear(); try { - mService.discoverServices(mClientIf, device.getAddress()); + mService.discoverServices(mClientIf, mDevice.getAddress()); } catch (RemoteException e) { Log.e(TAG,"",e); return false; @@ -839,16 +734,15 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device * @return List of services on the remote device. Returns an empty list * if service discovery has not yet been performed. */ - public List<BluetoothGattService> getServices(BluetoothDevice device) { + public List<BluetoothGattService> getServices() { List<BluetoothGattService> result = new ArrayList<BluetoothGattService>(); for (BluetoothGattService service : mServices) { - if (service.getDevice().equals(device)) { + if (service.getDevice().equals(mDevice)) { result.add(service); } } @@ -868,14 +762,13 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device * @param uuid UUID of the requested service * @return BluetoothGattService if supported, or null if the requested * service is not offered by the remote device. */ - public BluetoothGattService getService(BluetoothDevice device, UUID uuid) { + public BluetoothGattService getService(UUID uuid) { for (BluetoothGattService service : mServices) { - if (service.getDevice().equals(device) && + if (service.getDevice().equals(mDevice) && service.getUuid().equals(uuid)) { return service; } @@ -923,8 +816,7 @@ public final class BluetoothGatt implements BluetoothProfile { } /** - * Writes a given characteristic and it's values to the associated remote - * device. + * Writes a given characteristic and its values to the associated remote device. * * <p>Once the write operation has been completed, the * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, @@ -1061,15 +953,14 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device * @return true, if the reliable write transaction has been initiated */ - public boolean beginReliableWrite(BluetoothDevice device) { - if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + device.getAddress()); + public boolean beginReliableWrite() { + if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return false; try { - mService.beginReliableWrite(mClientIf, device.getAddress()); + mService.beginReliableWrite(mClientIf, mDevice.getAddress()); } catch (RemoteException e) { Log.e(TAG,"",e); return false; @@ -1089,15 +980,14 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device * @return true, if the request to execute the transaction has been sent */ - public boolean executeReliableWrite(BluetoothDevice device) { - if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + device.getAddress()); + public boolean executeReliableWrite() { + if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return false; try { - mService.endReliableWrite(mClientIf, device.getAddress(), true); + mService.endReliableWrite(mClientIf, mDevice.getAddress(), true); } catch (RemoteException e) { Log.e(TAG,"",e); return false; @@ -1113,15 +1003,13 @@ public final class BluetoothGatt implements BluetoothProfile { * operations for a given remote device. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param device Remote device */ - public void abortReliableWrite(BluetoothDevice device) { - if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + device.getAddress()); + public void abortReliableWrite(BluetoothDevice mDevice) { + if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return; try { - mService.endReliableWrite(mClientIf, device.getAddress(), false); + mService.endReliableWrite(mClientIf, mDevice.getAddress(), false); } catch (RemoteException e) { Log.e(TAG,"",e); } @@ -1172,12 +1060,12 @@ public final class BluetoothGatt implements BluetoothProfile { * remote device. * @hide */ - public boolean refresh(BluetoothDevice device) { - if (DBG) Log.d(TAG, "refresh() - device: " + device.getAddress()); + public boolean refresh() { + if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return false; try { - mService.refreshDevice(mClientIf, device.getAddress()); + mService.refreshDevice(mClientIf, mDevice.getAddress()); } catch (RemoteException e) { Log.e(TAG,"",e); return false; @@ -1194,15 +1082,14 @@ public final class BluetoothGatt implements BluetoothProfile { * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device * @return true, if the RSSI value has been requested successfully */ - public boolean readRemoteRssi(BluetoothDevice device) { - if (DBG) Log.d(TAG, "readRssi() - device: " + device.getAddress()); + public boolean readRemoteRssi() { + if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress()); if (mService == null || mClientIf == 0) return false; try { - mService.readRemoteRssi(mClientIf, device.getAddress()); + mService.readRemoteRssi(mClientIf, mDevice.getAddress()); } catch (RemoteException e) { Log.e(TAG,"",e); return false; @@ -1212,98 +1099,38 @@ public final class BluetoothGatt implements BluetoothProfile { } /** - * Get the current connection state of the profile. - * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} + * with {@link BluetoothProfile#GATT} as argument * - * @param device Remote bluetooth device. - * @return State of the profile connection. One of - * {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING}, - * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING} + * @throws UnsupportedOperationException */ @Override public int getConnectionState(BluetoothDevice device) { - if (DBG) Log.d(TAG,"getConnectionState()"); - if (mService == null) return STATE_DISCONNECTED; - - List<BluetoothDevice> connectedDevices = getConnectedDevices(); - for(BluetoothDevice connectedDevice : connectedDevices) { - if (device.equals(connectedDevice)) { - return STATE_CONNECTED; - } - } - - return STATE_DISCONNECTED; + throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); } /** - * Get connected devices for the Gatt profile. - * - * <p> Return the set of devices which are in state {@link #STATE_CONNECTED} - * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} + * with {@link BluetoothProfile#GATT} as argument * - * @return List of devices. The list will be empty on error. + * @throws UnsupportedOperationException */ @Override public List<BluetoothDevice> getConnectedDevices() { - if (DBG) Log.d(TAG,"getConnectedDevices"); - - List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>(); - if (mService == null) return connectedDevices; - - try { - connectedDevices = mService.getDevicesMatchingConnectionStates( - new int[] { BluetoothProfile.STATE_CONNECTED }); - } catch (RemoteException e) { - Log.e(TAG,"",e); - } - - return connectedDevices; + throw new UnsupportedOperationException + ("Use BluetoothManager#getConnectedDevices instead."); } /** - * Get a list of devices that match any of the given connection - * states. - * - * <p> If none of the devices match any of the given states, - * an empty list will be returned. - * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. + * Not supported - please use + * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} + * with {@link BluetoothProfile#GATT} as first argument * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param states Array of states. States can be one of - * {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING}, - * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}, - * @return List of devices. The list will be empty on error. + * @throws UnsupportedOperationException */ @Override public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { - if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates"); - - List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); - if (mService == null) return devices; - - try { - devices = mService.getDevicesMatchingConnectionStates(states); - } catch (RemoteException e) { - Log.e(TAG,"",e); - } - - return devices; + throw new UnsupportedOperationException + ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); } } diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java index afa4539..c9e5fea 100644 --- a/core/java/android/bluetooth/BluetoothGattCallback.java +++ b/core/java/android/bluetooth/BluetoothGattCallback.java @@ -18,34 +18,10 @@ package android.bluetooth; import android.bluetooth.BluetoothDevice; -import android.util.Log; - /** * This abstract class is used to implement {@link BluetoothGatt} callbacks. - * @hide */ public abstract class BluetoothGattCallback { - /** - * Callback to inform change in registration state of the application. - * - * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application - * was successfully registered. - */ - public void onAppRegistered(int status) { - } - - /** - * Callback reporting an LE device found during a device scan initiated - * by the {@link BluetoothGatt#startScan} function. - * - * @param device Identifies the remote device - * @param rssi The RSSI value for the remote device as reported by the - * Bluetooth hardware. 0 if no RSSI value is available. - * @param scanRecord The content of the advertisement record offered by - * the remote device. - */ - public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) { - } /** * Callback indicating when a remote device has been connected or disconnected. @@ -61,8 +37,8 @@ public abstract class BluetoothGattCallback { } /** - * Callback invoked when the list of remote services, characteristics and - * descriptors for the remote device have been updated. + * Callback invoked when the list of remote services, characteristics and descriptors + * for the remote device have been updated, ie new services have been discovered. * * @param device Remote device * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device @@ -97,7 +73,7 @@ public abstract class BluetoothGattCallback { * @param status The result of the write operation */ public void onCharacteristicWrite(BluetoothGattCharacteristic characteristic, - int status) { + int status) { } /** @@ -113,23 +89,21 @@ public abstract class BluetoothGattCallback { * Callback reporting the result of a descriptor read operation. * * @param descriptor Descriptor that was read from the associated - * remote device. + * remote device. * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation * was completed successfully */ - public void onDescriptorRead(BluetoothGattDescriptor descriptor, - int status) { + public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) { } /** * Callback indicating the result of a descriptor write operation. * * @param descriptor Descriptor that was writte to the associated - * remote device. + * remote device. * @param status The result of the write operation */ - public void onDescriptorWrite(BluetoothGattDescriptor descriptor, - int status) { + public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) { } /** @@ -150,7 +124,7 @@ public abstract class BluetoothGattCallback { * * @param device Identifies the remote device * @param rssi The RSSI value for the remote device - * @param status 0 if the RSSI was read successfully + * @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully */ public void onReadRemoteRssi(BluetoothDevice device, int rssi, int status) { } diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java index f44dc5c..d63d97e 100644 --- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java +++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java @@ -21,8 +21,7 @@ import java.util.List; import java.util.UUID; /** - * Represents a Bluetooth Gatt Characteristic - * @hide + * Represents a Bluetooth GATT Characteristic */ public class BluetoothGattCharacteristic { @@ -119,7 +118,7 @@ public class BluetoothGattCharacteristic { public static final int WRITE_TYPE_NO_RESPONSE = 0x01; /** - * Write characteristic including and authenticated signature + * Write characteristic including authentication signature */ public static final int WRITE_TYPE_SIGNED = 0x04; @@ -219,12 +218,30 @@ public class BluetoothGattCharacteristic { protected List<BluetoothGattDescriptor> mDescriptors; /** + * Create a new BluetoothGattCharacteristic. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param uuid The UUID for this characteristic + * @param properties Properties of this characteristic + * @param permissions Permissions for this characteristic + */ + public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) { + initCharacteristic(null, uuid, 0, properties, permissions); + } + + /** * Create a new BluetoothGattCharacteristic * @hide */ /*package*/ BluetoothGattCharacteristic(BluetoothGattService service, UUID uuid, int instanceId, int properties, int permissions) { + initCharacteristic(service, uuid, instanceId, properties, permissions); + } + + private void initCharacteristic(BluetoothGattService service, + UUID uuid, int instanceId, + int properties, int permissions) { mUuid = uuid; mInstance = instanceId; mProperties = properties; @@ -249,11 +266,16 @@ public class BluetoothGattCharacteristic { } /** - * Add a descriptor to this characteristic - * @hide + * Adds a descriptor to this characteristic. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param descriptor Descriptor to be added to this characteristic. + * @return true, if the descriptor was added to the characteristic */ - /*package*/ void addDescriptor(BluetoothGattDescriptor descriptor) { + public boolean addDescriptor(BluetoothGattDescriptor descriptor) { mDescriptors.add(descriptor); + descriptor.setCharacteristic(this); + return true; } /** @@ -265,8 +287,15 @@ public class BluetoothGattCharacteristic { } /** + * Sets the service associated with this device. + * @hide + */ + /*package*/ void setService(BluetoothGattService service) { + mService = service; + } + + /** * Returns the UUID of this characteristic - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return UUID of this characteristic */ @@ -280,8 +309,6 @@ public class BluetoothGattCharacteristic { * <p>If a remote device offers multiple characteristics with the same UUID, * the instance ID is used to distuinguish between characteristics. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @return Instance ID of this characteristic */ public int getInstanceId() { @@ -294,8 +321,6 @@ public class BluetoothGattCharacteristic { * <p>The properties contain a bit mask of property flags indicating * the features of this characteristic. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @return Properties of this characteristic */ public int getProperties() { @@ -304,7 +329,6 @@ public class BluetoothGattCharacteristic { /** * Returns the permissions for this characteristic. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return Permissions of this characteristic */ @@ -314,7 +338,6 @@ public class BluetoothGattCharacteristic { /** * Gets the write type for this characteristic. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return Write type for this characteristic */ @@ -329,11 +352,6 @@ public class BluetoothGattCharacteristic { * {@link BluetoothGatt#writeCharacteristic} function write this * characteristic. * - * <p>The default write type for a characteristic is - * {@link #WRITE_TYPE_DEFAULT}. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @param writeType The write type to for this characteristic. Can be one * of: * {@link #WRITE_TYPE_DEFAULT}, @@ -345,8 +363,15 @@ public class BluetoothGattCharacteristic { } /** + * Set the desired key size. + * @hide + */ + public void setKeySize(int keySize) { + mKeySize = keySize; + } + + /** * Returns a list of descriptors for this characteristic. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return Descriptors for this characteristic */ @@ -358,9 +383,7 @@ public class BluetoothGattCharacteristic { * Returns a descriptor with a given UUID out of the list of * descriptors for this characteristic. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @return Gatt descriptor object or null if no descriptor with the + * @return GATT descriptor object or null if no descriptor with the * given UUID was found. */ public BluetoothGattDescriptor getDescriptor(UUID uuid) { @@ -376,12 +399,10 @@ public class BluetoothGattCharacteristic { * Get the stored value for this characteristic. * * <p>This function returns the stored value for this characteristic as - * retrieved by calling {@link BluetoothGatt#readCharacteristic}. To cached + * retrieved by calling {@link BluetoothGatt#readCharacteristic}. The cached * value of the characteristic is updated as a result of a read characteristic * operation or if a characteristic update notification has been received. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @return Cached value of the characteristic */ public byte[] getValue() { @@ -397,8 +418,6 @@ public class BluetoothGattCharacteristic { * characteristic value at the given offset are interpreted to generate the * return value. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @param formatType The format type used to interpret the characteristic * value. * @param offset Offset at which the integer value can be found. @@ -436,7 +455,6 @@ public class BluetoothGattCharacteristic { /** * Return the stored value of this characteristic. * <p>See {@link #getValue} for details. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param formatType The format type used to interpret the characteristic * value. @@ -462,7 +480,7 @@ public class BluetoothGattCharacteristic { /** * Return the stored value of this characteristic. * <p>See {@link #getValue} for details. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * * @param offset Offset at which the string value can be found. * @return Cached value of the characteristic */ @@ -481,8 +499,6 @@ public class BluetoothGattCharacteristic { * {@link BluetoothGatt#writeCharacteristic} to send the value to the * remote device. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @param value New value for this characteristic * @return true if the locally stored value has been set, false if the * requested value could not be stored locally. @@ -495,7 +511,6 @@ public class BluetoothGattCharacteristic { /** * Set the locally stored value of this characteristic. * <p>See {@link #setValue(byte[])} for details. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param value New value for this characteristic * @param formatType Integer format type used to transform the value parameter @@ -542,7 +557,7 @@ public class BluetoothGattCharacteristic { /** * Set the locally stored value of this characteristic. * <p>See {@link #setValue(byte[])} for details. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * * @param mantissa Mantissa for this characteristic * @param exponent exponent value for this characteristic * @param formatType Float format type used to transform the value parameter @@ -582,7 +597,7 @@ public class BluetoothGattCharacteristic { /** * Set the locally stored value of this characteristic. * <p>See {@link #setValue(byte[])} for details. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * * @param value New value for this characteristic * @return true if the locally stored value has been set */ @@ -593,7 +608,6 @@ public class BluetoothGattCharacteristic { /** * Returns the size of a give value type. - * @hide */ private int getTypeLen(int formatType) { return formatType & 0xF; @@ -601,7 +615,6 @@ public class BluetoothGattCharacteristic { /** * Convert a signed byte to an unsigned int. - * @hide */ private int unsignedByteToInt(byte b) { return b & 0xFF; @@ -609,7 +622,6 @@ public class BluetoothGattCharacteristic { /** * Convert signed bytes to a 16-bit unsigned int. - * @hide */ private int unsignedBytesToInt(byte b0, byte b1) { return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8)); @@ -617,7 +629,6 @@ public class BluetoothGattCharacteristic { /** * Convert signed bytes to a 32-bit unsigned int. - * @hide */ private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) { return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8)) @@ -626,7 +637,6 @@ public class BluetoothGattCharacteristic { /** * Convert signed bytes to a 16-bit short float value. - * @hide */ private float bytesToFloat(byte b0, byte b1) { int mantissa = unsignedToSigned(unsignedByteToInt(b0) @@ -637,7 +647,6 @@ public class BluetoothGattCharacteristic { /** * Convert signed bytes to a 32-bit short float value. - * @hide */ private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) { int mantissa = unsignedToSigned(unsignedByteToInt(b0) @@ -649,7 +658,6 @@ public class BluetoothGattCharacteristic { /** * Convert an unsigned integer value to a two's-complement encoded * signed value. - * @hide */ private int unsignedToSigned(int unsigned, int size) { if ((unsigned & (1 << size-1)) != 0) { @@ -660,7 +668,6 @@ public class BluetoothGattCharacteristic { /** * Convert an integer into the signed bits of a given length. - * @hide */ private int intToSignedBits(int i, int size) { if (i < 0) { diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java index ba1f28a..6ba2db7 100644 --- a/core/java/android/bluetooth/BluetoothGattDescriptor.java +++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java @@ -19,8 +19,7 @@ package android.bluetooth; import java.util.UUID; /** - * Represents a Bluetooth Gatt Descriptor - * @hide + * Represents a Bluetooth GATT Descriptor */ public class BluetoothGattDescriptor { @@ -109,12 +108,28 @@ public class BluetoothGattDescriptor { * Create a new BluetoothGattDescriptor. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * + * @param uuid The UUID for this descriptor + * @param permissions Permissions for this descriptor + */ + public BluetoothGattDescriptor(UUID uuid, int permissions) { + initDescriptor(null, uuid, permissions); + } + + /** + * Create a new BluetoothGattDescriptor. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * * @param characteristic The characteristic this descriptor belongs to * @param uuid The UUID for this descriptor * @param permissions Permissions for this descriptor */ /*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid, int permissions) { + initDescriptor(characteristic, uuid, permissions); + } + + private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid, + int permissions) { mCharacteristic = characteristic; mUuid = uuid; mPermissions = permissions; @@ -129,8 +144,15 @@ public class BluetoothGattDescriptor { } /** + * Set the back-reference to the associated characteristic + * @hide + */ + /*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) { + mCharacteristic = characteristic; + } + + /** * Returns the UUID of this descriptor. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return UUID of this descriptor */ @@ -140,7 +162,6 @@ public class BluetoothGattDescriptor { /** * Returns the permissions for this descriptor. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return Permissions of this descriptor */ @@ -152,12 +173,10 @@ public class BluetoothGattDescriptor { * Returns the stored value for this descriptor * * <p>This function returns the stored value for this descriptor as - * retrieved by calling {@link BluetoothGatt#readDescriptor}. To cached + * retrieved by calling {@link BluetoothGatt#readDescriptor}. The cached * value of the descriptor is updated as a result of a descriptor read * operation. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @return Cached value of the descriptor */ public byte[] getValue() { @@ -172,8 +191,6 @@ public class BluetoothGattDescriptor { * {@link BluetoothGatt#writeDescriptor} to send the value to the * remote device. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @param value New value for this descriptor * @return true if the locally stored value has been set, false if the * requested value could not be stored locally. diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index 6b69377..d1f4b82 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -38,88 +38,30 @@ import java.util.List; import java.util.UUID; /** - * Public API for the Bluetooth Gatt Profile server role. + * Public API for the Bluetooth GATT Profile server role. * - * <p>This class provides Bluetooth Gatt server role functionality, + * <p>This class provides Bluetooth GATT server role functionality, * allowing applications to create and advertise Bluetooth Smart services * and characteristics. * * <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service * via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the * BluetoothGatt proxy object. - * @hide */ public final class BluetoothGattServer implements BluetoothProfile { private static final String TAG = "BluetoothGattServer"; private static final boolean DBG = true; - private Context mContext; - private ServiceListener mServiceListener; + private final Context mContext; private BluetoothAdapter mAdapter; private IBluetoothGatt mService; private BluetoothGattServerCallback mCallback; - private int mServerIf; + private Object mServerIfLock = new Object(); + private int mServerIf; private List<BluetoothGattService> mServices; - /** - * Bluetooth state change handlers - */ - private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = - new IBluetoothStateChangeCallback.Stub() { - public void onBluetoothStateChange(boolean up) { - if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); - if (!up) { - if (DBG) Log.d(TAG,"Unbinding service..."); - synchronized (mConnection) { - try { - mService = null; - mContext.unbindService(mConnection); - } catch (Exception re) { - Log.e(TAG,"",re); - } - } - } else { - synchronized (mConnection) { - try { - if (mService == null) { - if (DBG) Log.d(TAG,"Binding service..."); - if (!mContext.bindService(new - Intent(IBluetoothGatt.class.getName()), - mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth GATT Service"); - } - } - } catch (Exception re) { - Log.e(TAG,"",re); - } - } - } - } - }; - - /** - * Service binder handling - */ - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - if (DBG) Log.d(TAG, "Proxy object connected"); - mService = IBluetoothGatt.Stub.asInterface(service); - ServiceListener serviceListner = mServiceListener; - if (serviceListner != null) { - serviceListner.onServiceConnected(BluetoothProfile.GATT_SERVER, - BluetoothGattServer.this); - } - } - public void onServiceDisconnected(ComponentName className) { - if (DBG) Log.d(TAG, "Proxy object disconnected"); - mService = null; - ServiceListener serviceListner = mServiceListener; - if (serviceListner != null) { - serviceListner.onServiceDisconnected(BluetoothProfile.GATT_SERVER); - } - } - }; + private static final int CALLBACK_REG_TIMEOUT = 10000; /** * Bluetooth GATT interface callbacks @@ -133,11 +75,14 @@ public final class BluetoothGattServer implements BluetoothProfile { public void onServerRegistered(int status, int serverIf) { if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status + " serverIf=" + serverIf); - mServerIf = serverIf; - try { - mCallback.onAppRegistered(status); - } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + synchronized(mServerIfLock) { + if (mCallback != null) { + mServerIf = serverIf; + mServerIfLock.notify(); + } else { + // registration timeout + Log.e(TAG, "onServerRegistered: mCallback is null"); + } } } @@ -147,13 +92,7 @@ public final class BluetoothGattServer implements BluetoothProfile { */ public void onScanResult(String address, int rssi, byte[] advData) { if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); - - try { - mCallback.onScanResult(mAdapter.getRemoteDevice(address), - rssi, advData); - } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); - } + // no op } /** @@ -209,8 +148,7 @@ public final class BluetoothGattServer implements BluetoothProfile { BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType); if (service == null) return; - BluetoothGattCharacteristic characteristic = service.getCharacteristic( - charUuid); + BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid); if (characteristic == null) return; try { @@ -340,31 +278,13 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Create a BluetoothGattServer proxy object. */ - /*package*/ BluetoothGattServer(Context context, ServiceListener l) { + /*package*/ BluetoothGattServer(Context context, IBluetoothGatt iGatt) { mContext = context; - mServiceListener = l; + mService = iGatt; mAdapter = BluetoothAdapter.getDefaultAdapter(); + mCallback = null; + mServerIf = 0; mServices = new ArrayList<BluetoothGattService>(); - - IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE); - if (b != null) { - IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b); - try { - mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Unable to register BluetoothStateChangeCallback", re); - } - } else { - Log.e(TAG, "Unable to get BluetoothManager interface."); - throw new RuntimeException("BluetoothManager inactive"); - } - - //Bind to the service only if the Bluetooth is ON - if(mAdapter.isEnabled()){ - if (!context.bindService(new Intent(IBluetoothGatt.class.getName()), mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth Gatt Service"); - } - } } /** @@ -372,82 +292,67 @@ public final class BluetoothGattServer implements BluetoothProfile { */ /*package*/ void close() { if (DBG) Log.d(TAG, "close()"); - - unregisterApp(); - mServiceListener = null; - - IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE); - if (b != null) { - IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b); - try { - mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Unable to unregister BluetoothStateChangeCallback", re); - } - } - - synchronized (mConnection) { - if (mService != null) { - try { - mService = null; - mContext.unbindService(mConnection); - } catch (Exception re) { - Log.e(TAG,"",re); - } - } - } - } - - /** - * Returns a service by UUID, instance and type. - * @hide - */ - /*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) { - for(BluetoothGattService svc : mServices) { - if (svc.getType() == type && - svc.getInstanceId() == instanceId && - svc.getUuid().equals(uuid)) { - return svc; - } - } - return null; + unregisterCallback(); } /** - * Register an application callback to start using Gatt. + * Register an application callback to start using GattServer. * * <p>This is an asynchronous call. The callback is used to notify * success or failure if the function returns true. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param callback Gatt callback handler that will receive asynchronous - * callbacks. - * @return true, if application was successfully registered. + * @param callback GATT callback handler that will receive asynchronous + * callbacks. + * @return true, the callback will be called to notify success or failure, + * false on immediate error */ - public boolean registerApp(BluetoothGattServerCallback callback) { - if (DBG) Log.d(TAG, "registerApp()"); - if (mService == null) return false; - - mCallback = callback; - UUID uuid = UUID.randomUUID(); - if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid); - - try { - mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback); - } catch (RemoteException e) { - Log.e(TAG,"",e); + /*package*/ boolean registerCallback(BluetoothGattServerCallback callback) { + if (DBG) Log.d(TAG, "registerCallback()"); + if (mService == null) { + Log.e(TAG, "GATT service not available"); return false; } + UUID uuid = UUID.randomUUID(); + if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid); - return true; + synchronized(mServerIfLock) { + if (mCallback != null) { + Log.e(TAG, "App can register callback only once"); + return false; + } + + mCallback = callback; + try { + mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback); + } catch (RemoteException e) { + Log.e(TAG,"",e); + mCallback = null; + return false; + } + + try { + mServerIfLock.wait(CALLBACK_REG_TIMEOUT); + } catch (InterruptedException e) { + Log.e(TAG, "" + e); + mCallback = null; + } + + if (mServerIf == 0) { + mCallback = null; + return false; + } else { + return true; + } + } } /** * Unregister the current application and callbacks. */ - public void unregisterApp() { - if (DBG) Log.d(TAG, "unregisterApp() - mServerIf=" + mServerIf); + private void unregisterCallback() { + if (DBG) Log.d(TAG, "unregisterCallback() - mServerIf=" + mServerIf); if (mService == null || mServerIf == 0) return; try { @@ -460,77 +365,22 @@ public final class BluetoothGattServer implements BluetoothProfile { } /** - * Starts a scan for Bluetooth LE devices. - * - * <p>Results of the scan are reported using the - * {@link BluetoothGattServerCallback#onScanResult} callback. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @return true, if the scan was started successfully - */ - public boolean startScan() { - if (DBG) Log.d(TAG, "startScan()"); - if (mService == null || mServerIf == 0) return false; - - try { - mService.startScan(mServerIf, true); - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - - return true; - } - - /** - * Starts a scan for Bluetooth LE devices, looking for devices that - * advertise given services. - * - * <p>Devices which advertise all specified services are reported using the - * {@link BluetoothGattServerCallback#onScanResult} callback. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param serviceUuids Array of services to look for - * @return true, if the scan was started successfully + * Returns a service by UUID, instance and type. + * @hide */ - public boolean startScan(UUID[] serviceUuids) { - if (DBG) Log.d(TAG, "startScan() - with UUIDs"); - if (mService == null || mServerIf == 0) return false; - - try { - ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length]; - for(int i = 0; i != uuids.length; ++i) { - uuids[i] = new ParcelUuid(serviceUuids[i]); + /*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) { + for(BluetoothGattService svc : mServices) { + if (svc.getType() == type && + svc.getInstanceId() == instanceId && + svc.getUuid().equals(uuid)) { + return svc; } - mService.startScanWithUuids(mServerIf, true, uuids); - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - - return true; - } - - /** - * Stops an ongoing Bluetooth LE device scan. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - */ - public void stopScan() { - if (DBG) Log.d(TAG, "stopScan()"); - if (mService == null || mServerIf == 0) return; - - try { - mService.stopScan(mServerIf, true); - } catch (RemoteException e) { - Log.e(TAG,"",e); } + return null; } /** - * Initiate a connection to a Bluetooth Gatt capable device. + * Initiate a connection to a Bluetooth GATT capable device. * * <p>The connection may not be established right away, but will be * completed when the remote device is available. A @@ -542,11 +392,10 @@ public final class BluetoothGattServer implements BluetoothProfile { * when the remote device is in range/available. Generally, the first ever * connection to a device should be direct (autoConnect set to false) and * subsequent connections to known devices should be invoked with the - * autoConnect parameter set to false. + * autoConnect parameter set to true. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param device Remote device to connect to * @param autoConnect Whether to directly connect to the remote device (false) * or to automatically connect as soon as the remote * device becomes available (true). @@ -590,7 +439,7 @@ public final class BluetoothGattServer implements BluetoothProfile { * Send a response to a read or write request to a remote device. * * <p>This function must be invoked in when a remote read/write request - * is received by one of these callback methots: + * is received by one of these callback methods: * * <ul> * <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest} @@ -662,17 +511,17 @@ public final class BluetoothGattServer implements BluetoothProfile { } /** - * Add a service to the list of services to be advertised. + * Add a service to the list of services to be hosted. * * <p>Once a service has been addded to the the list, the service and it's - * included characteristics will be advertised by the local device. + * included characteristics will be provided by the local device. * - * <p>If the local device is already advertising services when this function + * <p>If the local device has already exposed services when this function * is called, a service update notification will be sent to all clients. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param service Service to be added to the list of services advertised + * @param service Service to be added to the list of services provided * by this device. * @return true, if the service has been added successfully */ @@ -721,11 +570,11 @@ public final class BluetoothGattServer implements BluetoothProfile { } /** - * Removes a service from the list of services to be advertised. + * Removes a service from the list of services to be provided. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * - * @param service Service to beremoved. + * @param service Service to be removed. * @return true, if the service has been removed */ public boolean removeService(BluetoothGattService service) { @@ -749,7 +598,7 @@ public final class BluetoothGattServer implements BluetoothProfile { } /** - * Remove all services from the list of advertised services. + * Remove all services from the list of provided services. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. */ public void clearServices() { @@ -765,7 +614,7 @@ public final class BluetoothGattServer implements BluetoothProfile { } /** - * Returns a list of GATT services offered bu this device. + * Returns a list of GATT services offered by this device. * * <p>An application must call {@link #addService} to add a serice to the * list of services offered by this device. @@ -802,99 +651,40 @@ public final class BluetoothGattServer implements BluetoothProfile { return null; } + /** - * Get the current connection state of the profile. + * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} + * with {@link BluetoothProfile#GATT} as argument * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param device Remote bluetooth device. - * @return State of the profile connection. One of - * {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING}, - * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING} + * @throws UnsupportedOperationException */ @Override public int getConnectionState(BluetoothDevice device) { - if (DBG) Log.d(TAG,"getConnectionState()"); - if (mService == null) return STATE_DISCONNECTED; - - List<BluetoothDevice> connectedDevices = getConnectedDevices(); - for(BluetoothDevice connectedDevice : connectedDevices) { - if (device.equals(connectedDevice)) { - return STATE_CONNECTED; - } - } - - return STATE_DISCONNECTED; + throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); } /** - * Get connected devices for the Gatt profile. - * - * <p> Return the set of devices which are in state {@link #STATE_CONNECTED} + * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} + * with {@link BluetoothProfile#GATT} as argument * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @return List of devices. The list will be empty on error. + * @throws UnsupportedOperationException */ @Override public List<BluetoothDevice> getConnectedDevices() { - if (DBG) Log.d(TAG,"getConnectedDevices"); - - List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>(); - if (mService == null) return connectedDevices; - - try { - connectedDevices = mService.getDevicesMatchingConnectionStates( - new int[] { BluetoothProfile.STATE_CONNECTED }); - } catch (RemoteException e) { - Log.e(TAG,"",e); - } - - return connectedDevices; + throw new UnsupportedOperationException + ("Use BluetoothManager#getConnectedDevices instead."); } /** - * Get a list of devices that match any of the given connection - * states. - * - * <p> If none of the devices match any of the given states, - * an empty list will be returned. - * - * <p>This is not specific to any application configuration but represents - * the connection state of the local Bluetooth adapter for this profile. - * This can be used by applications like status bar which would just like - * to know the state of the local adapter. + * Not supported - please use + * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} + * with {@link BluetoothProfile#GATT} as first argument * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param states Array of states. States can be one of - * {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING}, - * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}, - * @return List of devices. The list will be empty on error. + * @throws UnsupportedOperationException */ @Override public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { - if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates"); - - List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); - if (mService == null) return devices; - - try { - devices = mService.getDevicesMatchingConnectionStates(states); - } catch (RemoteException e) { - Log.e(TAG,"",e); - } - - return devices; + throw new UnsupportedOperationException + ("Use BluetoothManager#getDevicesMatchingConnectionStates instead."); } } diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java index 4f608ff..f9f1d97 100644 --- a/core/java/android/bluetooth/BluetoothGattServerCallback.java +++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java @@ -22,30 +22,8 @@ import android.util.Log; /** * This abstract class is used to implement {@link BluetoothGattServer} callbacks. - * @hide */ public abstract class BluetoothGattServerCallback { - /** - * Callback to inform change in registration state of the application. - * - * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application - * was successfully registered. - */ - public void onAppRegistered(int status) { - } - - /** - * Callback reporting an LE device found during a device scan initiated - * by the {@link BluetoothGattServer#startScan} function. - * - * @param device Identifies the remote device - * @param rssi The RSSI value for the remote device as reported by the - * Bluetooth hardware. 0 if no RSSI value is available. - * @param scanRecord The content of the advertisement record offered by - * the remote device. - */ - public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) { - } /** * Callback indicating when a remote device has been connected or disconnected. @@ -101,9 +79,9 @@ public abstract class BluetoothGattServerCallback { * @param value The value the client wants to assign to the characteristic */ public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattCharacteristic characteristic, - boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { + BluetoothGattCharacteristic characteristic, + boolean preparedWrite, boolean responseNeeded, + int offset, byte[] value) { } /** @@ -118,7 +96,7 @@ public abstract class BluetoothGattServerCallback { * @param descriptor Descriptor to be read */ public void onDescriptorReadRequest(BluetoothDevice device, int requestId, - int offset, BluetoothGattDescriptor descriptor) { + int offset, BluetoothGattDescriptor descriptor) { } /** @@ -137,9 +115,9 @@ public abstract class BluetoothGattServerCallback { * @param value The value the client wants to assign to the descriptor */ public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattDescriptor descriptor, - boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { + BluetoothGattDescriptor descriptor, + boolean preparedWrite, boolean responseNeeded, + int offset, byte[] value) { } /** diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java index 6a3ce66..c3b3cfe 100644 --- a/core/java/android/bluetooth/BluetoothGattService.java +++ b/core/java/android/bluetooth/BluetoothGattService.java @@ -22,8 +22,7 @@ import java.util.List; import java.util.UUID; /** - * Represents a Bluetooth Gatt Service - * @hide + * Represents a Bluetooth GATT Service */ public class BluetoothGattService { @@ -81,9 +80,14 @@ public class BluetoothGattService { /** * Create a new BluetoothGattService. - * @hide + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param uuid The UUID for this service + * @param serviceType The type of this service, + * {@link BluetoothGattService#SERVICE_TYPE_PRIMARY} or + * {@link BluetoothGattService#SERVICE_TYPE_SECONDARY} */ - /*package*/ BluetoothGattService(UUID uuid, int serviceType) { + public BluetoothGattService(UUID uuid, int serviceType) { mDevice = null; mUuid = uuid; mInstanceId = 0; @@ -115,11 +119,28 @@ public class BluetoothGattService { } /** + * Add an included service to this service. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param service The service to be added + * @return true, if the included service was added to the service + */ + public boolean addService(BluetoothGattService service) { + mIncludedServices.add(service); + return true; + } + + /** * Add a characteristic to this service. - * @hide + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param characteristic The characteristics to be added + * @return true, if the characteristic was added to the service */ - /*package*/ void addCharacteristic(BluetoothGattCharacteristic characteristic) { + public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) { mCharacteristics.add(characteristic); + characteristic.setService(this); + return true; } /** @@ -136,6 +157,15 @@ public class BluetoothGattService { } /** + * Force the instance ID. + * This is needed for conformance testing only. + * @hide + */ + public void setInstanceId(int instanceId) { + mInstanceId = instanceId; + } + + /** * Get the handle count override (conformance testing. * @hide */ @@ -144,6 +174,15 @@ public class BluetoothGattService { } /** + * Force the number of handles to reserve for this service. + * This is needed for conformance testing only. + * @hide + */ + public void setHandles(int handles) { + mHandles = handles; + } + + /** * Add an included service to the internal map. * @hide */ @@ -153,7 +192,6 @@ public class BluetoothGattService { /** * Returns the UUID of this service - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return UUID of this service */ @@ -168,8 +206,6 @@ public class BluetoothGattService { * (ex. multiple battery services for different batteries), the instance * ID is used to distuinguish services. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * * @return Instance ID of this service */ public int getInstanceId() { @@ -178,15 +214,13 @@ public class BluetoothGattService { /** * Get the type of this service (primary/secondary) - * @hide */ public int getType() { return mServiceType; } /** - * Get the list of included Gatt services for this service. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * Get the list of included GATT services for this service. * * @return List of included services or empty list if no included services * were discovered. @@ -197,7 +231,6 @@ public class BluetoothGattService { /** * Returns a list of characteristics included in this service. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return Characteristics included in this service */ @@ -217,9 +250,7 @@ public class BluetoothGattService { * UUID, the first instance of a characteristic with the given UUID * is returned. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @return Gatt characteristic object or null if no characteristic with the + * @return GATT characteristic object or null if no characteristic with the * given UUID was found. */ public BluetoothGattCharacteristic getCharacteristic(UUID uuid) { diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java new file mode 100644 index 0000000..19083b5 --- /dev/null +++ b/core/java/android/bluetooth/BluetoothManager.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth; + +import android.content.Context; +import android.os.RemoteException; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +/** + * High level manager used to obtain an instance of an {@link BluetoothAdapter} + * and to conduct overall Bluetooth Management. + * <p> + * Use {@link android.content.Context#getSystemService(java.lang.String)} + * with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager}, + * then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}. + * <p> + * Alternately, you can just call the static helper + * {@link BluetoothAdapter#getDefaultAdapter()}. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about using BLUETOOTH, read the + * <a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer guide.</p> + * </div> + * + * @see Context#getSystemService + * @see BluetoothAdapter#getDefaultAdapter() + */ +public final class BluetoothManager { + private static final String TAG = "BluetoothManager"; + private static final boolean DBG = true; + private static final boolean VDBG = true; + + private final BluetoothAdapter mAdapter; + + /** + * @hide + */ + public BluetoothManager(Context context) { + context = context.getApplicationContext(); + if (context == null) { + throw new IllegalArgumentException( + "context not associated with any application (using a mock context?)"); + } + // Legacy api - getDefaultAdapter does not take in the context + mAdapter = BluetoothAdapter.getDefaultAdapter(); + } + + /** + * Get the default BLUETOOTH Adapter for this device. + * + * @return the default BLUETOOTH Adapter + */ + public BluetoothAdapter getAdapter() { + return mAdapter; + } + + /** + * Get the current connection state of the profile to the remote device. + * + * <p>This is not specific to any application configuration but represents + * the connection state of the local Bluetooth adapter for certain profile. + * This can be used by applications like status bar which would just like + * to know the state of Bluetooth. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param device Remote bluetooth device. + * @param profile GATT or GATT_SERVER + * @return State of the profile connection. One of + * {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING}, + * {@link BluetoothProfile#STATE_DISCONNECTED}, + * {@link BluetoothProfile#STATE_DISCONNECTING} + */ + public int getConnectionState(BluetoothDevice device, int profile) { + if (DBG) Log.d(TAG,"getConnectionState()"); + + List<BluetoothDevice> connectedDevices = getConnectedDevices(profile); + for(BluetoothDevice connectedDevice : connectedDevices) { + if (device.equals(connectedDevice)) { + return BluetoothProfile.STATE_CONNECTED; + } + } + + return BluetoothProfile.STATE_DISCONNECTED; + } + + /** + * Get connected devices for the specified profile. + * + * <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED} + * + * <p>This is not specific to any application configuration but represents + * the connection state of Bluetooth for this profile. + * This can be used by applications like status bar which would just like + * to know the state of Bluetooth. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param profile GATT or GATT_SERVER + * @return List of devices. The list will be empty on error. + */ + public List<BluetoothDevice> getConnectedDevices(int profile) { + if (DBG) Log.d(TAG,"getConnectedDevices"); + if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { + throw new IllegalArgumentException("Profile not supported: " + profile); + } + + List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>(); + + try { + IBluetoothManager managerService = mAdapter.getBluetoothManager(); + IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + if (iGatt == null) return connectedDevices; + + connectedDevices = iGatt.getDevicesMatchingConnectionStates( + new int[] { BluetoothProfile.STATE_CONNECTED }); + } catch (RemoteException e) { + Log.e(TAG,"",e); + } + + return connectedDevices; + } + + /** + * + * Get a list of devices that match any of the given connection + * states. + * + * <p> If none of the devices match any of the given states, + * an empty list will be returned. + * + * <p>This is not specific to any application configuration but represents + * the connection state of the local Bluetooth adapter for this profile. + * This can be used by applications like status bar which would just like + * to know the state of the local adapter. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. + * + * @param profile GATT or GATT_SERVER + * @param states Array of states. States can be one of + * {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING}, + * {@link BluetoothProfile#STATE_DISCONNECTED}, + * {@link BluetoothProfile#STATE_DISCONNECTING}, + * @return List of devices. The list will be empty on error. + */ + public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) { + if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates"); + + if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { + throw new IllegalArgumentException("Profile not supported: " + profile); + } + + List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); + + try { + IBluetoothManager managerService = mAdapter.getBluetoothManager(); + IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + if (iGatt == null) return devices; + devices = iGatt.getDevicesMatchingConnectionStates(states); + } catch (RemoteException e) { + Log.e(TAG,"",e); + } + + return devices; + } + + /** + * Open a GATT Server + * The callback is used to deliver results to Caller, such as connection status as well + * as the results of any other GATT server operations. + * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer + * to conduct GATT server operations. + * @param context App context + * @param callback GATT server callback handler that will receive asynchronous callbacks. + * @return BluetoothGattServer instance + */ + public BluetoothGattServer openGattServer(Context context, + BluetoothGattServerCallback callback) { + if (context == null || callback == null) { + throw new IllegalArgumentException("null parameter: " + context + " " + callback); + } + + // TODO(Bluetooth) check whether platform support BLE + // Do the check here or in GattServer? + + try { + IBluetoothManager managerService = mAdapter.getBluetoothManager(); + IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + if (iGatt == null) { + Log.e(TAG, "Fail to get GATT Server connection"); + return null; + } + BluetoothGattServer mGattServer = new BluetoothGattServer(context, iGatt); + Boolean regStatus = mGattServer.registerCallback(callback); + return regStatus? mGattServer : null; + } catch (RemoteException e) { + Log.e(TAG,"",e); + return null; + } + } +} diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index 9ee202a..43079f4 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -89,13 +89,11 @@ public interface BluetoothProfile { /** * GATT - * @hide */ static public final int GATT = 7; /** * GATT_SERVER - * @hide */ static public final int GATT_SERVER = 8; diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl index ed8777c..493d2f8 100755 --- a/core/java/android/bluetooth/IBluetoothManager.aidl +++ b/core/java/android/bluetooth/IBluetoothManager.aidl @@ -17,6 +17,7 @@ package android.bluetooth; import android.bluetooth.IBluetooth; +import android.bluetooth.IBluetoothGatt; import android.bluetooth.IBluetoothManagerCallback; import android.bluetooth.IBluetoothStateChangeCallback; @@ -35,6 +36,7 @@ interface IBluetoothManager boolean enable(); boolean enableNoAutoConnect(); boolean disable(boolean persist); + IBluetoothGatt getBluetoothGatt(); String getAddress(); String getName(); diff --git a/core/java/android/bluetooth/MutableBluetoothGattCharacteristic.java b/core/java/android/bluetooth/MutableBluetoothGattCharacteristic.java deleted file mode 100644 index c05abb2..0000000 --- a/core/java/android/bluetooth/MutableBluetoothGattCharacteristic.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.bluetooth; - -import java.util.ArrayList; -import java.util.IllegalFormatConversionException; -import java.util.List; -import java.util.UUID; - -/** - * Mutable variant of a Bluetooth Gatt Characteristic - * @hide - */ -public class MutableBluetoothGattCharacteristic extends BluetoothGattCharacteristic { - - /** - * Create a new MutableBluetoothGattCharacteristic. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param uuid The UUID for this characteristic - * @param properties Properties of this characteristic - * @param permissions Permissions for this characteristic - */ - public MutableBluetoothGattCharacteristic(UUID uuid, int properties, int permissions) { - super(null, uuid, 0, properties, permissions); - } - - /** - * Adds a descriptor to this characteristic. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param descriptor Descriptor to be added to this characteristic. - */ - public void addDescriptor(MutableBluetoothGattDescriptor descriptor) { - mDescriptors.add(descriptor); - descriptor.setCharacteristic(this); - } - - /** - * Set the desired key size. - * @hide - */ - public void setKeySize(int keySize) { - mKeySize = keySize; - } - - /** - * Sets the service associated with this device. - * @hide - */ - /*package*/ void setService(BluetoothGattService service) { - mService = service; - } -} diff --git a/core/java/android/bluetooth/MutableBluetoothGattDescriptor.java b/core/java/android/bluetooth/MutableBluetoothGattDescriptor.java deleted file mode 100644 index e455392..0000000 --- a/core/java/android/bluetooth/MutableBluetoothGattDescriptor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth; - -import java.util.UUID; - -/** - * Mutable variant of a Bluetooth Gatt Descriptor - * @hide - */ -public class MutableBluetoothGattDescriptor extends BluetoothGattDescriptor { - - /** - * Create a new BluetoothGattDescriptor. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param uuid The UUID for this descriptor - * @param permissions Permissions for this descriptor - */ - public MutableBluetoothGattDescriptor(UUID uuid, int permissions) { - super(null, uuid, permissions); - } - - /** - * Set the back-reference to the associated characteristic - * @hide - */ - /*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) { - mCharacteristic = characteristic; - } -} diff --git a/core/java/android/bluetooth/MutableBluetoothGattService.java b/core/java/android/bluetooth/MutableBluetoothGattService.java deleted file mode 100644 index 927f5ab..0000000 --- a/core/java/android/bluetooth/MutableBluetoothGattService.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.bluetooth; - -import android.bluetooth.BluetoothDevice; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * Represents a Bluetooth Gatt Service - * @hide - */ -public class MutableBluetoothGattService extends BluetoothGattService { - - /** - * Create a new MutableBluetoothGattService. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param uuid The UUID for this service - * @param serviceType The type of this service (primary/secondary) - */ - public MutableBluetoothGattService(UUID uuid, int serviceType) { - super(uuid, serviceType); - } - - /** - * Add an included service to this service. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param service The service to be added - * @return true, if the included service was added to the service - */ - public boolean addService(BluetoothGattService service) { - mIncludedServices.add(service); - return true; - } - - /** - * Add a characteristic to this service. - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param characteristic The characteristics to be added - * @return true, if the characteristic was added to the service - */ - public boolean addCharacteristic(MutableBluetoothGattCharacteristic characteristic) { - mCharacteristics.add(characteristic); - characteristic.setService(this); - return true; - } - - /** - * Force the instance ID. - * This is needed for conformance testing only. - * @hide - */ - public void setInstanceId(int instanceId) { - mInstanceId = instanceId; - } - - /** - * Force the number of handles to reserve for this service. - * This is needed for conformance testing only. - * @hide - */ - public void setHandles(int handles) { - mHandles = handles; - } -} |