Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb9d3463 authored by Jaikumar Ganesh's avatar Jaikumar Ganesh
Browse files

Make Bluetooth Health APIs public.

Fix a few bugs:
  a) Pass a integer token to identify the channel.
  b) Close fds in case of errors.

Change-Id: I2046787be5008769435f2f72a5bd67c19b749da0
parent 9fefa3c7
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -4528,6 +4528,44 @@ package android.bluetooth {
    field public static final java.lang.String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = "android.bluetooth.headset.intent.category.companyid";
  }
  public final class BluetoothHealth implements android.bluetooth.BluetoothProfile {
    method public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
    method public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int);
    method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
    method public int getConnectionState(android.bluetooth.BluetoothDevice);
    method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
    method public android.os.ParcelFileDescriptor getMainChannelFd(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
    method public boolean registerSinkAppConfiguration(java.lang.String, int, android.bluetooth.BluetoothHealthCallback);
    method public boolean unregisterAppConfiguration(android.bluetooth.BluetoothHealthAppConfiguration);
    field public static final int APP_CONFIG_REGISTRATION_FAILURE = 1; // 0x1
    field public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0; // 0x0
    field public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3; // 0x3
    field public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2; // 0x2
    field public static final int CHANNEL_TYPE_RELIABLE = 10; // 0xa
    field public static final int CHANNEL_TYPE_STREAMING = 11; // 0xb
    field public static final int SINK_ROLE = 2; // 0x2
    field public static final int SOURCE_ROLE = 1; // 0x1
    field public static final int STATE_CHANNEL_CONNECTED = 2; // 0x2
    field public static final int STATE_CHANNEL_CONNECTING = 1; // 0x1
    field public static final int STATE_CHANNEL_DISCONNECTED = 0; // 0x0
    field public static final int STATE_CHANNEL_DISCONNECTING = 3; // 0x3
  }
  public final class BluetoothHealthAppConfiguration implements android.os.Parcelable {
    method public int describeContents();
    method public int getDataType();
    method public java.lang.String getName();
    method public int getRole();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
  }
  public abstract class BluetoothHealthCallback {
    ctor public BluetoothHealthCallback();
    method public void onHealthAppConfigurationStatusChange(android.bluetooth.BluetoothHealthAppConfiguration, int);
    method public void onHealthChannelStateChange(android.bluetooth.BluetoothHealthAppConfiguration, android.bluetooth.BluetoothDevice, int, int, android.os.ParcelFileDescriptor, int);
  }
  public abstract interface BluetoothProfile {
    method public abstract java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
    method public abstract int getConnectionState(android.bluetooth.BluetoothDevice);
+34 −18
Original line number Diff line number Diff line
@@ -32,10 +32,25 @@ import java.util.List;
 * <p>BluetoothHealth is a proxy object for controlling the Bluetooth
 * Service via IPC.
 *
 * <p> Use {@link BluetoothAdapter#getProfileProxy} to get
 * the BluetoothHealth proxy object. Use
 * {@link BluetoothAdapter#closeProfileProxy} to close the service connection.
 * @hide
 * <p> How to connect to a health device which is acting in the source role.
 *  <li> Use {@link BluetoothAdapter#getProfileProxy} to get
 *  the BluetoothHealth proxy object. </li>
 *  <li> Create an {@link BluetoothHealth} callback and call
 *  {@link #registerSinkAppConfiguration} to register an application
 *  configuration </li>
 *  <li> Pair with the remote device. This currently needs to be done manually
 *  from Bluetooth Settings </li>
 *  <li> Connect to a health device using {@link #connectChannelToSource}. Some
 *  devices will connect the channel automatically. The {@link BluetoothHealth}
 *  callback will inform the application of channel state change. </li>
 *  <li> Use the file descriptor provided with a connected channel to read and
 *  write data to the health channel. </li>
 *  <li> The received data needs to be interpreted using a health manager which
 *  implements the IEEE 11073-xxxxx specifications.
 *  <li> When done, close the health channel by calling {@link #disconnectChannel}
 *  and unregister the application configuration calling
 *  {@link #unregisterAppConfiguration}
 *
 */
public final class BluetoothHealth implements BluetoothProfile {
    private static final String TAG = "BluetoothHealth";
@@ -137,7 +152,6 @@ public final class BluetoothHealth implements BluetoothProfile {
     *
     * @param config  The health app configuration
     * @return Success or failure.
     * @hide
     */
    public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
        boolean result = false;
@@ -222,16 +236,15 @@ public final class BluetoothHealth implements BluetoothProfile {
     * @param device The remote Bluetooth device.
     * @param config The application configuration which has been registered using
     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
     * @param fd The file descriptor that was associated with the channel.
     * @param channelId The channel id associated with the channel
     * @return If true, the callback associated with the application config will be called.
     * @hide
     */
    public boolean disconnectChannel(BluetoothDevice device,
            BluetoothHealthAppConfiguration config, ParcelFileDescriptor fd) {
            BluetoothHealthAppConfiguration config, int channelId) {
        if (mService != null && isEnabled() && isValidDevice(device) &&
                config != null) {
            try {
                return mService.disconnectChannel(device, config, fd);
                return mService.disconnectChannel(device, config, channelId);
            } catch (RemoteException e) {
                Log.e(TAG, e.toString());
            }
@@ -248,11 +261,13 @@ public final class BluetoothHealth implements BluetoothProfile {
     *
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
     *
     * <p> Its the responsibility of the caller to close the ParcelFileDescriptor
     * when done.
     *
     * @param device The remote Bluetooth health device
     * @param config The application configuration
     * @return null on failure, ParcelFileDescriptor on success.
     */

    public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
            BluetoothHealthAppConfiguration config) {
        if (mService != null && isEnabled() && isValidDevice(device) &&
@@ -300,7 +315,7 @@ public final class BluetoothHealth implements BluetoothProfile {
    }

    /**
     * Get connected devices for this specific profile.
     * Get connected devices for the health profile.
     *
     * <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
     *
@@ -374,8 +389,9 @@ public final class BluetoothHealth implements BluetoothProfile {
        @Override
        public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
                                       BluetoothDevice device, int prevState, int newState,
                                       ParcelFileDescriptor fd) {
            mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd);
                                       ParcelFileDescriptor fd, int channelId) {
            mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd,
                                                 channelId);
        }
    }

@@ -389,13 +405,13 @@ public final class BluetoothHealth implements BluetoothProfile {
    public static final int STATE_CHANNEL_DISCONNECTING = 3;

    /** Health App Configuration registration success */
    public static final int APPLICATION_REGISTRATION_SUCCESS = 0;
    public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0;
    /** Health App Configuration registration failure */
    public static final int APPLICATION_REGISTRATION_FAILURE = 1;
    public static final int APP_CONFIG_REGISTRATION_FAILURE = 1;
    /** Health App Configuration un-registration success */
    public static final int APPLICATION_UNREGISTRATION_SUCCESS = 2;
    public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2;
    /** Health App Configuration un-registration failure */
    public static final int APPLICATION_UNREGISTRATION_FAILURE = 3;
    public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3;

    private ServiceListener mServiceListener;
    private IBluetooth mService;
+3 −5
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.Parcelable;
 * that the Bluetooth Health third party application will register to communicate with the
 * remote Bluetooth health device.
 *
 * @hide
 */
public final class BluetoothHealthAppConfiguration implements Parcelable {
    private final String mName;
@@ -39,6 +38,7 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
     *
     * @param name Friendly name associated with the application configuration
     * @param dataType Data Type of the remote Bluetooth Health device
     * @hide
     */
    BluetoothHealthAppConfiguration(String name, int dataType) {
        mName = name;
@@ -54,6 +54,7 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
     * @param dataType Data Type of the remote Bluetooth Health device
     * @param role {@link BluetoothHealth#SOURCE_ROLE} or
     *                     {@link BluetoothHealth#SINK_ROLE}
     * @hide
     */
    BluetoothHealthAppConfiguration(String name, int dataType, int role, int
        channelType) {
@@ -93,7 +94,6 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
            mChannelType + "]";
    }

    @Override
    public int describeContents() {
        return 0;
    }
@@ -132,6 +132,7 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
     * @return One of {@link BluetoothHealth#CHANNEL_TYPE_RELIABLE} or
     *                         {@link BluetoothHealth#CHANNEL_TYPE_STREAMING} or
     *                         {@link BluetoothHealth#CHANNEL_TYPE_ANY}.
     * @hide
     */
    public int getChannelType() {
        return mChannelType;
@@ -155,13 +156,10 @@ public final class BluetoothHealthAppConfiguration implements Parcelable {
        }
    };

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mName);
        out.writeInt(mDataType);
        out.writeInt(mRole);
        out.writeInt(mChannelType);
    }


}
+35 −9
Original line number Diff line number Diff line
@@ -21,22 +21,48 @@ import android.os.ParcelFileDescriptor;
import android.util.Log;

/**
 * This class is used for all the {@link BluetoothHealth} callbacks.
 * @hide
 * This abstract class is used to implement {@link BluetoothHealth} callbacks.
 */
public abstract class BluetoothHealthCallback {

    private static final String TAG = "BluetoothHealthCallback";

    /**
     * Callback to inform change in registration state of the health
     * application.
     * <p> This callback is called on the binder thread (not on the UI thread)
     *
     * @param config Bluetooth Health app configuration
     * @param status Success or failure of the registration or unregistration
     *            calls. Can be one of
     *            {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or
     *            {@link BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
     *            {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS} or
     *            {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
     */
    public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
            int status) {
        Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + "Status: " + status);
    }

    /**
     * Callback to inform change in channel state.
     * <p> Its the responsibility of the implementor of this callback to close the
     * parcel file descriptor when done. This callback is called on the Binder
     * thread (not the UI thread)
     *
     * @param config The Health app configutation
     * @param device The Bluetooth Device
     * @param prevState The previous state of the channel
     * @param newState The new state of the channel.
     * @param fd The Parcel File Descriptor when the channel state is connected.
     * @param channelId The id associated with the channel. This id will be used
     *            in future calls like when disconnecting the channel.
     */
    public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
                                    BluetoothDevice device, int prevState, int newState,
                                    ParcelFileDescriptor fd) {
            BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
            int channelId) {
        Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device +
            "PrevState:" + prevState + "NewState:" + newState + "FileDescriptor:" + fd);
              "prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd +
              "ChannelId:" + channelId);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ interface IBluetooth
    boolean connectChannelToSource(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
    boolean connectChannelToSink(in BluetoothDevice device, in BluetoothHealthAppConfiguration config,
        int channelType);
    boolean disconnectChannel(in BluetoothDevice device, in BluetoothHealthAppConfiguration config, in ParcelFileDescriptor fd);
    boolean disconnectChannel(in BluetoothDevice device, in BluetoothHealthAppConfiguration config, int id);
    ParcelFileDescriptor getMainChannelFd(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
    List<BluetoothDevice> getConnectedHealthDevices();
    List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(in int[] states);
Loading