Skip to content

Commit

Permalink
Framework changes for HFP and A2DP profile implementation of the new …
Browse files Browse the repository at this point in the history
…stack.

Add IBluetoothHeadsetPhone.aidl for a small service in Phone to get
phone state changes

Change-Id: I1015e4a69720c4e9cd18ae4236ccd0dbff2e1b2c
  • Loading branch information
Matthew Xie authored and Android (Google) Code Review committed Jul 17, 2012
1 parent e21a4ac commit 3e8c82e
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 176 deletions.
1 change: 1 addition & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothA2dp.aidl \
core/java/android/bluetooth/IBluetoothCallback.aidl \
core/java/android/bluetooth/IBluetoothHeadset.aidl \
core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl \
core/java/android/bluetooth/IBluetoothHealthCallback.aidl \
core/java/android/bluetooth/IBluetoothPbap.aidl \
core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
Expand Down
121 changes: 27 additions & 94 deletions core/java/android/bluetooth/BluetoothA2dp.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import java.util.ArrayList;
Expand All @@ -42,7 +44,7 @@
*/
public final class BluetoothA2dp implements BluetoothProfile {
private static final String TAG = "BluetoothA2dp";
private static final boolean DBG = false;
private static final boolean DBG = true;

/**
* Intent used to broadcast the change in connection state of the A2DP
Expand Down Expand Up @@ -101,6 +103,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
public static final int STATE_NOT_PLAYING = 11;

private Context mContext;
private ServiceListener mServiceListener;
private IBluetoothA2dp mService;
private BluetoothAdapter mAdapter;
Expand All @@ -110,22 +113,12 @@ public final class BluetoothA2dp implements BluetoothProfile {
* Bluetooth A2DP service.
*
*/
/*package*/ BluetoothA2dp(Context mContext, ServiceListener l) {
//TODO(BT): Fix this
IBinder b = null;
/*package*/ BluetoothA2dp(Context context, ServiceListener l) {
mContext = context;
mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
if (b != null) {
mService = IBluetoothA2dp.Stub.asInterface(b);
if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, this);
}
} else {
Log.w(TAG, "Bluetooth A2DP service not available!");

// Instead of throwing an exception which prevents people from going
// into Wireless settings in the emulator. Let it crash later when it is actually used.
mService = null;
if (!context.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
}
}

Expand Down Expand Up @@ -346,67 +339,6 @@ && isValidDevice(device)) {
return false;
}

/**
* Initiate suspend from an A2DP sink.
*
* <p> This API will return false in scenarios like the A2DP
* device is not in connected state etc. When this API returns,
* true, it is guaranteed that {@link #ACTION_CONNECTION_STATE_CHANGED}
* intent will be broadcasted with the state. Users can get the
* state of the A2DP device from this intent.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
* permission.
*
* @param device Remote A2DP sink
* @return false on immediate error,
* true otherwise
* @hide
*/
public boolean suspendSink(BluetoothDevice device) {
if (mService != null && isEnabled()
&& isValidDevice(device)) {
try {
return mService.suspendSink(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}

/**
* Initiate resume from a suspended A2DP sink.
*
* <p> This API will return false in scenarios like the A2DP
* device is not in suspended state etc. When this API returns,
* true, it is guaranteed that {@link #ACTION_SINK_STATE_CHANGED}
* intent will be broadcasted with the state. Users can get the
* state of the A2DP device from this intent.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
* @param device Remote A2DP sink
* @return false on immediate error,
* true otherwise
* @hide
*/
public boolean resumeSink(BluetoothDevice device) {
if (mService != null && isEnabled()
&& isValidDevice(device)) {
try {
return mService.resumeSink(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}

/**
* This function checks if the remote device is an AVCRP
* target and thus whether we should send volume keys
Expand All @@ -427,23 +359,6 @@ public boolean shouldSendVolumeKeys(BluetoothDevice device) {
return false;
}

/**
* Allow or disallow incoming connection
* @param device Sink
* @param value True / False
* @return Success or Failure of the binder call.
* @hide
*/
public boolean allowIncomingConnect(BluetoothDevice device, boolean value) {
if (DBG) log("allowIncomingConnect(" + device + ":" + value + ")");
try {
return mService.allowIncomingConnect(device, value);
} catch (RemoteException e) {
Log.e(TAG, "", e);
return false;
}
}

/**
* Helper for converting a state to a string.
*
Expand All @@ -469,6 +384,24 @@ public static String stateToString(int state) {
}
}

private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothA2dp.Stub.asInterface(service);

if (mServiceListener != null) {
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
}
}
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
if (mServiceListener != null) {
mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
}
}
};

private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
Expand Down
Loading

0 comments on commit 3e8c82e

Please sign in to comment.